gate: plugin conformance, hostile-runtime containment and production disclosure #80
Labels
No labels
code-review
correctness
dos
performance
security
severity/high
severity/low
severity/medium
tech-debt
Kind/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Blocks
Depends on
#41 test: scale ceilings for graph caps, resolver fan-out and dynamic plugin generations
h-dv/code-index
#65 perf/reliability: tier 1R and C# partial resolution scale quadratically and hide progress
h-dv/code-index
#73 perf: project_overview needs generation-scoped O(1) aggregates, not repeated refs scans
h-dv/code-index
Reference
h-dv/code-index#80
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Child of #75. Depends on #76–#79 plus the formally linked correctness, scale, payload, product-benchmark and disclosure gates.
Purpose
Runtime plugins move code-index from a closed, compile-time language set to an open system that executes third-party grammar/extractor code and admits new evidence into a safety-sensitive resolver.
This issue defines the proof required before a package or the architecture is called production-ready. Disclosure is necessary, but it is the last layer; isolation, determinism, provenance, rollback and semantic containment must be tested first.
Product surfaces
Ship an operator/developer workflow:
No indexing command downloads or executes a repository-requested package implicitly.
Every mutating command prints exact project, package digest, capability grant and expected reindex domain before confirmation/non-interactive execution.
Conformance layers
C0 — static package validation
From #76:
No plugin code runs.
C1 — isolated runtime validation
Through #79:
A package failing C1 cannot be enabled.
C2 — extraction correctness
Fixtures declare canonical facts, not internal database ids:
Fixtures need negative assertions: named decoys that must not emit facts. Count-only tests are insufficient because overcapture can look productive.
C3 — resolver containment
Index the probe corpus with:
Assertions:
The check is necessary but does not claim universal semantic correctness on every unseen repository. Runtime least-authority remains the primary safety boundary.
C4 — lifecycle equivalence
From #78:
C5 — hostile package containment
Required adversaries:
Passing means the daemon, active index and unrelated projects remain usable and the failure is accurately disclosed.
C6 — scale and operations
Run on committed small fixtures plus scheduled large corpora:
Commit ceilings, not just measurements. A package that exceeds a ceiling is rejected/quarantined with the old generation active.
Runtime budgets
Host maximums are versioned product contracts. Package-requested values can only reduce them.
At minimum:
Budget exhaustion is a refusal with a stable reason code. It is never a warning followed by partial insertion.
Disclosure model
Every response that can be affected by plugin coverage carries a normalized package-state block or an explicit unavailable marker.
Project-level block:
Per-package state is a closed trichotomy plus lifecycle:
Each state has its own constant semantics and stable reason codes. Empty and unavailable are different.
Per-result provenance is compact:
A response may define package handles once and reference them from rows.
Stable reason-code families
At minimum:
Package/install:
Runtime:
Fact validation:
Activation:
Coverage:
Reason values are wire contract. Renames require compatibility normalization.
Tool-specific honesty
The existing #81 symbol-blind extension disclosure ships independently and remains meaningful when a requested plugin is unavailable or rejected.
XAML/C# reference package
The first production package proves grammar, extraction and bridges:
Generated Designer.cs remains a separate coverage decision and is measured explicitly. Runtime XAML support must not be used to excuse missing generated C# definitions.
Full-language migration proof
DONE — this is #84, closed 2026-09-06. Migrate one complete existing compiled plugin into an external package path.
Run builtin and package implementations against:
Compare canonical extraction facts and resolved projection. Any intentional delta is separately reviewed and pinned; aggregate-count similarity is not equivalence.
This is the anti-vacuity gate for “real plugin architecture.” XAML alone proves markup extensibility, not general language extensibility.
Release and compatibility
Before first stable plugin ABI:
For stable ABI:
The startup/tool-description payload budget includes new plugin fields; reference documentation belongs in resources, not repeated on every tool schema.
Documentation
Final end-to-end release gate
On a clean machine with released binaries:
Steps 1–11 are implemented in
release_gate_e2e::the_release_gate.#75 is not complete until this gate is green.
Adjacent release blockers formally linked to this gate
CORRECTED 2026-09-07. Seven of these nine are closed. Kept in place rather than deleted, because the list is the record of what this gate was held to:
bench_promotion_lock.rs:194-241, filed under #116, which is why a grep ofgeneration_promotion.rsfound nothing. The GC calibration was taken on an idle box 2026-09-07 (7,678 / 9,204 / 10,396 ns per cascaded row) and the constant deliberately left at 60,000, because its only consumer runs on a shared runner; seecollect.rs.COSI_RUBY_PKG_COST_BLESS) is CLOSED. Criterion 3 and criterion 2's XAML half are not started.These were dependencies, not optional polish, and passing package unit fixtures while the host product hangs, lies about coverage or becomes undiscoverable still does not satisfy #75.
gate: honesty for languages that arrive at runtime — disclosure, inertness harness, and the ungradeableto gate: plugin conformance, hostile-runtime containment and production disclosurederived_names, so a package using #86 gap 1 can never be enabled #103Blocker audit, 2026-09-04 at
4555887: four of the nine adjacent blockers are already closed, and this issue quotes two of them as live grounds.This body lists nine adjacent blockers. Audited each against the tree — not against the issue text, because on this repo issue text goes stale in both directions and has already cost a lane once (#85 was cited twice as a live blocker after shipping in v0.24.0).
c29d806shipped in v0.23.0This body was edited 2026-09-04 at 13:53 — two hours after #82 closed — and still lists it as unproved. That is not a criticism of the edit; it is the reason this audit was run.
The two sentences in this issue that are now false
resolve_budget.rsbudgets five stages against the four #65 named, with five guard sites, and progress rides onproject_overviewso it is agent-visible rather than log-only. Closed with the citations.recv_line(), with a floor as well as a ceiling so a collapsed payload cannot read as a win. Closed with the citations.Residuals split out rather than left buried in the closes: #110 (the bridge tier is the one fan-out stage with no budget, and its exemption is argued rather than measured) and #111 (the payload ratchet reports one total, not the five categories #71 asked for — and the ceiling has already been raised once).
Two findings that make this gate weaker than the ledger suggests
Both verified independently against source and against the live API, and filed:
COSI_CORPUS_REQUIRE=1fires only when nothing ran (corpus/mod.rs:911:require && self.executed.is_empty()).corpus.tomlpins nine repos. Eight can skip and the run passes green on a silently shrunken universe. Same class as the I035 defect the guard was written for; it has a floor of one instead of nine.corpus-scale,plugin-path-costandgrammar-rebuildare manual-only, and nothing says so. That matters specifically here because this project's own hard-won finding is that correctness gates cannot see slowdowns — a 3.2× cold-index regression passed ~1950 tests and CI 10/10 three times, and only a weekly wall-clock ceiling caught it. That ceiling lives incorpus-scale. It has never run on its own schedule.Two more, smaller, from the same audit
generation_equivalence.rs:113-121says out loud that the activation digest "is NOT part of any compared projection", and:1156asserts only that the digest moves, never that the three legs agree. What is enforced is a projection triangle over five id-independent projections — real, and a different claim.ci.yml:56-58). So plugin baselines cannot be added without changing that corpus — which is why #45's baseline decision must be taken before #41 builds fixtures, or the fixtures get rebuilt.Recommended order for what is left
graph.rs:2683builds 1.1M live edges but is a unit test over a bareConnectionasserting no disclosure at all), and queries-during-build.Confidence, stated
Least confident: #72. Its acceptance is a shape ("a registry-style stage matrix"), not a behaviour, and its substance has been absorbed piecemeal under at least three vocabularies (
stage,coverage_reasons,EXTENSION_STATES). It is provable that the registry does not exist and that three named doors are unmodelled; it is not provable from this audit that every remaining permanent-refusal stage was found — running that sweep exhaustively is the issue.Method note worth keeping. Of the claims this audit first made from a text grep, two were wrong — that no test crosses the 1M-edge cap, and that no resolution-percentage gate exists. Both failed the same way: searching for a name and reading a null result as a property of the codebase, when the code referenced the concept without spelling the name. A reference query on the symbol would have caught both. That is the "audit by behaviour, not string equality" rule, broken while quoting it.
Blocker checklist, 2026-09-06 at
45cf6e4— readable without cross-referencing fifteen issuesSuccessor to the 2026-09-04 audit above, which is now itself partly stale. Five of the nine named blockers are closed, and this issue's body still quotes all five as live grounds. Four remain, plus the step-13 gate.
A triage pass ran today over all 81 open issues; the numbers below are checked against the tree and against tests that were executed, not against issue text.
The nine "adjacent release blockers", current
c807368in v0.23.0refusal_stage_registry.rsis the matrixPhase issues #76, #77, #78, #79 are all CLOSED (2026-09-05). The header line "Depends on #76–#79" is satisfied.
What remains, with its actual acceptance
#73 — the latency defect is FIXED; an acceptance test is what is left
Both refs scans are gone. m0060 took the census 237.4 ms → 29.8 ms; m0061
file_refs_rolluptookfile_health16.2M → 7.1M vm_step (237k refs) and 28.2M → 10.0M (rust-analyzer's 406k), for +3.84% paid once at cold index and repaid by the secondproject_overview. Generation-keying, promotion switching, freshness fields and boundedness all read MET.Remaining acceptance: the 2M-ref, two-generation acceptance test. It was measured on real 237k/406k indexes plus a scaling test instead, and
4c08caanames that substitution as a residual rather than hiding it. This is a test to write, not a defect to fix — the sentence in this body ("makes first-call overview latency scale with refs") is no longer true.#41 — two hard items genuinely absent, and the GC ceiling is loose by its own admission
Tier-1/tier-3 corpus green; the plugin-host, generation and GC legs now exist (
bench_promotion_lock,bench_generation_gc,crates/daemon/tests/graph_cap_scale_e2e.rs— the last measured a real 321× defect and fixed it).Still open:
graph_cap_scale_e2enow drives a real daemon over real RPC at 1,100,001 edges, which closes most of the old objection — but the disclosure assertions this gate wants are still worth pinning explicitly.MEASURED_COLLECT_NS_PER_CASCADED_ROW100,000 → 60,000, but "calibration is contended-only" — the box never fell below load 18, so 60,000 would not catch a 2× regression on a quiet machine. Three of four mutations unrun. The 100k-file arm never completed and no 100k row is claimed anywhere.#45 — one criterion NOT STARTED, one half-started
baseline.json,cost-baseline.json,stage-baseline.json,ruby-package-cost.json).projection::bless_verdictexceptCOSI_RUBY_PKG_COST_BLESS, whose waiver is written and self-clearing.de.h-dv.xamlstill has no committed projection baseline of any kind.git diff. The lane buildingtests/corpus/package-baseline.jsonwas killed by a rate limit before writing a line.The 2026-09-04 recommendation still holds and is the highest-leverage item here: take #45's plugin-baseline decision before #41 builds fixtures, or the fixtures get rebuilt.
#51 — all five acceptance boxes are ticked; the residuals are narrow
As of 2026-09-06 the fifth box (previously graded as a total) is a per-repo floor of 20 (20/20/20 over three repos). What is left:
rust-ripgrep's block stood at the pre-rebase measurement, red pending #165 — and #165 has since landed (efccc89), so this needs one re-run to settle rather than any work.ci.ymlcarries six stale figures citing it.ratchet.json's_conditionsstill says "debug profile".The sentence in this body — "#51 has not graded correctness and token value on real plugin workflows" — is false. It has, and its verdict belongs in this gate's text far more than the old sentence does: against a competent ripgrep baseline we cost 1.57–1.7× MORE context, not 10× less; what we buy is precision 1.000 vs 0.517 and 62 round trips vs 247. That refutation is #120, which is open and whose false claim is still shipping from five sites including a test that pins it.
#84 — step 13: phases 1–4 COMPLETE, and it may be closable
Axes A/B/C all green: 1254/1254 symbols identical on 9 of 10 columns, 18450/18450 ref sites, 231/231 imports, five pinned deltas each carrying a predicate checked on the row. The gate's own anti-vacuity clause caught the shipped package declaring
resolver = []and resolving 0 of 2853 refs while extraction was byte-identical — which is exactly the failure a count-only comparison would have missed.Both items the last #84 comment left open have since been closed elsewhere: axis C is CI-wired (
ci.yml:864, 878, 935, 948), and the ruby cost band was re-blessed from a measurement. Worth asking on #84 whether anything still blocks its close.The gate's own 13 steps — where they stand
Steps 1–11 are implemented as one sequenced test:
the_release_gate,crates/daemon/tests/release_gate_e2e.rs:920, with per-step markers at:954 :1061 :1104 :1158 :1222 :1335 :1385 :1528 :1665 :1937 :2094. Every mutating action is a child process of a shipped binary; every asserted fact is read from the database or off the wire. Two limits the file states itself (:66-86):CODE_INDEX_ABORT_AT_PHASE/CODE_INDEX_PARK_AT_PHASEbehindcfg!(debug_assertions)), so the phase-accurate crash is not reproducible against a released binary — recovery is. Full matrix:crates/indexer/tests/generation_crash_matrix.rs.plugin_package_e2e::a_hostile_package_is_contained_and_the_daemon_keeps_serving, which bypasses C1 through the library.Step 12 — partial.
release_smokeruns inbuild-muslbefore packaging and inci-windows.yml:270-290. Not covered: aarch64-linux-gnu is cross-built and never executed; the shipped Windows archive is windows-gnu while the native test proves the MSVC debug binary; macOS is not a target (#59, option 3 chosen deliberately); and the 11-step sequence runs on Linux-gnu only.Step 13 — implemented, but this gate's own file does not know it. All three #84 axes exist and are CI-wired (
ruby_claim_parity.rs:420/:510,ruby_builtin_expectations.rs:936,ruby_package_parity.rs:450,ruby_package_cost.rs:577,ruby_package_e2e.rs).release_gate_e2e.rs:102-122is stale: its step-12 table still says musl iscontinue-on-error(it is a separate job now) and its step-13 paragraph says "Nothing in this repository runs it today", which #84 made false.Sentences in this body that should be corrected
Under "Adjacent release blockers formally linked to this gate", these five are false:
and these two are stale rather than false:
Still substantially accurate: #41 and #45.
Header: "Depends on #76–#79" — all four closed. And the "Full-language migration proof" section reads as unstarted work; it was split to #84, whose phases 1–4 are complete.
Residuals that were split out of the now-closed blockers, so they are not lost
#110 (bridge tier has no
Stagebudget — verified still true today,resolve_budget.rs:130-136has five members and no bridge variant; related to #164, which names the mechanism and arguably contradicts #110's exemption argument), #111 (payload ratchet reports one total, not five categories — no movement,search_text("#111")returns 0 hits tree-wide), #119 (EMBEDDED_DISPATCH_SEMANTICS_VERSION = 0, so #77 criterion 2 is unexercisable), #137 (linked-project package identity — 2 of 3 criteria met).One CI fact that bears on this gate
At
f6a878athe ten Linux jobs were green and the native-Windows job was red (run 608, 15 s, dying in the disk pre-flight — #179, now fixed at45cf6e4but unverified on a real Windows host). Separately, #109 is now closed: the nightly cron genuinely fires — run 585 executed all 13 jobs withevent: schedule, includingcorpus-scale, which carries the weekly wall-clock ceiling and had never run on its own schedule. That matters here because correctness gates cannot see slowdowns, and this gate's C6 ceilings live in those jobs.🤖 Triage lane, 2026-09-06, master
45cf6e4code-index://docs/reason-codesis at 3,979 of its 4,000-token cap, so the next reason code this project mints cannot be documented #184release_gate_e2e.rs:102-122still says musl is continue-on-error and that nothing runs the step-13 migration gate — both false since #84 #187Stated plainly, because the checklist above buries it: this issue's BODY is now misleading, and it has caused real under-scoping twice.
The comment above is a correction layer. Anyone who reads the body — which is what a reader does first, and what a fresh lane does exclusively — gets a wrong answer about what blocks this gate. That is not a cosmetic problem for a release gate whose whole job is to be readable as a checklist.
The concrete cost, twice, in two days
Two correction comments on one issue, and the body still says the same five false things. A third comment will not fix that.
What is false in the body right now
Under "Adjacent release blockers formally linked to this gate" — "These are dependencies, not optional polish":
c807368in v0.23.0refusal_stage_registry.rsis the matrixHeader: "Depends on #76–#79" — all four closed 2026-09-05.
The "Full-language migration proof" section reads as unstarted work. It was split to #84, whose phases 1–4 are complete.
Genuinely still accurate: #41 and #45.
The recommendation
Edit the body. Not because the corrections are missing — they are two comments up — but because a release gate that requires reading two audit comments to know what it gates is not a checklist, and this project's own recorded rule is that issue text goes stale in both directions.
Minimum viable edit:
#76–#79dependency, or mark it satisfied.The same disease, one layer down — now filed
While compiling the checklist I found the identical failure inside the gate's own implementation: #187 —
crates/daemon/tests/release_gate_e2e.rs:102-122still says musl iscontinue-on-error(it is a separatebuild-musljob) and that "Nothing in this repository runs it today" about step 13 (#84 made that false).Both stale sentences there point the same way this body does: toward more remaining work than exists. Three instances in three files in one day (#185, #186, #187), all of the form in-tree prose asserting a state the tree has moved past, and in every case the prose overstated what was left. That is worth treating as a pattern rather than three chores.
I have not edited this body — rewriting a release gate's scope is a decision for its owner, not for a triage lane.
🤖 Triage lane, 2026-09-06, master
45cf6e4Blocker checklist, 2026-09-06 afternoon, at
552e3a2— the release-blocker lane's passSuccessor to the 09:44 checklist at
45cf6e4. Master has moved four commits since (df1551fand552e3a2landed from two other lanes). One of the four remaining blockers is now closed, one is recommended for close, and of the other two, one has a completely different remaining scope from the one that checklist named.Everything below was run or read in a worktree at
552e3a2. Where a verdict rests on a measurement, the command and its exit code are given.The four, now
#73 — CLOSED
crates/daemon/tests/overview_scale_2m_e2e.rs, registered on the nightlycorpus-scalejob.Refs x6.62 past 2M with files and symbols held flat costs x1.000. The census is 238 opcodes for 2.12M refs. A 2,000,000-ref pending generation costs x0.999, so the epoch gate is a seek. The derivation m0061 replaced is 10.1x the shipped one on the same database.
MUTATION (RUN):
index_healthreturnsindex_health_from_scanunconditionally → RED, exit 101,refs x6.62 -> work x6.224, wall 380 ms → 3.79 s. Restored bycpsnapshot, md5710fb58922c7c8b63416f9c13626faecboth sides. The restore run reproduces every vm_step figure digit for digit at a different machine load — which is the determinism claim proved on this fixture rather than inherited.One finding kept out of the close:
pools_cteis O(symbols) and was graded by nothing. It costs x2.141 for x6.62 symbols — sub-linear, not a #73 defect, but 12.1M of the 22.6M opcodes aproject_overviewpays on a 2M-ref index. It is now a number.#51 — the re-run is GREEN, and recall went UP on two repos
Executed, not skipped — three repo shas, 20 questions each, the ripgrep leg ran for real (22/24/23 calls).
rg_false_positivesheld EXACTLY on all three — that is the anti-blessing gate, and it moving would be the signature of a widened oracle. The recall gain is attributable:74d241b's D1 fix tookdapper.who_calls.CastResultfrom 3 truth / 0 returned to 3 / 3.All five acceptance boxes MET. The residuals are narrow and none is an acceptance criterion:
ci.yml:987's six stale rg figures,ratchet.json's_conditionsstill saying "debug profile", and the harness still unable to value-pin a zero-return known defect.One figure this gate should carry: fixed startup is 16,559 tokens against 22,618 for all sixty questions across three repositories. #120's refutation stands and belongs in this body far more than the sentence it would replace.
#41 — two of the checklist's three items were already done; three OTHER things are missing
The 09:44 checklist named: a daemon >1M-edge disclosure test, "queries during build — Absent", and the GC calibration. Graded against the tree:
graph_cap_scale_e2e::graph_tools_decline_past_the_cap_and_name_both_numbersasserts, on the wire, the measured live-edge count, the cap, and what still works — at 1,100,001 live edges, no#[ignore], no env gate, so it is insidecargo test --workspace, which IS inREQUIRED_JOBS.What is actually open on #41:
grep -c 'Instant::now'returns 0 in bothgeneration_promotion.rsandgeneration_collect.rs. #41 says rollback is to be measured.index.rs:12329 bench_reported_scaleis#[ignore]d, has zero assertions, and is named by no CI job. And the general defect behind it:release_gate.rs::TIMING_GATES, the mechanism that pins every#[ignore]d bench to its ci.yml step, can only pin integration-test binaries, so an ignored lib test is invisible to it by construction.Plus two smaller: no RSS is read anywhere in
graph_cap_scale_e2edespite the graph-cap leg's "no allocation spike/OOM" bullet, and the 100k GC arm IS dispatched nightly (--ignoredwith no name filter) with notimeout-minuteson step or job, and has never been observed to complete.#45 — unchanged, and now scoped
Criterion 3 (inert/activation/rollback/removal ratcheted) and criterion 2's XAML half remain NOT STARTED. The scoping (full detail on #45):
projection::stage_row's existingproducer.*/influence.*prefixes with no new observation code.crates/indexer/tests/drives a generation lifecycle with a real package — all six cited sites use compiled-inFixturePlugins andExtractors::builtin, so none can emit a package-bearingproducer.*row. (b)resolved_by::bridgeneeds a C# corpus that does not exist:find tests/packages/xaml -name '*.cs'returns nothing, and both declared bridges arepaired_file, which needsX.xamlbesideX.xaml.cs.stage_row's closed sets PANIC on an unknown code; per-state plugin-host spawn cost).The gate's own thirteen steps — one correction
#187 is still live, verified at
552e3a2.release_gate_e2e.rs:102-122says musl iscontinue-on-error; it is a separatebuild-musljob, andrelease.yml:1167-1177explicitly argues why it is a job and not acontinue-on-errormatrix leg. The same block says of step 13 "Nothing in this repository runs it today";ruby_package_parityis dispatched atci.yml:935. Both stale sentences point the same way — toward more remaining work than exists.The question this lane was asked, answered plainly
No. After this pass the release gate's remaining scope is NOT only #80's own thirteen-step operator walk.
Two blockers remain with real, sized work in them:
Beyond those, step 12 still owes what it always owed (aarch64 cross-built and never executed; the shipped Windows archive is windows-gnu while the native test proves the MSVC debug binary; the eleven-step sequence runs on Linux-gnu only), and step 13's implementation exists but the gate's own file does not know it (#187).
What is now true and was not this morning: #73 is closed with a measurement, and #51's last open line is settled with a green, executed run. Two of the four are done.
Two product findings from doing this work, since we are our own users
read_codeon/tmp/cosi-lane-release/...answerspath_outside_known_rootseven though both checkouts are the same repo at the same commit (verified bygit rev-parseand md5 on the files). The hint offers a[[links]]entry, which is heavy for what is literally the same tree. Lanes work in worktrees here by policy, so this is the common case, not an edge one.evidence_gaps.partial_sources_in_index: 1fired on every single reply in this session andpartial_sourceswas never populated. A disclosure that always fires and never names the file is not actionable, and it is the shape this project has elsewhere called out by name.🤖 Generated with Claude Code
https://claude.ai/code/session_01K1zj5VcFJvJt3pQxe9259K
Close-out sweep: the open list is now TRUE. 63 open issues, and this gate's own dependency list has 3 left, not 9.
Close-out lane, master
552e3a2. Six lanes landed work in the last few hours and closed almost nothing, so the open list overstated the remaining work and had already caused two under-scopings of this gate. This comment states the corrected figures.Count method, because it has been wrong three times in two days: the Forgejo issues API caps at 50 rows and silently ignores a larger
limit. Paged until a short page — 50 + 13 + 0 = 63 open issues.Closed by this sweep (7), each with evidence in its own closing comment
Stage::Bridgeinresolve_budget.rs:129/:154,BRIDGE_WORK_BUDGET_DEFAULTatindex.rs:2582,guard_measured_atatindex.rs:7371; xaml gate EXIT=0,corpus_stageEXIT=0executed=7index.rs:2530-2582if: success() || failure()guards;ci_cadencegate with a paired can-fail detector; verified by dispatch (job 33556,agent_task_benchran, 5 passed)ruby_package_parityEXIT=0,executed=1 controls=4, 834/31/11nameof-class occurrence in C#name_identifieratcsharp.rs:1997on bothemit_callarms; residual 34 over-binds carried by #189future_import_statementarm + a registry that discovers node kinds from the compiled grammarKept open, with corrected text and titles (10)
#168 #173 #174 #175 #177 #178 #179 #180 #125 #93. Every one was reported as fixed or as a refusal by its lane, and every one still has a live, reproducible residual. Titles were rewritten where the filed diagnosis turned out to be wrong — most sharply #175 (the cause is
method_call → POOL_METHODpluspython.rsminting no module symbol, not package directories) and #168 (both proposed directions were measured, cost ~1 300 correct binds, and did not fix the two phantoms — they relocated them into the stem-anchored arm).Two were refusals backed by numbers and are recorded as such without closing, because the refusal disposed of the direction, not of the defect: #168 and #170's direction 2 (refuted by reading the eleven rows — the package leg's answer is the correct one).
This gate's formally linked blockers: 3 of 9 remain
The body lists nine. Current state:
The phase chain is also complete: #76, #77, #78, #79 are all closed. What is left of #75's structure is this gate, plus #84 (the step-13 full-language migration proof) and #86 (the three ABI gaps that block migrating any language other than Ruby or PHP).
So the honest scoping of #80 is: #41, #45, #51, #84, #86, plus the 13-step end-to-end gate itself.
Two things that should change how this gate is read today
1. Master has never been through CI. Local master
552e3a2is 7 commits ahead oforigin/master(a9ba058) and unpushed:74d241b acfd41b 8d90075 8d9ac8e df1551f 0f011cd 552e3a2. Every green cited by the lanes above — including the whole #180 second half and the Windows shell-out fix — is a local green. Step 12 of this gate ("repeat the runtime gate on every shipped platform") cannot be evaluated against an unpushed tree.2. The Windows job is red. Dispatched twice since the #179 fix (run 610 / job 33546 at
45cf6e4; run 612 / job 33560 ata9ba058) — failure both times, onci_disk_preflightandschedule_liveness, both spawning a.shon a platform with no interpreter. The local fix is8d9ac8e, itself unpushed and therefore also unverified by dispatch.windows-gategates releases.The 63, grouped
#75 structure (4): 75, 80, 84, 86
#80's remaining formally-linked blockers (3): 41, 45, 51
Roadmap / backlog under #75 (18): 24, 27, 28, 31, 32, 34, 35, 42, 46, 47, 48, 49, 50, 53, 59, 68, 69, 70
Findings, mostly from the last few days (38): 93, 98, 111, 119, 120, 124, 125, 128, 133, 137, 149, 153, 154, 158, 159, 160, 162, 166, 168, 173, 174, 175, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192
One caution about that last group, for anyone sizing this gate from it: #188 records that
precision_gate's 7/7 withphantom_count == 0is ~47 probes over 54 fixture files and never indexes a corpus repo. It is cited constantly in lane reports and is not evidence about corpus-scale resolution. The corpus-scale evidence iscorpus_ratchet/corpus_stage/corpus_tier3_ratchetat a non-zeroexecuted=— withoutCOSI_CORPUS_DIRthey reportexecuted=0 unavailable=1and pass.release_gate_e2e.rs:102-122still says musl is continue-on-error and that nothing runs the step-13 migration gate — both false since #84 #187code-index://docs/reason-codesis at 3,979 of its 4,000-token cap, so the next reason code this project mints cannot be documented #184Close-out round 2 — the true remaining count on this gate, 2026-09-06, master
fc329a8Four lanes merged since the last close-out and closed nothing. This lane verified their claims against the tree and settled ten issues. Posting this gate's real state so it stops being re-derived.
Repository-wide: 55 open issues (was 61). Counted by paging the Forgejo issues API to a short page — it caps at 50 rows and silently ignores a larger
limit.The nine adjacent release blockers this issue formally links — 6 of 9 are now closed
Three remain, and all three are measurement work rather than product work. Plus the two issues hanging directly off this gate: #84 (step 13, the full-language migration proof) and #86 (the three plugin-ABI gaps that block migrating any language other than Ruby or PHP).
The final end-to-end gate cannot run today, and that is the headline
Step 12 says "repeat the runtime gate on every shipped platform", and the release workflow's
windows-gateis what enforces it.fmt + clippy + build + test (windows)has failed on both87a3fc8andfc329a8(runs #4978 and #4980). It gates releases.OSS corpus (tier 1)failed onfc329a8and was green on87a3fc8. Reproduced locally and attributed:corpus_costbreaches onphp-guzzle,vm_step 44,631,448 → 49,762,991 (+11.5%, over the +5% ceiling). The only two repos that moved up are the only two languages inRECEIVER_LOCALITY_BLIND_PROFILES; every other language is flat within ±0.5%. These are SQLite opcode counters, not the clock. Full evidence and the "do not bless it green" argument are on #189.release.ymlhas not run at all in the newest 30 forge runs, so #162's scheduler-liveness step — which sits insidewindows-gate— has never executed. That is recorded on #162.So of this issue's 13-step final gate, step 12 is currently unrunnable and step 13 is unstarted (#84). Everything green on this tree is green on a tree whose own CI is red.
Settled this round
Closed: #188 (
precision_gatereports and ratchets its own population — 47 probes, 23 declared decoy sites, 87 files, 0 corpus repos, JavaScript'sforbid_sitesis 1; floor mutation run to red by this lane), #189 (inverted receiver gate, now three-valuedrecv_proof), #111 (five payload categories on the wire, summing to the measured total), #98 and #133 (reconciled, closed separately, neither as the other's duplicate), #120 (the "10x less context" claim, corrected at five sites with an inverted pinning test).Left open with corrected residuals: #149 (
dynamic_influence.semanticsships but nothing asserts it — deleting its initializer compiles and stays green), #158 (no blessed absolute read-pathvm_stepover the corpus), #160 (items 1 and 3; tool descriptions are 38,636 chars, +1,293 above the figure the issue was filed on, andfind_calleesis still a separate tool), #162 (implemented, unit-graded, never executed).Note for this gate specifically: #160's item 1 bears on the disclosure model here. This issue requires "reference documentation belongs in resources, not repeated on every tool schema", and the description budget has grown, not shrunk, since that was written.
plugin enableindexes nothing on a newly-claimed extension, andpackage_fixture::XAML_BRIDGESholds a bridge key the production door refuses while its doc claims the guides show it #207$max_tree_bytestruncates real-world files from ~80 KB — measured on a 14,056-file production repo, ~50 files affected #222pluginsubcommand is documented —plugin updateshipped with ZERO operator documentation and every gate green #256