Repository navigation
Record the class where a diagnostic's name is accurate about the situation and silent about the mechanism - #9414
Merged
Conversation
…ation and silent about the mechanism
A diagnostic's NAME describes the state it was raised in faithfully and says nothing
about WHICH PREDICATE produced it. Nothing in the name is wrong, which is why review
reads past it, and a reader who treats the name as a cause builds a coherent story with
no load-bearing contact with the code.
Three receipts in one night from three readers, provenance stated per receipt inside the
row because a row about untraced names must not itself rest on an untraced relay:
1. Measured by this author, and it leads because the reader was the author of the
story. rustc labels reading `expected Rc<Vector<i64>>, found String` at 49 sites
plus 2 reversed; a representation fork in the model type `Symbol` was inferred and
published. Measured: `Symbol` renders consistently as `String`, `Connective.Atom`
carries `identity: String`, and the .dag is well-typed with the same declared type
on both sides. AND THE CHECK FAILED THE SAME WAY THE READING DID -- a grep for the
printed type name returned zero and zero was read as absence, when the source spells
`Rc<Vec<i64>>` and lib.rs carries `use im::Vector as Vec`, so rustc was printing the
resolved underlying name. What the 49 sites actually are is left named and UNCHASED:
`Rc<Vec<i64>>` is how `List<Int>` renders. The amendment closed the wrong
explanation, not the defect.
2. Reported by quick-bat-372, independently verified by warm-hawk-909 at
04_infer.dag:3541: `MethodNotFound` does not say which predicate gates it --
`method_existence_decision` gates on `kernel_profile_lookup`, so a fully resolved
user product with no kernel profile answers `MethodExistenceUndecided`.
3. Same provenance, verified by exhausting the three FieldNotFound construction sites
(04_patterns.dag:356 and :362, 04_infer.dag:6234): there is no field-ACCESS
producer at all.
Two of the three would have shipped as permanently-green witness arms -- an assertion
that a wall fired, over a wall that cannot fire for that input. That is 4b's
decoration-cited-as-coverage reached by a route no existing row names, and all three
were caught by reading the PRODUCER rather than by review. The row carries its own rate
caveat: three instances in one night is a suggestive rate and not a base rate.
Distinctness, since it borders two existing rows and is neither: "identical diagnostic
text is not identical cause" is about two SITES sharing a spelling; "a suggestion names
where the failure was detected, not caused" is about LOCATION. This is about the NAMED
CONCEPT -- one name, accurate and mechanism-silent.
DESIGN.md IS NOT REGENERATED BY THIS COMMIT, AND THAT IS NOT A DEFECT THIS CHANGE
INTRODUCED. No route in this repository regenerates it. `generated_artifact_body_for_path`
is not CLI-callable (it returns `GeneratedArtifactPathBody`, not `ProcessExit`) and is
reached only through the interpreter by claim_executor for drift CHECKING; both consumers
of `Produced` are read-only. There is no --heal, --converge, --write-artifact or
--regen-artifact on any bin, and the hooks do cargo fmt and repo-local git config only.
claim_executor's own comment beside the Produced arm names byte identity here as "exactly
the drift check that has had no owner since" the floor cut, and DESIGN's unguarded list
names heal -- which was the writer. The artifact is therefore stale with respect to this
row until an actuator exists; the actuator is dispatched as its own lane rather than
riding here, because a write beside an existing read is load-bearing enough to deserve
its own reasoning and review.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 27, 2026
Second merge of main in one resolution: main advanced 9 commits while the first regeneration was running, so the same two generated projections re-conflicted. That is a property of the projection being SHARED -- nearly every lane edits DESIGN.md -- not of the resolution, and no amount of care wins the race, only merging sooner. The .dag authorities merged cleanly again, carrying BOTH main's new `diagnostic_name_mechanism_silent` row (#9414) and this branch's restored `bound_shaped_closure`. Only the projections conflicted, and they are regenerated rather than hand-resolved. THE REGENERATED DESIGN.md NOW DIFFERS FROM MAIN BY THREE LINES AND ALL THREE ARE ACCOUNTED FOR. Two are this branch's own edits. The third is the recurring-failure-mode line, and it differs because MAIN'S DESIGN.md IS STALE AGAINST ITS OWN AUTHORITY IN THE OPPOSITE DIRECTION FROM THE ORPHAN REPAIRED IN THE PREVIOUS COMMIT: main DESIGN.md 'accurate about the situation' -> 0 main recurring_failure_mode.dag diagnostic_name_... -> 3 #9414 landed the authority row without regenerating the projection, so main's committed DESIGN.md does not render a class its own authority declares. Regenerating here renders it, which is the correct projection rather than an edit by this branch. So this repository currently has generated-artifact drift in BOTH directions on one file: content in the projection that no authority produces (repaired in the previous commit), and content in the authority that the projection does not render (rendered here). Both are invisible to anyone who does not diff a regeneration against the committed copy and account for every changed line. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 27, 2026
#9414 added a row to `gunbc.recurring_failure_mode` on main. That module is an input to `gunbc.design_document`, so the merge result's authority no longer matches the committed projection. WORTH RECORDING BECAUSE IT IS A PROPERTY OF THE PHASE AND NOT A ONE-OFF: CI adjudicates the PULL REQUEST MERGE COMMIT, not the branch head, so the phase compares the projection against the MERGED authorities. A branch that is internally consistent goes red the moment main lands an authority change under it -- which is correct, since the post-merge tree is what would sit on main -- and the remedy is always the same: merge and regenerate, never hand-edit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
briansrls
pushed a commit
that referenced
this pull request
Aug 27, 2026
…a required CI phase — the writer exists and is run by hand, so the gap is enrolment, not a missing regenerator (#9415) * No route checked DESIGN.md or ROADMAP.md against their authorities: enrol the whole committed generated-artifact population as a required CI phase `gunbc.generated_artifact_emit` `generated_artifact_body_for_path` is a pure projection over the three authorities `main_wet` folds -- the committed-artifact roster, `artifact_path`, and the single `artifact_generate` dispatch -- and it answers, for any repo-relative path, exactly what the tree ought to hold there. THE PRODUCER WAS NEVER MISSING AND NEITHER WAS THE WRITER. THE CHECKER WAS. (Premise correction from warm-hawk-909, who wrote the brief: the work item's title says no route REGENERATES these files, and that is false -- `tools.generated_artifact_gate` `main_wet` is a declared writer. Nothing here adds a second one; every repair below was installed by invoking that one.) From the 2026-08-15 floor cut until this change, the only route that ASKED the projection anything was `claim_executor`'s behavioural-receipt census, which asks only about paths of the form `src/v1/stage0/src/<mirror>` because its subject is emitted Rust mirrors. Every committed artifact that is not a Rust mirror -- `DESIGN.md`, `ROADMAP.md`, the workflow YAML, `.gitignore`, `.gitattributes`, the githooks, the plans -- was compared by nothing. DESIGN's own CI paragraph named the generated-artifact drift gates on the re-add queue that cut created; this is the first item taken off it. WHAT THE PHASE FOUND ON ITS FIRST EXECUTION, measured at 441ce5c (stated with its subject sha because the gate's whole purpose is to make this number zero, so it is not re-derivable from a later tree): rostered=72 adjudicated=72 matches=68 drifted=2 absent=2 unadjudicated=0 TWO WERE DRIFT AND ARE REGENERATED HERE: DESIGN.md this change's own authority edit docs/plans/realization-measurement-loop.md #9394 dissolved the ContainerRuntime nickname in the authority and the projection still named it The second is the headline: an authority-side divergence with a provenance I did not author, wrong since #9394, invisible to everything. It is also what proves the generator READS the authority -- a checker comparing a file to itself cannot produce it. THE OTHER TWO WERE NOT DRIFT AND ARE NOT REGENERATED. `docs/plans/v2-corpus-self-host.md` was DELETED ON PURPOSE by a295e17, whose entire subject is the ruling that the .dag carrier is the authority and the markdown should not exist; `docs/plans/import-namespace-program.md` has never existed at that path. An earlier revision of this branch regenerated both. That was wrong, and the way it was wrong is the most dangerous shape this phase can have: a drift gate makes whatever it adjudicates BINDING, so an absence that was inert before becomes a line-stop, and the cheapest way to move the line is to regenerate -- converting a dormant registry mistake into a standing obligation to recreate deleted files, green either way. Caught in review by warm-hawk-909. THE STALE HALF WAS THE REGISTRY ROW, NOT THE MISSING FILE, so the repair runs the other way: `gunbc.plan` gains `PlanProjection`, a plan declares whether its markdown is a committed artifact at all, and `artifact_commit_policy` asks the plan instead of answering `CommitRequired` for every slug. `PlanIsAuthorityOnly` carries the ruling that removed the projection, so the row cannot drift from its reason. It is NOT an exemption list and NOT a shrink: both plans stay rostered, stay generated, and still refuse if generation refuses -- only whether their bytes are expected on disk changes. The field is required, so a new plan cannot omit the decision. CONSTRUCTION, not another roster. The host resolves `generated_artifact_emit` once and asks it for BOTH the roster (`committed_generated_artifact_paths`) and each body, so an artifact added to `generated_artifact_registry` is enrolled with no edit to the host, and a path list in Rust -- the second roster DESIGN 3 forbids -- does not exist. Production precedes adjudication in the TYPE: every verdict is reached through the produced population, so "refused, having compared nothing" has no spelling outside the arms that carry no population. TWO COUNTS, NEVER ONE. A rostered member that reaches no verdict is reported and stops the line SEPARATELY from a drifted one. `0 drifted` over a population nothing asked about is the execution-provenance loss DESIGN names, and the discriminating unit test asserts exactly that: an outcome whose every verdict matched is NOT clean while one member is unadjudicated, and is still not reported as drift. READ-ONLY BY CONSTRUCTION: no write path, no flag that opens one. Installing a regenerated artifact stays `main_wet`'s job, because a gate that can also write its own subject is a gate whose green proves nothing. The bridge `claim_executor` had declared privately (`GeneratedArtifactPathBody`, `generated_artifact_ctx`, `generated_artifact_body_for_path`) is hoisted into `v1_compiler::cli_run::generated_artifact_boundary_host` and re-exported through `cli_run`, the way the regen and partition-crate producers already are, rather than copied -- two hosts asking one projection is the forked dispatch DESIGN 3 forbids. The new file is registered as seed-retained hand Rust in `v2.compiler.self_host.stage0_crate_layout`, beside `partition_crate_boundary_host`; its layout projections are regenerated. The refusal names a route that EXISTS, in one place (`GENERATED_ARTIFACT_PRODUCING_COMMAND`), because a stop whose only sanctioned move is unavailable does not stop the line, it launders a hand edit. EXECUTED, whole build lane, from binaries built out of this tree: regen first_generation_equal=true v2-emission EmissionCompleted blocking=0 partition-crates rendered=14 matches=14 generated-artifact rostered=70 adjudicated=70 matches=70 drifted=0 absent=0 unadjudicated=0 lane=build phases_run=4 failed=0 WHAT IS NOT CLAIMED: `main_wet` generates and writes one artifact at a time, so a refusal partway would install a mixed projection epoch. That is a mechanism read, not an executed receipt -- no generation refused here -- and it is left to its own PR with its own receipt rather than repaired on a hypothesis. THE SEED-GROWTH OBLIGATION FOR THE NEW HOST RUST (codex/gpt-5.6-sol, review 56588). The registration in `stage0_crate_layout` acknowledges the file; it does not reconcile it with DESIGN 7's shrinking-seed mandate, and that reconciliation is what the gate requires. `gunbc.generated_artifact_boundary_seed_growth` now carries it, joined into `gunbc.seed_growth_admission`'s roster: 19 declarations enumerated at identity grain rather than counted, the reason Rust is needed at all (the comparison is against BYTES ON DISK, a host effect the hermetic floor refuses by construction), the rejected alternative and why (running the existing gate through the interpreter in Wet mode makes the interpreter load-bearing for a NEW required phase while two lanes delete it, and would drag in `artifact_extra_valid`'s `ci_yml_parses` as a second unasked subject), the owning lane (`v1-hand-queue-drain`), and a trigger that names the capability rather than an artifact: delete all 19 when a modeled operation can read a committed file's bytes inside the required envelope. THE FOUR INHERENT METHODS BECAME FREE FUNCTIONS TO PAY THAT OBLIGATION HONESTLY. `std.decl_ref` offers `WholeDeclaration` or `NamedField` and neither names a method on an `impl` block, so every method would have been an item this roster could not cite -- growing exactly the uncitable-item class `gunbc.seed_growth_admission` counts. There is now no `impl` block in the file and zero of the 19 rows are uncitable. NET, STATED SO THE ROSTER IS NOT MISREAD AS A DIFF: three of the 19 (`GeneratedArtifactPathBody`, `generated_artifact_ctx`, `generated_artifact_body_for_path`) are DELETED from `bin/claim_executor.rs` in this same change, so the corpus-wide delta for those three is zero and only their home moved. THE PROJECTION DECISION DESCENDS INSTEAD OF COLLAPSING (codex/gpt-5.6-sol, review 56610). The first cut of `PlanProjection` carried a `plan_projects_committed_markdown(p) -> Bool` predicate that matched the coproduct into true/false, and `artifact_commit_policy` then branched on the Bool. That is the predicate residue DESIGN 6 forbids, and it is also the "total at the level examined, blind one level down" shape one entry over: a second projection state would have had to pick an existing Bool rather than failing to compile at the decision. The predicate is DELETED and `artifact_commit_policy` matches `plan.projection` directly, so a new `PlanProjection` variant fails to compile exactly where the commit policy is decided. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Regenerate two plan projections the merge left behind `docs/plans/budget-tree.md` and `docs/plans/ci-humming.md` are projections of `gunbc.plans.budget_tree` and `gunbc.plans.ci_humming`, both of which git auto-merged when main came in. The regeneration ran, but its output was left UNSTAGED and `git commit` on a merge commits the index -- so the merge commit carried the merged authorities and the pre-merge projections. Caught by the `generated-artifact` phase this branch adds, on its own branch, naming both paths. That is the phase doing exactly what it exists for, on the class it exists for, against its own author. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * An empty roster reported clean: refuse it at the producer and at the predicate Found in review (codex/gpt-5.6-sol, review 56696), and it is a real defect in exactly the class this phase exists to close. `boundary_is_clean` required that every verdict matched and nothing was unadjudicated -- both VACUOUSLY TRUE of an outcome carrying zero members. So a run that adjudicated NOTHING rendered identically to a run that adjudicated seventy paths and found them all correct, and neither reporting branch in the phase body fired, so the line did not stop. That is the empty-observation narrow DESIGN names -- bottom-as-answer conflated with bottom-as-ignorance -- and it is strictly worse than the widen 5 already forbids: a widen is merely expensive, a narrow is silently uncovered. The PR body claimed "nothing was asked cannot appear clean". It could. CLOSED AT THREE LEVELS, none of them redundant with the others because each is reachable where the next is not: PRODUCER. `run_generated_artifact_boundary` refuses an empty roster with a typed cause. `committed_generated_artifacts` filters a module-scope literal, so empty is never a fact about the tree -- it means the projection or this bridge lost sight of the population, which is ignorance and must refuse. PREDICATE. `boundary_is_clean` no longer admits an empty population. This covers any outcome VALUE, including one a caller or a fixture builds by hand, which is the only boundary at which the state is still expressible now that the producer refuses it -- and therefore the only boundary at which its RED is authorable, which is what 4b requires before a check is worth writing. PHASE. The phase's verdict now derives from `boundary_is_clean` alone; the two reporting branches name WHAT went wrong, they no longer decide WHETHER anything did. A state neither branch happens to describe refuses with an explicit unnamed-cause line rather than falling between them. A second definition of clean beside the carrier's is the fork that lets a ledger and a gate disagree about one run. THE DISCRIMINATING RED IS AUTHORED AND CARRIES ITS POSITIVE CONTROL: `an_empty_population_is_not_clean_even_though_no_verdict_disagreed` asserts the empty outcome is not clean AND that a single matching member still is, so the conjunct is emptiness rather than a blanket refusal. It returns green under the previous code, which is the state it exists to forbid. Five tests pass. The seed-growth roster grows by one to 20 and its trigger is re-counted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Regenerate DESIGN.md against main's recurring-failure-mode addition #9414 added a row to `gunbc.recurring_failure_mode` on main. That module is an input to `gunbc.design_document`, so the merge result's authority no longer matches the committed projection. WORTH RECORDING BECAUSE IT IS A PROPERTY OF THE PHASE AND NOT A ONE-OFF: CI adjudicates the PULL REQUEST MERGE COMMIT, not the branch head, so the phase compares the projection against the MERGED authorities. A branch that is internally consistent goes red the moment main lands an authority change under it -- which is correct, since the post-merge tree is what would sit on main -- and the remedy is always the same: merge and regenerate, never hand-edit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Install the regenerated stage0 layout mirror: the merge resolution took main's copy, which predates this branch's host registration Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
One row in
dag/gunbc/recurring_failure_mode.dag, registered inrecurring_failure_mode_roster: a diagnostic's NAME is accurate about the situation and silent about the mechanism. Nothing in the name is wrong, which is why review reads past it, and a reader who treats the name as a cause builds a coherent story with no load-bearing contact with the code.Ruled in by direction (warm-hawk-909), who verified receipts 2 and 3 at their sites rather than taking them on relay.
The three receipts, with provenance per receipt
A row about not trusting a name you have not traced to its producer must not itself rest on an untraced relay, so the provenance is inside the row.
1 — measured by me, and it leads because the reader was the author of the story. rustc labels reading
expected Rc<Vector<i64>>, found Stringat 49 sites plus 2 reversed. I inferred a representation fork in the model typeSymboland published it. Measured:Symbolrenders consistently asString,Connective.Atomcarriesidentity: String, and the.dagis well-typed with the same declared type on both sides.And the check failed the same way the reading did — this is the instructive part, not decoration. I grepped for the printed type name, got zero, and read zero as absence. The source spells
Rc<Vec<i64>>, andlib.rscarriesuse im::{OrdSet as BTreeSet, Vector as Vec}, so rustc was printing the resolved underlying name. I read a name as a fact about the tree twice in one investigation — once in the diagnostic, once in refuting it.What the 49 sites actually are is named and left unchased:
Rc<Vec<i64>>is howList<Int>renders, so they read expectedList<Int>, foundString. The amendment closed the wrong explanation, not the defect.2 — reported by quick-bat-372, independently verified by warm-hawk-909 at
04_infer.dag:3541.MethodNotFounddoes not say which predicate gates it:method_existence_decisiongates onkernel_profile_lookup, so a fully resolved user product with no kernel profile answersMethodExistenceUndecided.3 — same provenance, verified by exhausting the producers (
04_patterns.dag:356,:362,04_infer.dag:6234):FieldNotFoundhas no field-ACCESS producer at all. The clause about what field access raises instead is dropped — it was not verified, and this row must not carry an untraced name.Why it earns a row
Two of the three would have shipped as permanently-green witness arms — an assertion that a wall fired, over a wall that cannot fire for that input. That is §4b's decoration-cited-as-coverage reached by a route no existing row names, and all three were caught by reading the producer, not by review.
Distinctness, since it borders two existing rows and is neither: identical diagnostic text is not identical cause is about two sites sharing a spelling; a suggestion names where the failure was detected, not caused is about location. This is about the named concept — one name, accurate and mechanism-silent.
The row carries its own rate caveat: three instances in one night is a suggestive rate and not a base rate; all three surfaced while several lanes were unusually deep in diagnostic populations.
Placement
Appended after
remediation_mutated_viewso the roster stays append-only and the carrier's own empty-diff projection oracle is preserved — its header notes that sorting the rows would destroy that oracle.DESIGN.md is not regenerated by this PR, and that is not a defect this change introduced
No route in this repository regenerates it. Measured, not assumed:
generated_artifact_body_for_pathis not CLI-callable —gunbc runrefuses with returnedGeneratedArtifactPathBody, notProcessExit. It is reached only through the interpreter, byclaim_executor, for drift checking.GeneratedArtifactPathBody::Producedare read-only.--heal,--converge,--write-artifactor--regen-artifacton any bin undersrc/v1/stage0/src/bin.cargo fmtand repo-local git config only.claim_executor's own comment beside theProducedarm names byte identity here as "exactly the drift check that has had no owner since" the floor cut — and DESIGN's unguarded list names heal, which was the writer.So the artifact is stale with respect to this row until an actuator exists. Direction ruled this route explicitly over the alternatives: hand-editing
DESIGN.mdcannot be verified without the generator's output, which would make it an unverifiable hand-edit dressed as a regeneration — strictly worse than an honest divergence, and the thing #9402 was closed for. The actuator is dispatched as its own lane, because a write beside an existing read is load-bearing enough to deserve its own reasoning and review rather than being waved through as unblocking a doc row.Verification
Module compiles as an entry: 0 blocking diagnostics.
🤖 Generated with Claude Code