Repository navigation
Decide a record-literal field's reference layer from identity, not spelling - #8984
Merged
Merged
Conversation
…elling
Same resolved declaration, different authored spelling, must produce the
same Rust. emit_field_value_with_context decided the shared reference
layer of a record-literal FIELD VALUE with
set_contains(shared_types, rc_name)
where rc_name is the name AS AUTHORED, while shared_types is keyed on the
bare declared name -- the same mismatch alias_rhs_qualified_name_routing_note
already records for every other lookup on that path. A qualified spelling
matched nothing, so the value was emitted UNWRAPPED into a field whose
declared type is Rc<T>. That is not a style difference: it is a type error
rustc reports as E0308, and no correct declaration can compensate for it.
needs_box_wrapping reads the same authored spelling for the same decision
and is repaired with it; the witness pins the field-value arm, and that
second call is the same lookup on the same decision rather than an
independently evidenced one.
MEASURED, minimal, both arms against one provider:
bare uri: Rc::new(QualspellUri \{
qualified uri: QualspellUri \{ <- before
qualified uri: Rc::new(QualspellUri \{ <- after
DISCRIMINATING RED, BY EXECUTION rather than by inference: the witness
returns false against an emitter with this one decision reverted, and true
with it. Both runs were performed; the red is not deduced from the earlier
output.
WHY MAIN IS GREEN WITHOUT THIS. The measured seed closure contains almost
no qualified type reference, so an ordinary green regen exercises the bare
arm only -- which is why the witness AUTHORS the qualified arm instead of
relying on the corpus to contain one. 4066 qualified dotted type references
already exist corpus-wide (555 files, 2314 in src/v2) and enter the seed
closure as v2 self-hosting advances, so the population reaching this path
grows with the roadmap rather than staying latent.
ZERO-DRIFT, AND WHY IT IS STRUCTURAL: qualified_last_segment is the
identity on an unqualified name, so every bare spelling emits exactly as
before. Receipt: required-regen over the 132-module subject reports
first_generation_equal=true with only this repair's own mirror changed.
DECLARED RESIDUE, not fixed and not claimed. A qualified reference to a
zero-parameter ALIAS is still peeled to its target, and where that target
lives in a THIRD module the peeled name reaches the output with no
use-line (E0412). Located cause: a qualified reference parses as a
module-projection spine, so it fails the NoConnective-and-childless guard
on the alias-preserving branch of render_rust_fn_sig_type and never
reaches the alias lookup at all. Three candidate repairs were written and
all three were reverted here rather than landed unproven, because none is
pinned by an executing control. The fixture cannot carry that RED either:
compile_dag_rust_emit_check compiles the probe against an import-driven
source set, so a third fixture module turned the BARE control red -- the
harness refusing the closure, not the emitter failing. Recorded so the
next attempt does not rediscover both walls.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
MEASURED ON THE FIRST CI RUN, not predicted. As one conjoined claim this witness grew RSS by 1.22GB and was the floor's worst single claim, against 0.12GB for the whole rest of the roster on the same-day main run -- both compile_dag_rust_emit_check calls are live inside one claim and each builds a corpus-wide scope. The two arms are independent propositions -- the RED and its regression control -- so they are two test fns. Each compile is now evaluated and collected on its own, and a failure names WHICH arm broke instead of returning one conjoined false. DESIGN section 6, bare minimum cost: a proven cost-shape defect is fixed regardless of the realized n. Nothing refused on this run and no budget was exceeded, which is exactly the condition under which the fix gets skipped and the cost is left to break someone else's budget later. NOT FIXED HERE, because it is not mine: this PR's CI failure is REQUIRED-FLOOR REFUSAL cause=TerminalLedgerUnrenderable reason=seed-disposition-disagrees offending= test.claim.accelerator_demo_execution_witness.accelerator_demo_execution_lane_witnesses, which reproduces byte-identically on main (run 32617459831, sha dcac648). The floor-known-red line is also identical on both -- 206 held, 6 now PASS. Both are pre-existing main breakage, and the only line this PR moved was the memory one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 23, 2026
…ne mirror that collided The only conflict was src/v1/stage0/src/v1_compiler_emit_rust.rs, a generated mirror. A generated artifact is not merged, it is regenerated from the authority both sides edited: main's 05_emit_rust.dag changes and this branch's two-site fix merged cleanly by content, so the mirror was rebuilt from that composed authority rather than hand-reconciled. Receipt, measured on this merge rather than transcribed: pass 1 reported first_generation_equal=false with changed_paths=[v1_compiler_emit_rust.rs] -- exactly the staged-from-main base lacking the fix -- and pass 2 after installing the candidate and rebuilding reported first_generation_equal=true, planned=133 executed=133, declared_divergent=1 [main.rs], the known hand-maintained entry. The emitted delta is the two sites and nothing else: needs_box_wrapping now compares the qualified last segment of the authored name, and emit_field_value_with_context does the same for rc_name. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 23, 2026
…overed Operator ruling 2026-08-23: kill/quarantine it and find out why. Both halves are here -- the move, and the measurement that makes this a filed defect rather than a cost row. #9031's run 32657761997 was otherwise clean (failed=0, stale_quarantine=0, interrupted_before_verdict=0) with ONE non-pass: COMPLETED-OVER-COST-REQUIREMENT qualified_spelling_takes_the_shared_layer wall_ms=57337 cpu_ms=57193 [floor-claim-memory] grew rss by 1.22GB (to 11.70GB) 11x the 5000ms executor fail-stop. The fail-stop is doing its job: at 11.70GB this claim genuinely threatens the process it runs in. THE SPLIT THAT WAS SUPPOSED TO FIX THIS DID NOTHING, and that is the finding. #8984's own note records the conjoined two-arm claim at 1.22GB RSS growth against 0.12GB for the whole rest of the roster, and splits the arms into separate test fns on the reasoning that two live compile_dag_rust_emit_check calls sat inside one claim. Measured after the split, the QUALIFIED ARM ALONE grows 1.22GB -- the identical figure -- and the bare arm appears in no over-cost or memory line at all. So the entire cost was always the qualified arm. It is not two compiles; it is the qualified-name resolution path specifically, which is the path #8984 exists to repair. WHY QUARANTINE AND NOT A COST ENVELOPE. An envelope large enough to admit 57s and 1.22GB would admit the defect rather than measure it. The dissolution condition on this row is therefore the REPAIR, explicitly not an envelope, so nobody closes it by raising the ceiling. WHY IT REACHED MAIN UNSEEN. #8984 landed in the batch after the last green run while main refused at floor PREPARATION on an unrelated ArgvCommand seal break, so its floor phase never executed and this row never surfaced on its own check. That is the same masking that hid #9022's roster defect in the same batch -- two independent defects merged behind one preparation refusal, which is the argument for consuming every gating cause on your own run rather than only the rows you meant to change. WHAT MOVES: the file to dag/test/claim/long/ with its module renamed, one WitnessExclusionRow carrying the measurement and the local recipe, and the provider fixture's prose pointer updated so it does not name a module path that no longer exists. WHAT DOES NOT MOVE: both arms, their assertions and the whole authored rationale are untouched. This is a home change and a declared rung drop, not a repair and not a weakening of what the witness claims.
gunbai-bot Bot
added a commit
that referenced
this pull request
Aug 23, 2026
…ather than by widening the seal (#9031) * Convert the one ArgvCommand site the seal missed, through a builder rather than by widening the seal main does not compile. `extdeps.exec.command` `ArgvCommand` became `sole_constructor { program, arguments }` in #8919, and its carrier states the invariant: "Every ArgvCommand construction site in the corpus was converted in the same change, because a partial seal is a dual-authority interval rather than a weaker seal." One site was not. `gunbc.runner_slot_provision` `observe_runner_slot_members_wet` still built `ArgvCommand { argv: ["ls", "-1", actions_runner_base_dir] }`, producing four distinct diagnostics and refusing the floor at strict-preparation — so no witness ran and no `required-floor` counter line was emitted at all. Not a missed conversion by that PR. #8992 ADDED this site after #8919 was authored and before it merged; neither touched the other's lines, so git merged both without a conflict and the corpus broke on semantics. A clean merge is not coherence. WHAT WAS DELIBERATELY NOT DONE: `runner_slot_provision` is not added to `argv_command`'s `admit_callers`. That list is forty named builders, each for ONE operation of ONE tool, homed in that tool's own extdeps module; admitting a product module would defeat the wall rather than satisfy it. A MODELED ALTERNATIVE WAS LOOKED FOR FIRST and does not exist at this layer. `ls -1 | parse` is a shell-ism, so the right first question was whether the substrate already answers "what entries are under this path" without shelling out. `dag/extdeps/filesystem` carries posix `EntryKind` but no listing operation, and the `list_dir` in `src/v2/extdeps/file_system.dag` is the v2 realization surface, not reachable from a v1-era `wet` observation running over `LocalExec`. So the builder is authored rather than the listing being re-modeled, and the call site keeps enumerating BY DIRECTORY — which its own carrier requires, since probing the desired names could only ever return a subset of what was already intended and would make an out-of-band slot invisible. `-1` is baked into the builder with its reason, following `rm_force_command`'s precedent: ls(1) columnates to a terminal and emits one-per-line to a pipe, so a caller that does not pass `-1` depends on where its output happens to go. It does not recurse and does not include dotfiles; a caller needing either needs its own name, not a flags parameter. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Enrolled-but-never-planned is not a parking spot: it refuses the whole floor The ArgvCommand repair in this branch unmasked a second main-red defect that had never been observed, because every run since it landed died at strict preparation before the fold could reach it. gunbc#9022 enrolled three compile_accepted_unevaluable_program_control identities in the expected-red roster while their file declares ReadsLiveTree, so the DeclinedLiveTree arm declines them (declined_live=899) and they are never planned. The floor requires every ENROLLED identity to be observed among the EXECUTED claims, so the run refuses with cause=ExpectedRedIdentityDidNotExecute count=3. Chunk 21's own annotation states the opposite belief -- "until it lands they are held here so that admission does not red main" -- and execution refutes it twice: on #9022's own run 32644795043, which was merged red, and again on run 32649496046 here, where it was the sole floor refusal once the seal stopped masking it. The precondition that enrolment was authored against has not landed: gunbc#8977 and gunbc#8982, which delete the decline arm, are both still open. The rows are correct and stay in chunk 21. Only their LIVENESS is wrong, so they join the file's existing exclusion in floor_expected_red_is_live -- the mechanism already used for the mock-totality family -- which keeps the rows for provenance while removing them from the live roster. Verified by execution, not by reading the predicate: each of the three returns excluded (exit 1) through --claim-run, and an arbitrary unrelated identity returns live (exit 0), so the predicate discriminates rather than excluding everything. The exclusion is a coupling, not a note: whoever lands #8977 or #8982 must delete these three exclusions in the same change, or the rows will execute while excluded, count as ordinary failures, and red the build. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * The srv4 activation witness re-spelled two programs the seal then moved Third blocker on main, and the first one visible only after the other two cleared: with preparation passing and the roster refusal gone, the fold reaches this row and it returns false. FAIL test.claim.runner_host_deploy.srv4_enables_its_declared_runner_instances The cause is one conjunct, and it is not the width axis this row is otherwise about: && string_contains(s: enable, pattern: "'sudo' 'systemctl' 'enable' '--now'") That was correct against the hand-built argv the row was written for. #8919 routed runner_enable_command_argv through extdeps.systemd.systemctl systemctl_enable_now_command, which mints through the sealed argv_command with sudo_binary_path (/usr/bin/sudo) as the program and inserts sudo's non-interactive flag -- so the rendered prefix is no longer the four words the pattern names, and #8919 updated two lines of this file without reaching this one. WHAT I CHECKED BEFORE CHANGING ANYTHING, because a witness edited to match the code it guards is worse than a red one. Quoting was the obvious suspect and it is NOT the cause: shell_quote single-quotes unconditionally (emit_test's shell_quote(arg: "plain") == "'plain'" pins it), so the unit-name conjuncts still match. Admission was the other suspect and it is not the cause either: the fixture receipts bind correctly on every arm admit_runner_activation checks -- instance host, managed_unit against intended_unit, all six verified flags, pool host, and slice_unit against intended_compile_pool -- so the command is READY and `enable` is a real render rather than the refusal arm's "". THE REPAIR CITES RATHER THAN RE-SPELLS. The old pattern was a third authoring of facts extdeps.sudo.elevation and extdeps.systemd.systemctl already own, which is why it rotted without anyone touching it (DESIGN section 3). The conjunct is now two, deriving the program spellings from those authorities and split because they assert different things: that activation ELEVATES NON-INTERACTIVELY, and that it reaches systemctl's ENABLE --NOW. WHY THIS IS NOT measure() == measure(). `enable` and `--now` stay literal, and they are the discriminating half: they are systemctl's own operands, spelled inline by the builder rather than read from any row, so a command that carried the units without the verb still fails here. What the derived halves buy is that a future re-homing of the sudo or systemctl spelling moves the assertion with the authority instead of leaving a fourth copy to rot. Not verified locally: the same stale-binary limit recorded on the previous commit applies. CI is the authority. * join is not a std.types export: the two derived patterns build with concat Preparation refused on the previous head with a single diagnostic -- runner_host_deploy_witness_test.dag:4:33: name 'join' not found in module 'std.types' -- so the import I added to carry the derived invocation patterns named a symbol that module does not export. The witness already builds every other composed pattern with concat and needs no import for it; the two new ones now do the same. This is my own defect from the previous commit, not new fallout: the repair it carries is unchanged, only its spelling of string concatenation. The stale-binary limit recorded there is exactly why it reached CI to be caught -- a local compile under a binary that predates the seal cannot answer questions about this tree. * Quarantine the qualified-spelling witness, and file the defect it uncovered Operator ruling 2026-08-23: kill/quarantine it and find out why. Both halves are here -- the move, and the measurement that makes this a filed defect rather than a cost row. #9031's run 32657761997 was otherwise clean (failed=0, stale_quarantine=0, interrupted_before_verdict=0) with ONE non-pass: COMPLETED-OVER-COST-REQUIREMENT qualified_spelling_takes_the_shared_layer wall_ms=57337 cpu_ms=57193 [floor-claim-memory] grew rss by 1.22GB (to 11.70GB) 11x the 5000ms executor fail-stop. The fail-stop is doing its job: at 11.70GB this claim genuinely threatens the process it runs in. THE SPLIT THAT WAS SUPPOSED TO FIX THIS DID NOTHING, and that is the finding. #8984's own note records the conjoined two-arm claim at 1.22GB RSS growth against 0.12GB for the whole rest of the roster, and splits the arms into separate test fns on the reasoning that two live compile_dag_rust_emit_check calls sat inside one claim. Measured after the split, the QUALIFIED ARM ALONE grows 1.22GB -- the identical figure -- and the bare arm appears in no over-cost or memory line at all. So the entire cost was always the qualified arm. It is not two compiles; it is the qualified-name resolution path specifically, which is the path #8984 exists to repair. WHY QUARANTINE AND NOT A COST ENVELOPE. An envelope large enough to admit 57s and 1.22GB would admit the defect rather than measure it. The dissolution condition on this row is therefore the REPAIR, explicitly not an envelope, so nobody closes it by raising the ceiling. WHY IT REACHED MAIN UNSEEN. #8984 landed in the batch after the last green run while main refused at floor PREPARATION on an unrelated ArgvCommand seal break, so its floor phase never executed and this row never surfaced on its own check. That is the same masking that hid #9022's roster defect in the same batch -- two independent defects merged behind one preparation refusal, which is the argument for consuming every gating cause on your own run rather than only the rows you meant to change. WHAT MOVES: the file to dag/test/claim/long/ with its module renamed, one WitnessExclusionRow carrying the measurement and the local recipe, and the provider fixture's prose pointer updated so it does not name a module path that no longer exists. WHAT DOES NOT MOVE: both arms, their assertions and the whole authored rationale are untouched. This is a home change and a declared rung drop, not a repair and not a weakening of what the witness claims. * Two zero-byte shell artifacts were committed at the repo root `exit_code` and `{` are both empty files introduced by 96da63f. They are redirect and brace-expansion debris from an interactive shell, not source, and nothing references either as a path: the `exit_code` hits in the corpus are shell-transport OUTPUT FIELD decodings (`exit_code: Int from "exit_code"` in extdeps.shell.exec and friends), which name a captured field, not a file. Removed rather than ignored. A .gitignore rule does not untrack a path already in the branch, and leaving them would land two junk files in the repo root on merge. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Brian Searls <briansearls1@gmail.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.
Same resolved declaration, different authored spelling, must produce the same Rust.
emit_field_value_with_contextdecided the shared reference layer of a record-literal FIELD VALUE withset_contains(shared_types, rc_name)whererc_nameis the name AS AUTHORED, whileshared_typesis keyed on the bare declared name — the mismatchalias_rhs_qualified_name_routing_notealready records for every other lookup on that path.A qualified spelling matched nothing, so the value was emitted UNWRAPPED into a field whose declared type is
Rc<T>. That is a type error (E0308), not a style difference.Measured, minimal, both arms against one provider
Discriminating RED, by execution
The witness returns
falseagainst an emitter with this one decision reverted, andtruewith it. Both runs were performed — the red is not deduced from the earlier output.Why main is green without this
The measured seed closure contains almost no qualified type reference, so an ordinary green regen exercises the bare arm only. That is why the witness AUTHORS the qualified arm rather than relying on the corpus to contain one.
4066 qualified dotted type references already exist corpus-wide (555 files, 2314 in
src/v2) and enter the seed closure as v2 self-hosting advances, so the population reaching this path grows with the roadmap rather than staying latent.Zero-drift, structurally
qualified_last_segmentis the identity on an unqualified name, so every bare spelling emits exactly as before. Receipt:required-regenover the 132-module subject reportsfirst_generation_equal=truewith only this repair mirror changed.Declared residue — not fixed, not claimed
A qualified reference to a zero-parameter ALIAS is still peeled to its target, and where that target lives in a THIRD module the peeled name reaches output with no use-line (E0412).
Located cause: a qualified reference parses as a module-projection spine, so it fails the
NoConnective-and-childless guard on the alias-preserving branch ofrender_rust_fn_sig_typeand never reaches the alias lookup at all. Three candidate repairs were written and all three reverted rather than landed unproven, since none is pinned by an executing control.The fixture cannot carry that RED either:
compile_dag_rust_emit_checkcompiles against an import-driven source set, so a third fixture module turned the BARE control red — the harness refusing the closure, not the emitter failing.Provenance
Found while driving
integration/namespace-cut(#8282), where this producer accounts for 115 of the branch diagnostics. Per the agreed sequencing this lands on main first, where it is independently testable; the cut branch then takes this exact patch rather than re-inventing it.🤖 Generated with Claude Code