Repository navigation
The heal route's step 1 deleted rows: stop telling authors to stage the ours side - #10383
Merged
gunbai-bot[bot] merged 2 commits intoSep 4, 2026
Merged
Conversation
…he ours side
The driver leaves the OURS side in the worktree with no conflict markers and marks the path
unmerged. Step 1 said "stage the driver-left bytes", so following it commits this branch's
rows over the base's and drops every row the base added since the merge base, adding none of
this branch's own.
The common diagnostic in this same file already stated the hazard -- "Taking either side
drops the other side's authority-derived content" -- and the route then instructed taking
one. The artifact contradicted itself.
MEASURED 2026-09-04 on docs/design-failure-modes.md, five heads that hit this driver:
four followed step 1 as written and each committed a 97-row projection against a base of 98
and an authority of 99, every one silently dropping the same two rows
(denominator_moved_between_measurement_and_comparison, absent_reads_identically_to_never_looked).
The single clean head was the one that did not follow the route -- it read the index stages
instead of the worktree and reconstructed. Two of the four were mine.
THE ROUTE INSTRUCTED THE ACTION THAT DISARMS THE GUARD: committing the provisional bytes
moves the merge base, after which this driver has nothing left to refuse, merge-tree is
clean, GitHub admits, and every instrument reports green over a head that deletes rows.
That is guard_precondition_discharged_by_the_route_that_uses_it with the route itself as the
discharging agent, which is a sharper receipt than the one the row carries today.
The replacement takes the BASE side verbatim. That is explicitly not claimed as a
resolution: it leaves the tree authority-ahead by this branch's own rows, which is the state
heal exists to repair and which the generated-artifact gate can still see. What it removes
is the DELETION, which nothing downstream can see at all.
Two steps are added because the wording alone leaves the trap intact for anyone who reads
the file rather than the route:
- verify by SET DIFFERENCE, never by count. A count says a number moved; only the
difference names WHICH rows went dark, and the name is the whole finding.
- do not check for conflict markers and conclude anything. Zero markers is precisely what
this driver GUARANTEES on a refusal, so a marker count reports that the DRIVER worked,
never that its SUBJECT is intact -- reading a mechanism's success signal as evidence
about its subject is how three of the four deletions happened.
The emitted .githooks/generated-artifact-merge is left for heal to derive.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WgiDD3VoavwLrcu832nJ2V
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Sep 4, 2026
The merge at 4a9e6e6 followed the generated-artifact merge driver's OLD printed remedy -- stage the driver-left ours bytes as a "provisional" projection -- and that route does exactly what the driver's own diagnostic says it does: it drops the other side's authority-derived content. Measured by set difference against origin/main, this branch's projection was missing absent_reads_identically_to_never_looked denominator_moved_between_measurement_and_comparison both of which are on main. 97 rows against main's 98. This is the fifth head tonight to lose the same two rows to the same route; #10383 replaces that remedy with "take the BASE side verbatim, verify by set difference, let heal derive the projection", and this commit is that route applied. docs/design-failure-modes.md is now origin/main's bytes VERBATIM: both difference directions against main are empty and the file is byte-identical. It is deliberately NOT regenerated. The roster carries 99 entries and this projection carries 98, so it is authority-BEHIND by exactly one row -- this PR's own emitted_entry_point_succeeds_doing_nothing -- and the required generated-artifact phase will keep refusing until heal derives it. That refusal is correct and is the mechanism working: it already caught this defect once, reporting rostered=38 adjudicated=38 matches=37 drifted=1. Authority-behind-and-loudly-refused is the benign shape; silently dropping two of main's rows was not. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WgiDD3VoavwLrcu832nJ2V
gunbai-bot
Bot
deleted the
session/bright-ram-778-heal-route-deletes-rows
branch
September 4, 2026 12:12
briansrls
pushed a commit
that referenced
this pull request
Sep 4, 2026
Merged cleanly with no driver refusal, so the corrected route in #10383 did not fire here. Its verification step was run anyway, because the check is cheap and the failure it catches is invisible: set difference of the projection's row identities, main MINUS the merge result, is EMPTY -- no row went dark. Counts are not used as the check; a count says a number moved, only the difference names WHICH rows died. The projection is behind its authority by this branch's two rows, which is the authority-ahead-of-artifact state regeneration repairs and the generated-artifact gate can see. The state that nothing downstream can see -- a deletion -- is absent, and that is what was verified. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018vz8ESEVFC7Cox1xAaXudg
briansrls
pushed a commit
that referenced
this pull request
Sep 4, 2026
…rom the merged authorities One conflicting path, .github/workflows/witnesses.yml, and it is a generated projection -- so this is the regeneration case, not a reconciliation of two intents about what the CI jobs are. dag/gunbc/witness/witness_floor_workflow.dag auto-merged and dag/gunbc/instruments/generated_artifact_gate.dag is untouched by main since the merge base, so it cannot conflict at all. THE DRIVER-PRINTED ROUTE IS NOT FOLLOWED HERE, and that is deliberate rather than incidental: the driver that runs during a merge is the one the BRANCH had before it, so an older checkout prints the pre-#10383 route whose step 1 stages the driver-left OURS side. Staging those bytes deletes every row the base added since the merge base -- measured across five heads, four of which committed a 97-row projection against a base of 98. This resolution regenerates the path from the merged authorities instead, which is immune to that failure by construction because it derives the bytes rather than choosing a side. BOTH INTENTS VERIFIED PRESENT ON THE MERGED AUTHORITY, since a clean auto-merge establishes only that git found no textual disagreement and says nothing about whether either side's meaning survived: declaration step present and ordered Declare -> Regenerate -> Converge -> Commit fabric_evidence_job_id 0 occurrences (the operator-ruled job cut honoured) rust_unit_tests_job_id 0 occurrences (likewise) HealRepairDeclarationMissing refusal arm intact and on the emitted workflow: four jobs, the declaration step sitting between Build and Regenerate. NO ROW WENT DARK, verified by SET DIFFERENCE rather than by count and never by counting conflict markers, since zero markers is exactly what the driver guarantees on a refusal: failure-mode ledger main 99, merged 99, lost [] rung-drop ledger main 34, merged 34, lost [] The zeros are readable because the same instrument was fired against a tree that really did differ (main vs main~30), where it reported three named failure-mode identities and five rung-drop headings lost. A zero with no accompanying nonzero establishes nothing. 15 witnesses green on the merged tree. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YRSSLXXVjavzktziwdpEpH
briansrls
pushed a commit
that referenced
this pull request
Sep 4, 2026
…thority-ahead-of-artifact gap The remote tip 7f46e2c is a CI auto-heal commit that landed while this work was held locally, and it carries exactly the artifact --required-regen does not emit: docs/design-failure-modes.md regenerated to 101 rows, INCLUDING both of this branch's two. So the gap the previous commit declared -- roster 101, projection 99, repaired by heal under the design-ledger carve-out -- is closed here rather than after the next CI cycle. The carve-out worked as declared; this merge just collects the result. Verified after the merge rather than assumed: projection 101 rows and roster 101 entries, both new rows present in the projection exactly once, and the #10383 set-difference check -- rows on main MINUS rows here -- EMPTY, so nothing went dark. Source work confirmed present by count on all three carriers: the emit-side exclusion, the enrolled test in the emitted bytes, and the admission label. Merged rather than force-pushed over: heal's commit is real work on a shared branch, and a force push would have discarded a regeneration this branch needed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018vz8ESEVFC7Cox1xAaXudg
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Sep 4, 2026
…he route main changed under me Seven commits behind, and the projection conflicted again. This merge follows the route as it now reads, which is NOT the route I followed last time: main's #10383 rewrote step 1 from "stage the driver-left bytes" to "take the BASE side's projection verbatim -- git checkout <base-ref> -- docs/design-failure-modes.md -- and do NOT stage the bytes sitting in your worktree: those are the OURS side, and staging them commits your rows over the base's, deleting every row the base added since the merge base". So the base side is checked out and staged, and the projection is again knowingly stale in the other direction: it now carries main's rows and not mine. heal derives the union from the merged authorities, as it did on e935809. The hook that printed the OLD route during this merge is my worktree's copy, which this same merge updates. Recorded because it is the shape this repository keeps finding: the instrument that told me what to do was itself the stale artifact. No authority bytes were touched. The only conflicted path was the projection. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NF46KAHEcLoqEyMqzPWNZ9
briansrls
pushed a commit
that referenced
this pull request
Sep 4, 2026
…ion the admissions array TWO CONFLICTS, TWO DIFFERENT RESOLUTIONS, AND THE GENERATED ONE FOLLOWS #10383's CORRECTED ROUTE. docs/design-failure-modes.md conflicted with ZERO markers, which is the generated-artifact driver REFUSING rather than answering: it leaves the OURS bytes in the worktree and marks the path unmerged. Staging what is sitting there is the move #10383 measured as destructive -- four of five heads that did it silently dropped rows. So the BASE side is taken verbatim via `git checkout origin/main --`, and the result is verified BY SET DIFFERENCE rather than by count: rows on the base MINUS rows here is EMPTY, so no row went dark. A marker count would have established nothing here, because zero markers is exactly what this driver GUARANTEES on a refusal. That leaves the tree authority-ahead-of-artifact by this branch's two rows -- roster 101, projection 99 -- which is heal's to close under the design-ledger carve-out and which the generated-artifact gate can see. It is the deliberate cost of the safe resolution: the deletion is what nothing downstream can detect, and the deletion is what was avoided. Heal has already closed this same gap once on this branch, at 7f46e2c. namespace_wave_admission.rs is HAND-AUTHORED and conflicted substantively: main deleted the nineteen gunbc#10344 asset-identity rows as CONSUMED and recorded a TWENTY-FOURTH DISSOLUTION entry for them, while this branch still carried them. Main's array is current truth; taking this branch's side would have resurrected nineteen rows main deliberately retired. Resolved by taking MAIN's array and re-applying only this branch's delta -- the KERNEL_IDENTITY_RELOCATION_LABEL const and its two TransitionAdmission rows. Verified by assertion rather than by eye, and the assertions caught two off-by-one slices before anything was written: exactly two rows carrying this branch's label, zero gunbc#10344 rows surviving, main's dissolution entry preserved, the extracted block ending on a closing brace, and zero conflict markers. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018vz8ESEVFC7Cox1xAaXudg
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Sep 4, 2026
Main now carries the annotation repair (#10425, b4dfec3), so this branch stops inheriting the fleet-wide parse breakage. THE GENERATED-ARTIFACT ROUTE IS NOT THE ONE I FOLLOWED ON THE PREVIOUS TWO MERGES. #10383 replaced it: step 1 used to say stage the driver-left ours bytes as provisional. It now says take the BASE side verbatim (git checkout <base-ref> -- docs/design-failure-modes.md) and explicitly NOT to stage the worktree bytes, because those are the ours side and committing them writes this branch's rows over the base's, deleting every row the base added since the merge base. So this merge takes origin/main's projection verbatim. My own row is deliberately ABSENT from it -- the base does not have it yet, and heal derives the merged projection from the merged authorities. VERIFIED BY SET DIFFERENCE, WHICH IS WHAT THE ROUTE DEMANDS AND NOT BY COUNT: every row identity in the base projection is still present after the checkout, difference empty. A count would say a number moved; only the difference names WHICH rows went dark, and the name is the finding. I did NOT check for conflict markers and conclude anything from their absence. The driver GUARANTEES marker-free bytes on a refusal, so a marker count reports that the driver worked, never that its subject is intact. Authority after merge: 105 roster entries. The projection is knowingly behind that until heal derives it. Unrelated observation, not fixed here: .githooks/generated-artifact-merge emits `line 13: ([a-z0-9_]*): command not found` twice while printing the route. The route text still renders and the refusal still fires, so it is cosmetic, but the sed capture group in that message is being evaluated by the shell. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G
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.
The generated-artifact merge driver's own printed repair route instructs the action that deletes rows.
What happens
The driver refuses rather than answering: it leaves the ours side in the worktree with no conflict markers and marks the path unmerged. Step 1 said "stage the driver-left bytes as an explicitly PROVISIONAL projection:
git add -- $merged_path".Following it commits your rows over the base's — dropping every row the base added since the merge base, and adding none of your own.
The common diagnostic in this same file already states the hazard: "Taking either side drops the other side's authority-derived content." The route then instructed taking one. The artifact contradicted itself.
Measured
2026-09-04, on
docs/design-failure-modes.md, five heads that hit this driver:main)denominator_moved_between_measurement_and_comparison,absent_reads_identically_to_never_lookedThe single clean head is the one that ignored the route — it read the index stages instead of the worktree (stage 2 carries your rows and none of the base's; stage 3 the base's and none of yours) and reconstructed. Two of the four deletions were mine.
Why it is this class
The route instructed the action that disarms the guard. Committing the provisional bytes moves the merge base, after which the driver has nothing left to refuse,
merge-treeis clean, GitHub admits, and every instrument reports green over a head that deletes rows.That is
guard_precondition_discharged_by_the_route_that_uses_itwith the route itself as the discharging agent — a sharper receipt than the one the row carries today.The replacement
Take the base side verbatim. This is explicitly not claimed as a resolution: it leaves the tree authority-ahead by the branch's own rows, which is the state heal exists to repair and which the generated-artifact gate can still see. What it removes is the deletion, which nothing downstream can see at all.
Two further steps are added, because changing the wording alone leaves the trap intact for anyone who reads the file rather than the route:
Scope
Authority-only.
.githooks/generated-artifact-mergeis left forheal-generated-artifactsto derive, per the route this PR is amending.🤖 Generated with Claude Code
https://claude.ai/code/session_01WgiDD3VoavwLrcu832nJ2V