Skip to content

Three failure-mode rows for the 2026-09-03 19:49 main outage - #10392

Merged
briansrls merged 13 commits into
mainfrom
session/merry-hawk-143
Sep 4, 2026
Merged

briansrls merged 13 commits into
mainfrom
session/merry-hawk-143

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor

main was red from 19:49Z for roughly eighty minutes: gunbc.recurring_failure_mode
declared absence_classifier_default_bucket and
green_reported_over_a_population_the_instrument_does_not_own twice each, which
refused generated-artifact resolution and reddened the BUILD lane (not the floor).
#10278 (1af8892) repaired it with a four-line deletion. This files the classes;
it repairs nothing and builds no check.

ROW 1, RANKED FIRST -- head_landed_by_hand_before_its_own_verification_reported.
#10236 (cfe19ea) merged at 19:49:43Z, three seconds after the only run on its
merged head was created at 19:49:40Z; that run concluded FAILURE at 20:30:34Z, and
gh api reports merged_by: briansrls -- a HUMAN merge. The row says so explicitly
rather than naming an automated gate, because a broken automation and a missing
constraint on a person acting inside their own authority are different findings with
different repairs. It states that it SUBSUMES the detection-timing classes: if a head
can land before its checks conclude, no detection improvement changes the outcome.
Branch protection is named as UNMEASURED -- session tokens get 403 on it -- so the
row claims nothing about the ruleset. Distinguished from
required_evidence_absent_reads_as_evidence_of_pass, which is a defect in an admission
arm's quantifier; this row is the absence of any arm between the actor and the landing.

ROW 2 -- append_only_carrier_re_adds_what_its_own_base_already_carries. The two names
were first added by #10166 (2bba578) at 07:29Z; #10236 added both a second time,
its whole diff on the file being +4 lines. git merge-base --is-ancestor 2bba578d56e cfe19ea7f48 holds, so the branch re-added declarations its own base already carried,
and text merge reported nothing because both sides are insertions at different offsets.
The row quotes the carrier's own header premise -- "two lanes editing the SAME class
still conflict -- which is correct, because that is real disagreement about one fact"
-- and names why it holds for EDITS and fails for APPENDS, which is the only operation
an append-only roster performs. It also records why the projection-fidelity gate stayed
green: the projection maps over the roster, which names each identity once, so a
duplicated declaration renders nowhere. Distinguished from
premise_that_a_shared_subject_means_disagreement, which quotes the same sentence about
a different loss (author time, not a refusal).

ROW 3 -- verdict_stale_at_the_merge_instant, scoped as ANCILLARY and explicitly not
this outage's cause. #9981 (8b2323f) merged at 20:29Z with a verdict 52 minutes
stale, onto a tree already broken for forty minutes; it added a new identity colliding
with nothing. Filed anyway because the class is real and this specimen is clean.

All three carry rung found at, ceiling with its reason, and a next trigger named as a
capability. Rows 1 and 3 both name
gunbc.guarantee_stall merge_admission_terminal_verdict_stall and row 3 says the one
construction discharges both.

MODEL-SIDE ONLY: three row declarations, three roster lines, and the regenerated
projection. No v1 seed change.

RECEIPT: gunbc run --source-root dag --source-root src/v2 --entry dag/gunbc/instruments/generated_artifact_gate.dag --function main_wet exits 0 against
a gunbc built from this tree, and its only diff is the three appended rows in
docs/design-failure-modes.md.

Co-Authored-By: Claude Opus 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01NF46KAHEcLoqEyMqzPWNZ9

🤖 Generated with Claude Code

https://claude.ai/code/session_01NF46KAHEcLoqEyMqzPWNZ9


LIVE SPECIMEN, MEASURED ON THIS PULL REQUEST ITSELF, of main's
append_only_carrier_whose_serialization_shares_a_merge_region — recorded here rather
than filed as a row, because that row already owns the class and a second would be the
fork this PR renamed a row to avoid.

Merging origin/main at 78932411548 conflicted on exactly one path,
dag/gunbc/recurring_failure_mode/roster.dag, in both of its blocks: main had appended
discriminating_arm_built_but_never_enrolled and this branch had appended its three.
The appends are disjoint — different rows, different subjects, no shared fact — and they
collided anyway because the serialization puts every append in one merge region. The
resolution was a mechanical ordered union, main's row first by landing order so the
projection prefix does not move. That is the third such merge on this PR, and none of the
three carried any disagreement to resolve.

So the class blocking this change is the one the change documents the dual of: a conflict
carrying no information, holding up the PR that files the collision-producing-no-conflict
case beside it.

gunbc-ci-auto-heal and others added 3 commits September 4, 2026 09:58
main was red from 19:49Z for roughly eighty minutes: gunbc.recurring_failure_mode
declared absence_classifier_default_bucket and
green_reported_over_a_population_the_instrument_does_not_own twice each, which
refused generated-artifact resolution and reddened the BUILD lane (not the floor).
#10278 (1af8892) repaired it with a four-line deletion. This files the classes;
it repairs nothing and builds no check.

ROW 1, RANKED FIRST -- head_landed_by_hand_before_its_own_verification_reported.
#10236 (cfe19ea) merged at 19:49:43Z, three seconds after the only run on its
merged head was created at 19:49:40Z; that run concluded FAILURE at 20:30:34Z, and
`gh api` reports merged_by: briansrls -- a HUMAN merge. The row says so explicitly
rather than naming an automated gate, because a broken automation and a missing
constraint on a person acting inside their own authority are different findings with
different repairs. It states that it SUBSUMES the detection-timing classes: if a head
can land before its checks conclude, no detection improvement changes the outcome.
Branch protection is named as UNMEASURED -- session tokens get 403 on it -- so the
row claims nothing about the ruleset. Distinguished from
required_evidence_absent_reads_as_evidence_of_pass, which is a defect in an admission
arm's quantifier; this row is the absence of any arm between the actor and the landing.

ROW 2 -- append_only_carrier_re_adds_what_its_own_base_already_carries. The two names
were first added by #10166 (2bba578) at 07:29Z; #10236 added both a second time,
its whole diff on the file being +4 lines. `git merge-base --is-ancestor 2bba578
cfe19ea` holds, so the branch re-added declarations its own base already carried,
and text merge reported nothing because both sides are insertions at different offsets.
The row quotes the carrier's own header premise -- "two lanes editing the SAME class
still conflict -- which is correct, because that is real disagreement about one fact"
-- and names why it holds for EDITS and fails for APPENDS, which is the only operation
an append-only roster performs. It also records why the projection-fidelity gate stayed
green: the projection maps over the roster, which names each identity once, so a
duplicated declaration renders nowhere. Distinguished from
premise_that_a_shared_subject_means_disagreement, which quotes the same sentence about
a different loss (author time, not a refusal).

ROW 3 -- verdict_stale_at_the_merge_instant, scoped as ANCILLARY and explicitly not
this outage's cause. #9981 (8b2323f) merged at 20:29Z with a verdict 52 minutes
stale, onto a tree already broken for forty minutes; it added a new identity colliding
with nothing. Filed anyway because the class is real and this specimen is clean.

All three carry rung found at, ceiling with its reason, and a next trigger named as a
capability. Rows 1 and 3 both name
`gunbc.guarantee_stall` `merge_admission_terminal_verdict_stall` and row 3 says the one
construction discharges both.

MODEL-SIDE ONLY: three row declarations, three roster lines, and the regenerated
projection. No v1 seed change.

RECEIPT: `gunbc run --source-root dag --source-root src/v2 --entry
dag/gunbc/instruments/generated_artifact_gate.dag --function main_wet` exits 0 against
a gunbc built from this tree, and its only diff is the three appended rows in
docs/design-failure-modes.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NF46KAHEcLoqEyMqzPWNZ9
…he class takes the minimum

Review question: is the ceiling a property of OUR admission path, which we could model
and refuse on, or of GitHub's merge behavior, which we can only observe? The row said
`structurally guaranteed` on the merge-queue construction without deciding that, which
is the 4b(1) inflation of citing the strongest path while the one the incident happened
on stays silent.

It is two paths, and the row now says so.

PATH ONE, ours and on the ladder: a landing through an admission decision this
repository models -- gunbc.merge_lifecycle merge_enabled consulting
gunbc.merge_admission policy_admits, where the absent-receipt case is now an arm of the
decision rather than a fold seed. Authorable invalid state, authorable refusal,
enrollable RED. Ceiling 3 there.

PATH TWO, not ours and off the ladder: a person pressing merge in the hosting platform.
gunbc.repo_ruleset desired_ruleset_rules reads ruleset 16178731 back with no divergence
while the merge still lands, because the platform decides required contexts on what has
REPORTED at the merge instant. The honest form is a boundary obligation -- converge the
desired ruleset, observe every landing against the verdicts that existed at its merge
instant, refuse when there were none -- and today even that observation is partial,
because branch protection is unreadable from a session token.

So the row's ceiling is the boundary obligation, the minimum across its in-scope paths,
and the merge queue is recorded as the construction that DELETES path two rather than as
a proof we hold. The trigger splits to match: (a) the queue, held open by the operator's
2026-09-03 ruling, and (b) a landing observation meanwhile. The row also records that
the sibling row states structurally guaranteed on the same construction, does not amend
it, and names which direction a reader should reconcile them in.

Regenerated: generated_artifact_gate main_wet exits 0, one paragraph changed in
docs/design-failure-modes.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NF46KAHEcLoqEyMqzPWNZ9
…at documents why that is load-bearing

review 59994 flagged the receipts list in
head_landed_by_hand_before_its_own_verification_reported as six adjacent string
literals with no commas, and asked whether the grammar concatenates.

BOTH HALVES OF THAT QUESTION ARE ANSWERED BY MEASUREMENT AND THE FINDING IS REAL EITHER
WAY. The grammar DOES concatenate: `gunbc run --entry
dag/gunbc/instruments/generated_artifact_gate.dag --function main_wet` exited 0 both
before and after this commit, and the regenerated docs/design-failure-modes.md is
byte-identical across it -- this diff changes no projected byte. So it was not a parse
failure. It was worse in the way this carrier specifically cares about: without the
commas the six receipts are ONE list element, which is the exact geometry
gunbc.recurring_failure_mode's own header calls load-bearing rather than style -- a
missing trailing comma drags the preceding receipt into the conflict region and destroys
the minimal three-way merge shape that two repairs of this carrier were spent buying.

Five commas added. Nothing else changed.

Recorded because it is the joke this PR did not need: a receipts list fused into one
blob, on a row about a module that failed to resolve on main, in a carrier whose header
warns that nothing enforces this shape and it is held by that paragraph alone. Nothing
enforced it here either -- the header's own next-rung trigger, a producer carrying each
declaration's source extent, is what would have refused it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NF46KAHEcLoqEyMqzPWNZ9
@gunbai-bot

gunbai-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

review 59994: fixed in e377b88 — the finding was real, and the answer to "or confirm the grammar concatenates" is BOTH.

The grammar does concatenate: gunbc run --source-root dag --source-root src/v2 --entry dag/gunbc/instruments/generated_artifact_gate.dag --function main_wet exits 0 before and after the fix, and the regenerated docs/design-failure-modes.md is byte-identical across the commit — that diff changes no projected byte. So it was not a parse failure, and the module resolves.

It was still a defect, in the way this carrier specifically cares about. Without the commas those six receipts are ONE list element. gunbc.recurring_failure_mode's own header calls the per-element trailing comma load-bearing rather than style: a missing one drags the preceding receipt into the conflict region and destroys the minimal three-way merge geometry that two separate repairs of this carrier were spent buying. Five commas added, nothing else touched.

Worth noting what this says about the wall: that header also states nothing enforces the shape and it is held by the paragraph alone, and names the capability that would — a producer carrying each declaration's source extent, sufficient to refuse a row of this type whose elements are not severable. This landed exactly as that paragraph predicts: caught by a reader, not by a check.

— sent from merry-hawk-143

gunbc-ci-auto-heal and others added 2 commits September 4, 2026 11:49
…main landed a row whose name opens with mine

CONFLICTS AND HOW EACH WAS RESOLVED.

dag/gunbc/recurring_failure_mode/roster.dag -- ordered union in both blocks, main's
append_only_carrier_whose_serialization_shares_a_merge_region first, then this branch's
three. Order is source order and load-bearing in the projection, so the union had to
agree as a SEQUENCE and not merely as a set; main's row lands ahead of ours because it
landed ahead of ours in history, which keeps main's projection prefix unmoved.

docs/design-failure-modes.md -- NOT resolved by hand, per the generated-artifact
driver's own printed route: both sides changed the projection since the merge base, so
neither side's bytes are the projection of the merged authorities. The driver left the
ours side verbatim with no markers; those provisional bytes are staged as provisional,
and heal-generated-artifacts derives the real projection from the merged authorities
and pushes the healed head. I did not regenerate it locally, which the route explicitly
forbids. The staged bytes are therefore KNOWN STALE: they carry the pre-rename name and
not main's new row.

RENAME, DECIDED ON THIS MERGE RATHER THAN LEFT.
append_only_carrier_re_adds_what_its_own_base_already_carries is now
duplicate_declaration_arrives_through_a_clean_merge. Main's new row is
append_only_carrier_whose_serialization_shares_a_merge_region, and two rows whose names
open with the same four words invite exactly the fusion DESIGN section 3 warns about --
particularly here, where they are duals and a reader who fuses them loses the
distinction that matters.

THEY ARE DUALS AND THE ROW NOW SAYS SO. Main's class is a CONFLICT THAT CARRIES NO
INFORMATION: disjoint appends share a merge region, and the merge refuses a union whose
answer is mechanical. This class is a COLLISION THAT PRODUCES NO CONFLICT: identical
appends sit at different offsets, and the merge accepts a result that cannot resolve.
One refuses where it should union; the other unions where it should refuse. A
serialization in which independent appends do not share a merge region retires main's
row and leaves this one untouched, because the defect here is not WHERE the comparison
happens but WHAT it compares -- offsets rather than identities. That paragraph is in the
row, not only in this message.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NF46KAHEcLoqEyMqzPWNZ9
…that no longer exists

verdict_stale_at_the_merge_instant names the outage's actual cause row, and the rename
in the merge commit left that citation naming
append_only_carrier_re_adds_what_its_own_base_already_carries -- a symbol nothing
declares any more. Now cites duplicate_declaration_arrives_through_a_clean_merge.

The one surviving mention of the old name is deliberate: the renamed row records that it
was originally filed under it, which is what lets a reader following an older reference
land somewhere rather than nowhere.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NF46KAHEcLoqEyMqzPWNZ9
@gunbai-bot

gunbai-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

review 60061: APPROVE, nothing to fix — one factual amendment for whoever lands this, because the review describes docs/design-failure-modes.md on this head as the regenerated projection and on this head it is not.

After the merge with main, both sides had changed that projection since the merge base, so neither side's bytes are the projection of the merged authorities. The generated-artifact merge driver printed its declared route and I followed it: the driver-left ours bytes are staged as provisional and were deliberately NOT regenerated locally, which step 2 of that route explicitly forbids. heal-generated-artifacts derives the real projection from the merged authorities and pushes the healed head.

So the committed projection on a27ed439 is knowingly stale in two ways: it carries the pre-rename identity append_only_carrier_re_adds_what_its_own_base_already_carries (renamed to duplicate_declaration_arrives_through_a_clean_merge when main landed a row whose name opened with the same four words), and it lacks main's own new row. The .dag authorities are correct and complete; the markdown catches up when heal runs.

That is not a hole to worry about. The generated-artifact phase compares every committed projection against its authority and refuses on Drifted or Absent, it routes to the Build lane, and the aggregate needs [build, floor] with if: always(), refusing anything that is not success — including skipped and cancelled. If heal never runs, this reds rather than lands.

Verification of the merged authorities was done without breaking that route: the gate was run over the merge commit in a throwaway worktree (exit 0, only the projection differs) and discarded. This branch was not regenerated.

— sent from merry-hawk-143

gunbc-ci-auto-heal and others added 3 commits September 4, 2026 12:17
…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
@gunbai-bot

gunbai-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

CI status on 2dd5108, investigated: the two failing checks are not caused by this diff, and there is no fix for me to push.

  • required-witnesses-build: success.
  • heal-generated-artifacts: skipped, correctly — nothing left to heal.
  • required-witnesses-floor: failure, with the floor itself clean (verdict=FloorClean … claims_failed=0 unexpected_failures=0 on the prior run). It exits at adjudication REFUSED standing=measurement_completed blockers=2, and the two blockers are FAILED PHASE parse (16 error(s)) and FAILED PHASE namespace-wave-admission (no head index) — the second downstream of the first.
  • witnesses aggregate: failure, because a lane was not success.

All 16 parse refusals are in dag/test/claim/emit_copy_qualification_witness_test.dag lines 483–500, each source annotation names no subject: no module item follows it. That file ends with a trailing standalone // block attached to no declaration — what §4c says the .dag realization refuses. It was left there by #10390 when three rows were deleted, its bytes at origin/main (97345e5) are identical to the copy on this branch, and nothing in this PR touches it. Every branch that merges main reds the same way.

The repair is already owned twice over — #10414 (re-attach) and #10420 (delete) are both open — so a third attempt from here would be waste, and editing another lane's cut is not mine to do. Worth knowing for whoever lands this: #10414's run shows parse clean but still fails on namespace-wave-admission (NotEvaluated), so the annotation repair alone may not green the floor; re-read the phase list rather than assuming.

This PR is content-complete and parked: six approvals, the one REQUEST_CHANGES long superseded and fixed, projection union verified at this head (all three new rows plus main's own, in index and body). It is blocked on a main defect it did not cause.

— sent from merry-hawk-143

gunbc-ci-auto-heal and others added 2 commits September 4, 2026 15:28
review 60183 found the contradiction and it is real: the row said the actor acted
"with no constraint that could have stopped them" while, four receipts later, saying
it does not claim protection was absent, misconfigured or bypassed. merged_by plus two
timestamps establish an UNCERTIFIED LANDING; they do not establish which admission path
permitted it. Asserting the path from that evidence is the fabrication DESIGN section 4b
keeps off the ladder as external reality.

NARROWED TO WHAT WAS OBSERVED. The invalid state is now the landing itself -- at the
instant of the landing there is no concluded run for the landed ref -- and the row says
explicitly that which path permitted it (absent constraint, a constraint that treats an
unreported required context as not-failing, or a bypass) is a separate question the
actor and timestamps do not settle.

THE ACTOR STAYS, AS AN OBSERVATION ABOUT WHO RATHER THAN ABOUT WHAT STOOD IN THE WAY. It
is worth recording because it fixes who the repair must reach: a repair aimed at an
automated arm changes nothing for a landing no automated arm performed.

AND THE UNMEASURED RECEIPT NOW SEPARATES TWO THINGS IT HAD FUSED. This filing could not
read protection (403). The REPOSITORY does record the answer, and citing it is better
than leaving a hole: gunbc.merge_lifecycle holds that gunbc.repo_ruleset
desired_ruleset_rules read ruleset 16178731 back with NO divergence, and that the merge
was admitted anyway because the platform decides required contexts on what has REPORTED
at the merge instant. On that authority a constraint EXISTED AND ADMITTED -- which is a
stronger and more useful statement than the one the review struck, and it is why the row
is about an uncertified landing rather than a missing gate.

The sibling-row distinction is restated on the same basis: that row's subject is an
admission arm's quantifier, this row's is the landed state, which is reachable by paths
that arm never touches.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NF46KAHEcLoqEyMqzPWNZ9
@gunbai-bot

gunbai-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

review 60183: the finding was correct and is fixed in 031be0e32412dd0bebed73427bcf3a2b5f5958e8.

The row did contradict itself. It said the actor acted "with no constraint that could have stopped them" and, four receipts later, that it does not claim protection was absent, misconfigured, or bypassed. merged_by plus two timestamps establish an uncertified landing; they do not establish which admission path permitted it. Asserting the path from that evidence is the fabrication §4b keeps off the ladder as external reality — the review's citation is the right one.

Narrowed to what was observed. The invalid state is now the landing itself: at the instant of the landing there is no concluded run for the landed ref. The row states explicitly that which path permitted it — an absent constraint, a constraint that treats an unreported required context as not-failing, or a bypass — is a separate question the actor and timestamps do not settle.

The actor stays, as an observation about who, not about what stood in the way. It fixes who the repair must reach: a repair aimed at an automated arm changes nothing for a landing no automated arm performed.

And the unmeasured receipt now separates two things it had fused, which makes the row stronger rather than weaker. This filing could not read protection (session token, 403). The repository does record the answer, so it is cited rather than left as a hole: gunbc.merge_lifecycle holds that gunbc.repo_ruleset desired_ruleset_rules read ruleset 16178731 back with no divergence — active, default-branch-scoped, one required context — and that the merge was admitted anyway, because the platform decides required contexts on what has reported at the merge instant and an unreported context is expected rather than failing. On that authority a constraint existed and admitted, which is exactly why the row is about an uncertified landing and not a missing gate.

The sibling-row distinction is restated on the same basis: required_evidence_absent_reads_as_evidence_of_pass is about an admission arm's quantifier; this row is about the landed state, reachable by paths that arm never touches.

Re-verified: the generated-artifact gate exits 0 over the new commit in a throwaway worktree, and the derived projection carries the corrected text and no longer contains the struck claim.

— sent from merry-hawk-143

gunbc-ci-auto-heal and others added 3 commits September 4, 2026 16:00
…add the 6-of-40 population

The row cited gunbc.merge_lifecycle for the ruleset reading and stopped three lines short
of the number that decides what the class IS. That module records: across the forty most
recently merged pull requests at its measurement, six had no `witnesses` run that
completed successfully on their own head before `merged_at`.

WHY IT CHANGES THE ROW RATHER THAN DECORATING IT. With one specimen a reader files this
as an incident -- a bad night, a hurried merge. With 6/40 the class is a standing
property of the landing path, roughly one merge in seven landing uncertified, and the
question the next trigger waits on -- whether the construction that deletes this state is
worth its cost -- becomes a decision about a rate. It is also the shape DESIGN section 5
asks a denominator to have: a closed, independently discovered population, not a count
read off the current tree.

CITED, NOT RE-DERIVED. Naming the module that measured it is the citation; re-counting
would mint a second authority for one fact, and the row says so, so a later reader wanting
a current figure re-runs that module's instrument instead of trusting this sentence.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NF46KAHEcLoqEyMqzPWNZ9
…taken for the projection

CONFLICT: dag/gunbc/recurring_failure_mode/roster.dag, both blocks. Resolved as an
ordered union with main's discriminating_arm_built_but_never_enrolled first and this
branch's three after, matching history order so main's projection prefix does not move.

THE PROJECTION DID NOT CONFLICT THIS TIME, AND THAT IS THE PART WORTH RECORDING. Git
text-merged docs/design-failure-modes.md cleanly, which for a GENERATED file is not a
resolution at all: a textual union of two projections is derived from neither authority,
and it is exactly the plausible-looking artifact the driver refuses to produce when it is
reached. A clean auto-merge is therefore not evidence the bytes are derived -- it only
means no hunk overlapped. So the base side was taken verbatim, per the same route step 1
the driver prints on refusal, leaving bytes that are a real derivation of a real tree
until heal derives the union.

VERIFIED BY SET DIFFERENCE AGAINST THE BASE I ACTUALLY MERGED, named rather than called
"main": no row present in 7893241's projection is absent from the staged one, and no
identity in its roster is absent from the merged roster. Both empty.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NF46KAHEcLoqEyMqzPWNZ9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant