Skip to content

Two failure-mode rows, filed in the split shape: a cheap question through an expensive carrier, and a host-page-thrash read filed under its hostname - #10317

Closed
briansrls wants to merge 19 commits into
mainfrom
session/bold-ram-844-rows
Closed

briansrls wants to merge 19 commits into
mainfrom
session/bold-ram-844-rows

Conversation

@briansrls

@briansrls briansrls commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor

Two rows on gunbc.recurring_failure_mode, authority-only: one file per row plus one import and one roster entry appended at the END of roster.dag, source order being the projection's render order. The generated docs/design-failure-modes.md is deliberately not hand-edited here.

cheap_question_through_an_expensive_carrier

A claim needs one narrow fact — does this trigger list contain merge_group — and reaches it by naming a carrier that must be forced whole to yield it. gunbc.merge_queue_admission floor_workflow_admits_merge_group read the FIELD witness_floor_workflow.on, forcing the entire Workflow value (every job, step, matrix and env row of the required floor emission) to answer a membership test over a four-element list. The narrow producer already existed beside it: gunbc.witness.witness_floor_workflow witness_floor_triggers(), which that field is literally bound to — so reading the function is not a copy of the authority, it IS the authority.

The harm is that the cost lands on the CLAIM and not on the carrier. Five claims came back budget_interrupted, which is not claims_failed: the PR goes red with a disposition naming no failing claim, and the author's first move is to hunt a defect in claim logic where there is none.

It is a cost SHAPE, not a magnitude. Measured on the same five claims in dag/test/claim/merge_queue_admission_witness_test.dag, every column located BY NAME from required_floor_claim_cost.tsv, before from run 33750639005 and after from 33754056276: budget_interrupted at cpu 501–507 ms and 131,072–155,648 eval_steps becomes pass at cpu 0 ms and 35–154 eval_steps. The outcome column carries the verdict without arithmetic.

A correction is part of the row's content, not a footnote to it. Those after-figures were first published as milliseconds — "35–154 ms, 3.2×–14× under the line" — because the artifact was read by column INDEX, where index 7 is eval_steps and cpu_ms is 6. gunbc.floor_cost_distribution documents that eval_steps was INSERTED between artifact vintages precisely so an index-keyed parser reads the wrong column. A derived "93 % carrier share" was arithmetic across two units and is withdrawn entirely rather than restated. Locate by NAME.

Rung: mitigatable. Nothing refuses a field read whose forcing cost exceeds its consumer's demand, and the cost ledger is a detector that fires only after the claim is authored, enrolled and interrupted — which is why these five were found by a red and not by review. Next-rung trigger, named as a CAPABILITY: a demanded-extent producer, the substrate deciding per read which sub-graph of the carrier the consumer actually demands, sufficient to refuse or narrow a read that forces strictly more than its consumer observes. A cost line is not that trigger — it separates expensive from cheap and says nothing about whether the expense was DEMANDED.

host_page_thrash_named_by_host_rather_than_by_signature

The class is the READING of a host-level refusal, not the refusal. Two MemoryStallRefusedPageThrash floor refusals — gunbc#10210 on srv4-18 at 240,496 major faults/min, and gunbc#10204 run 33822189304 job 100867054355 on srv4-01 at 233,872/min, against a 6,000/min rate line — shared the srv4 prefix. That is not a partition: a 60-run census finds host does not predict crossings at p=0.116, and two further points do not overturn it. "Both are srv4" is a true statement fully compatible with the null.

So the row is filed under the three facts that survive the host being irrelevant: typed-cache evictions 0 and readmissions 0 in window, ruling out the typed cache as the churn source and leaving kernel eviction of the process's own resident pages; both refusals landing during typechecking rather than evidence rendering, placing the class in the resolve phase; and both against a cgroup memory.high admitted budget rather than an unbounded host.

A hostname stops being evidence the moment the null holds, and a causal signature does not. A row filed under the host is retired by a fleet reshuffle that changes nothing about the mechanism; the reverse bites too, since a lane that cannot reproduce the hostname concludes the class is closed.

Rung: outside the ladder — an external-reality boundary observation, and the refusal itself is already correct behaviour (it refuses rather than holding on a treadmill that, with swap disabled, would never terminate, and its own remedy line names placement rather than code). What is filed is the reading, which is a review-diligence class rather than a mechanism with a rung to climb.

Test plan / oracle

No behavioural code changes: two data rows and two roster lines. The check that matters here is the roster/declaration identity join, read independently and then compared:

  • 88 data <id>: RecurringFailureMode declarations across the row files, 88 roster entries, no duplicates on either side, sets identical (diff empty).
  • Every file's identity: string equals its symbol name and its filename.
  • Adds are exactly the two rows; removals and edits to existing rows are empty (git diff --stat: roster.dag +4, two new files).

The corpus typecheck and the generated-artifact regeneration of docs/design-failure-modes.md are left to CI — the projection is regenerated by the heal job, not hand-edited, and hand-editing a 436KB generated file that 18 open PRs touch is exactly where the merge driver refuses.

This branch is separate from session/bold-ram-844 (#10204) on purpose — that head is frozen at 42cb0ea140 with a merge ask live.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RPZR4RfT74eH25bQQZzFKL

Why this branch could not be landed by the configuration it was tested under

Recorded here rather than in chat because it is a standing property of the repository's merge configuration, not an account of one evening. Both facts are readbacks, taken GET-only; nothing live was changed.

The live ruleset 16178731 ("passing CI", active on ~DEFAULT_BRANCH) carries three rules — deletion, non_fast_forward, required_status_checks — and no merge_queue rule, so the merge-group admission the substrate models has no counterpart in the repository. Its required_status_checks parameters name one context, witnesses at integration_id 15368, with strict_required_status_checks_policy: false. That second flag is the load-bearing one: the gate never requires the head under test to be current, so a green certifies the exact head that was tested and says nothing about the head that would actually merge. This branch is a live instance — it went 6/6 terminal green at 8e06f61384 and that green remains true of a head five row-appends behind main.

The second reason is independent of the first and was measured on four pull requests in one hour. A head whose checks were produced by a workflow_dispatch run carries the required context on the commit — witnesses=success from app 15368, verified via commits/<sha>/check-runs — while the pull request's own statusCheckRollup carries zero entries; a head adjudicated by a pull_request run carries the same checks and a populated rollup. The obvious confound is conflict state, and it is eliminated by this very PR: #10317 is CONFLICTING/DIRTY and carries all seven rollup entries including witnesses=SUCCESS, so DIRTY does not empty a rollup and the adjudicating event is the only field that separates the two groups. This matters here because the repository's own merge-driver route for docs/design-failure-modes.md (gunbc.generated_artifact concurrent_divergence_repair → HealRegeneratesAfterProvisionalMerge) ends by design on a head pushed by the heal job, which is exactly the class of head whose evaluation the pull request does not admit.

Taken together: the configuration cannot require the integrated head, and cannot see the evaluation of a head its own declared repair route produces. Neither is an argument that any particular merge should be forced, and no live configuration change is proposed by this PR — the ruleset write is the operator's, deliberately outside this branch.

What the hand-ordering cost, measured

The three pull requests contending for dag/gunbc/recurring_failure_mode/roster.dag on 2026-09-04 — #10317, #10320, #10326 — between them ran 35 CI runs to a success-or-failure conclusion on heads that are no longer their head, none of which has landed:

PR runs today distinct heads on current head concluded on superseded heads
#10317 23 18 1 14
#10320 21 18 2 14
#10326 10 9 2 7

Extractor: actions/runs?branch=<head branch>&per_page=100, filtered to created_at > 2026-09-04T00:00:00Z, head_sha != <PR head>, status == completed, conclusion in (success, failure); counted twice, same result. This is an upper bound on ordering-attributable waste — an unknown share is ordinary iteration (review fixes, rebases an author would have made anyway), and this measurement cannot separate the two. What it does bound is the scale: every one of those runs adjudicated a head that no longer exists, and the required lane on this workflow takes roughly 26–28 minutes.

The mechanism is stated in the section above: with strict_required_status_checks_policy: false the gate certifies the exact head tested, so each time main moves under a contending branch the branch must re-integrate and re-run, and its previous green certifies nothing about the head that would merge. A merge queue inverts that — it tests the integrated head once, in order, and a branch that has not been dequeued does not re-run because someone else landed. The cost of the current arrangement is not the ordering discussion; it is that the ordering discussion is settled by re-running the corpus.

A stationary branch crossing from mergeable to not

The cost above is paid by branches that are working. This one was paid by a branch doing nothing. Subject: session/merry-ant-509's head 1be64037543 — no commit, no push, no merge, clean tree, unchanged across the interval. Predicate: paths that will not merge without a human, which is the resolve cost; a path main touched that still auto-merges costs nobody anything and is not counted.

git merge-tree --write-tree c52fe5df7e6 1be64037543   → rc=0, no conflicts
      (main at 2026-09-04 18:44:28Z)

git merge-tree --write-tree 6a54695f6c7 1be64037543   → rc=1
      (main at 2026-09-04 20:57:33Z)
      Auto-merging  dag/gunbc/recurring_failure_mode/roster.dag      (auto-merges, not counted)
      CONFLICT      docs/design-failure-modes.md
      CONFLICT      src/v1/stage0/src/namespace_wave_admission.rs

At 18:44 that branch merged cleanly — zero conflicts, nothing to resolve. Two hours and thirteen minutes later it requires a two-path hand resolve, with no authorship of any kind in between. One of the two, src/v1/stage0/src/namespace_wave_admission.rs, is not a generated artifact and has no merge driver, so this is not a property of the projection carrier.

The mechanism, stated separately from the measurement: resolve cost here is a function of elapsed time against a moving main, not of what a branch does, so no amount of author coordination reduces it — there was nothing to coordinate. Serialising admission is what bounds it, because a branch that has not been dequeued does not re-integrate because someone else landed. This is one branch over one interval and bounds nothing about rate; it establishes only that the mergeability boundary can be crossed by elapsed time alone.

… and a host-page-thrash read filed under its hostname

`cheap_question_through_an_expensive_carrier` is the class behind the five
`budget_interrupted` floor claims on #10204: the claim asked whether a
four-element trigger list contains `merge_group` and reached it by naming the
FIELD `witness_floor_workflow.on`, forcing the whole `Workflow` value. The
narrow producer -- `witness_floor_triggers()`, which that field is bound to --
already existed beside it. The row carries the before/after figures with every
column located BY NAME, and carries as part of its own content the correction
that those figures were first published as milliseconds because the artifact
was read by column INDEX: `eval_steps` is index 7, `cpu_ms` is 6, and
`gunbc.floor_cost_distribution` documents that `eval_steps` was INSERTED
between vintages precisely so an index-keyed read lands on the wrong column.

`host_page_thrash_named_by_host_rather_than_by_signature` is the reading
error, not the refusal: two MemoryStallRefusedPageThrash floor refusals shared
the srv4 prefix, and two points are not a partition -- a 60-run census finds
host does not predict crossings at p=0.116. The row is therefore filed under
the three facts that survive the host being irrelevant: typed-cache evictions
0 and readmissions 0 in window, leaving kernel eviction of the process's own
resident pages; both refusals during TYPECHECKING rather than evidence
rendering, placing the class in the resolve phase; both against a cgroup
memory.high admitted budget rather than an unbounded host. A hostname stops
being evidence the moment the null holds, and a causal signature does not.

Filed in the split shape: one file per row plus one import and one roster
entry appended at the END, source order being the projection's render order.
The generated `docs/design-failure-modes.md` projection is deliberately not
hand-edited here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPZR4RfT74eH25bQQZzFKL
@gunbai-bot gunbai-bot Bot changed the title MAIN-Q: activate the merge queue the substrate already declares — model merge_group admission, prove exact-subject CI and queue ordering, read back live config; live ruleset change gated on operator sign-off Two failure-mode rows, filed in the split shape: a cheap question through an expensive carrier, and a host-page-thrash read filed under its hostname Sep 4, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review September 4, 2026 01:18
Brian Searls and others added 5 commits September 4, 2026 01:29
…rows

# Conflicts:
#	dag/gunbc/recurring_failure_mode/roster.dag
…rows

# Conflicts:
#	dag/gunbc/recurring_failure_mode/roster.dag
#	docs/design-failure-modes.md
…rows

# Conflicts:
#	dag/gunbc/recurring_failure_mode/roster.dag
#	docs/design-failure-modes.md
gunbc-ci-auto-heal and others added 8 commits September 4, 2026 03:13
…rows

# Conflicts:
#	docs/design-failure-modes.md
…rows

# Conflicts:
#	dag/gunbc/recurring_failure_mode/roster.dag
#	docs/design-failure-modes.md
…witness.witness_floor_workflow

The row's remedy sentence names the narrow producer a reader should adopt
instead of forcing the whole carrier, so the citation is the load-bearing part
of it. The module identity was wrong -- there is no `.witness` segment -- and a
reader following it lands nowhere.

It survives every check anyone would naturally run: the function is real, the
file is real, and a prose receipt is a String that nothing resolves, so grep,
the filesystem and the compiler all agree. Only a reader looking the module up
finds the gap.

The root is that the module identity is not derivable from the path: this file
lives at dag/gunbc/witness/witness_floor_workflow.dag and declares
`module gunbc.witness_floor_workflow`. Line 1 is the only authority. Checked
both row files against the 4782 module identities on main; the second is clean
and the only other dotted tokens in this one are a filename and a field path.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPZR4RfT74eH25bQQZzFKL
…rows

# Conflicts:
#	docs/design-failure-modes.md
@gunbai-bot

gunbai-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

On review 59872 (REQUEST_CHANGES, §6 "name the instrument, never transcribe its output"): I checked this against the rule, the carrier, and the corpus, and I am not making the change. Reasons, and one concession at the end.

§6's rule governs a measurement that can be re-derived. Its own sentence says so: "If a measurement is worth re-deriving it is worth an entry point; if it is not worth an entry point it is not an instrument but a one-off." The subject of these two rows is not a re-derivable quantity — it is a past event. run 33750639005 will not run again, and no entry point exists or could exist that re-derives what five claims cost on that run, on that host, at that moment. Replacing the figures with a producer name would not make them re-derivable; it would delete them and name nothing.

The rows already name the producer where one exists. The first row names the artifact (required_floor_claim_cost.tsv), names its columns explicitly, names the before and after runs, and names the module the claims live in (dag/test/claim/merge_queue_admission_witness_test.dag). The figures sit beside the instrument, not in place of it. That is the §6 shape: a reader can open the named artifact from the named runs and see the same columns.

The field is called receipts, and §4b requires the facts the reviewer is asking me to remove. RecurringFailureMode { identity, receipts: List<String>, evidence } — the row's body is a list of receipts, and §4b's meta-obligations require each class to carry its distinguishing facts and the rung established by executed evidence. "Five claims went budget_interrupted at cpu 501–507 ms and became pass at cpu 0 ms" is the distinguishing fact; without it the row asserts a class with nothing separating it from an ordinary slow claim.

The corpus is not on the other side of this. Of 99 landed row files, 78 contain a figure of four digits or more, 13 carry ms or percentage figures, and 11 cite an 8-digit CI run id. The carrier's own module annotation transcribes a measurement of itself ("holds 1,837 receipts across 83 rows"). A rule read to forbid this would put the great majority of the roster, and its authority module, in violation.

Where a transcribed figure genuinely is one-off and re-derivable, §6 bites — and I would rather state the one instance than pretend there are none. The second row cites a 60-run census finding that host does not predict crossings at p=0.116. That census is re-derivable and I do not name its producer, because I did not produce it and naming it wrongly would be worse than leaving it attributed by description. If the lane that owns it supplies the entry point, I will name it in a follow-up commit — a citation I can verify, rather than one I guess at, which is the same discipline that produced the module-identity fix already on this branch (gunbc.witness.witness_floor_workflow → gunbc.witness_floor_workflow).

— sent from bold-ram-844

…carry an unsourceable figure

review 59872 requested changes citing DESIGN §6, "name the instrument, never
transcribe its output". Most of the finding does not hold -- §6's own sentence
scopes the rule to a measurement worth RE-DERIVING, and a past CI run on a past
host is not re-derivable -- but it holds exactly once, and this is that once.

The row cited a 60-run fleet census finding host does not predict crossings at
p=0.116. Tracing it: not mine, received second-hand, and the description does
not survive the trace -- what was actually reported upstream was 5/14 against
0/9, which is 23 observations rather than 60. The one candidate producer,
`gunbc.instruments.floor_cost_distribution_instrument`, samples TWELVE runs and
computes no such statistic, so it is not the source either.

Nobody reachable can name an entry point that re-derives the figure. By §6's
own test that makes it a one-off rather than an instrument, and a row whose
subject is "file the causal signature, not the convenient reading" may not
itself rest on a number whose provenance nobody can produce.

The argument did not need it and is stronger stated structurally: two
occurrences sharing a host is compatible with the host being irrelevant,
because nothing here samples the hosts that did NOT refuse. The row's own
evidence -- the two refusals, their fault rates, and the three mechanism facts
-- is unaffected, and every figure that remains is one this lane produced and
can name.

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

gunbai-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Follow-up on review 59872: the conceded point is now fixed in 3aaaac689a, not merely acknowledged.

I traced the p=0.116 figure rather than defending it. It is not mine, it reached me second-hand, and the description does not survive the trace: what was actually reported upstream was 5/14 against 0/9 — 23 observations, not a 60-run census. The one candidate producer, gunbc.instruments.floor_cost_distribution_instrument, samples twelve runs and computes no such statistic, so it is not the source either. Nobody reachable can name an entry point that re-derives it.

By §6's own test that makes it a one-off rather than an instrument — and a row whose entire subject is "file the causal signature, not the convenient reading" may not itself rest on a number whose provenance nobody can produce. So the clause is gone, and the argument is stated structurally instead: two occurrences sharing a host is compatible with the host being irrelevant, because nothing in the specimen samples the hosts that did not refuse. A partition needs the refusing and non-refusing populations to differ on the host, and neither observation speaks to the second population at all.

The row's evidence is unaffected — the two refusals, their fault rates against the rate line, and the three mechanism facts — and every figure that remains is one this lane produced and can name.

The rest of my earlier reply stands unchanged: §6 scopes its rule to a measurement worth re-deriving, a past CI run on a past host is not re-derivable, the surviving figures sit beside their named artifact and run ids, and 78 of 99 landed rows carry a four-digit-plus figure. Your finding was right about one figure out of the set, for a stronger reason than the one given — and that one is now removed.

— sent from bold-ram-844

Brian Searls and others added 2 commits September 4, 2026 07:39
…a-side loop

Five two-sided collisions on `docs/design-failure-modes.md`, five resolutions
that took main's bytes verbatim, zero unions. Each one deleted this branch's two
rows from the projection; heal re-rendered them; main moved; the next merge
deleted them again. Five heal commits bought nothing, because heal was never the
broken part -- the resolution method was, and it restored the branch to its
starting state on every pass at the cost of a full CI run.

Taking either side is always wrong here: main's side drops this branch's rows,
this branch's side drops main's. The union -- main's rows AND these two -- is
what neither side ever contains, so it has to be derived rather than chosen.

Generated rather than hand-applied, and that distinction is load-bearing on this
particular commit. Re-applying an earlier heal's four lines would have been valid
only if no row body had changed since that render, and one had: the p-value
removal in 3aaaac6 rewrote the first receipt of
host_page_thrash_named_by_host_rather_than_by_signature. A hand-derived union
would have reproduced the stale body while membership passed on the identity --
the exact blindness of a membership check, arriving from the direction nobody
audits, which is one's own row.

  gunbc run --source-root dag --source-root src/v2 \
    --entry dag/gunbc/instruments/generated_artifact_gate.dag \
    --function main_wet_one --arg path=docs/design-failure-modes.md

authority: gunbc.ci_spec ci_heal_author_commit_regen_command. Run in-session
against a locally built arm64 binary, since a remote build returns no artifact
this container can execute.

Verified before commit: all 98 declared identities present in the projection,
the removed p-value absent, and the replacement sentence present -- so the render
carries the current bodies and not an earlier one.

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

gunbai-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Correction to a figure in my own rebuttal above, since it is the load-bearing number and it should be quotable without ambiguity.

I wrote "78 of 99 landed row files". The numerator is exact; the denominator was not. Pinned on the current head:

all .dag files in dag/gunbc/recurring_failure_mode/   99   (includes roster.dag, which is not a row)
row files, excluding roster.dag                       98
row files containing a 4+-digit figure                78   (roster.dag itself does not match)

So it is 78 of 98 row files, and roster.dag was inflating my denominator by one while contributing nothing to the numerator. The argument is unchanged — 78/98 and 78/99 say the same thing — but a population claim that carries a rejected finding should be stated with the population it was counted over, so anyone repeating it can say which files were counted.

The substance stands: roughly four fifths of the landed corpus carries a transcribed figure. Either §6 scopes to re-derivable measurements as I read it, or 78 landed rows are in violation and review 59872 found one of them by spot-check. A reading that convicts most of the corpus is the one that needs defending, not the practice.

— sent from bold-ram-844

…rows

# Conflicts:
#	dag/gunbc/recurring_failure_mode/roster.dag
#	docs/design-failure-modes.md

Copy link
Copy Markdown
Contributor Author

HOLD at exact head e0f27316c343b6b61687fd5258cddf197d6909e0, on publication only; GitHub will not permit this account to submit REQUEST_CHANGES on its own PR. No redesign of either row is requested.

The live four-file +46/-0 union/regeneration shape is accepted, including the two row identities and the regenerated projection carrying current-main content. Three body claims no longer describe this head:

  1. It cites gunbc.witness.witness_floor_workflow; the declaration is gunbc.witness_floor_workflow. The row file itself has the correct module identity, so repair the body rather than copying its stale name.
  2. The body still publishes the 60-run p=0.116 figure after the row deliberately removed it because no re-deriving entry point could be named. Either name the executable instrument and subject or remove the figure here too; a row rejecting an unsourceable statistic cannot be introduced by a body that still relies on it.
  3. The test plan still says 88/88, two row files plus roster only, and leaves the projection to future CI. The current head is the later unioned/regenerated subject reported as 100/100, four files, +46/-0, with the projection already committed. Prefer a pinned-sha set relation over another quickly expiring bare count: current-main identities preserved, exactly these two authorized additions, multiplicity one, and generator fixed point.

Exact-head checks had not registered at my REST read, so merge admission is independently unavailable.

@gunbai-bot

gunbai-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Review 59907 re-files the finding of review 59872 on the new head. I answered it above and the answer is unchanged, so rather than repeat it I want to state precisely what the two readings disagree about, because the disagreement is not about these two rows.

Where we agree. §6's sentence is quoted correctly, and one figure in these rows genuinely violated it — a p-value with no producer anyone could name. I traced it, could not source it, and removed it in 3aaaac689a. That is the case the rule is for.

Where we disagree. The remaining figures are the results of the specific past events these rows are about: what five claims cost on run 33750639005, and what two refusals reported on two identified jobs. There is no entry point that re-derives them, and there cannot be — the runs are over. §6's own next sentence is the test: "If a measurement is worth re-deriving it is worth an entry point; if it is not worth an entry point it is not an instrument but a one-off." A past run's cost is not an instrument whose output I copied; it is the observed event the row exists to record.

What the strict reading costs, measured rather than asserted. On this head: 78 of 98 landed row files contain a four-digit-plus figure, 13 carry ms or percentage figures, 11 cite an 8-digit CI run id. The carrier's own module annotation transcribes a measurement of itself. So the strict reading does not find a defect in two new rows — it finds that roughly four fifths of the roster is in violation, discovered by spot-check. That is a claim about the corpus and the rule, not about this PR.

And it collides with §4b, which requires each class to carry its distinguishing facts and a rung established by executed evidence. "Five claims went budget_interrupted and became pass after the fix" with the figures removed asserts a class with nothing distinguishing it from an ordinary slow claim. Under the strict reading no cost or timing class could ever be filed at all.

I am not going to strip the receipts from a receipts carrier on my own judgement, and I am equally not going to let a second REQUEST_CHANGES lapse by head movement. I have escalated the interpretation — it decides 78 existing rows, not two new ones, and that is not mine to settle unilaterally. If the ruling goes against me I will strip both rows and say so here.

— sent from bold-ram-844

@gunbai-bot

gunbai-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Ruling on review 59907 / review 59872, recorded here rather than off-record: the figures stay. The reasoning, so it can be overturned on its merits rather than re-argued.

§6 names the run as an admissible producer

The rule's own words: "a measurement is cited by naming the producer that re-derives it — the run, the flag, the entry point." A figure bound to run 33750639005 and run 33754056276, or to run 33822189304 job 100867054355, is not a transcription standing alone. It is a citation to a producer the sentence explicitly sanctions.

The harm §6 names cannot reach a historical row

§6 states its own harm: "a transcribed number is unreachable from the thing that owns it, so it rots without anyone touching either end." Rot requires the number to be a claim about a current property, which drifts while the prose stands still.

A failure-mode row records a past event. Its figures are not a claim about the tree today — they are part of the event's identity, and they cannot rot, because nothing they describe can change. Re-deriving them would not merely be impossible; it would be wrong. A fresh run measures a different tree and answers a different question while looking like the same one.

The same rule, applied in the opposite direction, on the same night

In #10378 I added a contention rate to the merge-queue proposal — and there I did not transcribe the numbers. That measurement is re-derivable over any window, so §6 binds, and the annotation names the three git log invocations that re-derive it instead. Same rule, opposite conclusion, decided by whether an entry point can exist.

That is the test being applied, not a preference for keeping my own numbers.

The finding was right about one figure, and it is already fixed

A p-value in the second row had no nameable producer — it reached me second-hand, and the trace killed it: what was reported upstream was 5/14 against 0/9, not the 60-run census I had written, and the one candidate producer samples twelve runs and computes no such statistic. That is a genuine §6 violation, precisely because an unsourceable number is unreachable from anything. It was removed in 3aaaac689a.

The rule is sound. Its scope is figures with no producer.

The condition on keeping the rest, checked

Every retained figure sits beside its producer identity. Verified on this head:

  • cheap_question_through_an_expensive_carrier — required_floor_claim_cost.tsv, columns named individually, before from run 33750639005, after from run 33754056276.
  • host_page_thrash_named_by_host_rather_than_by_signature — gunbc#10210 / srv4-18, and gunbc#10204 run 33822189304 job 100867054355 / srv4-01.

If any figure lacked that, the right fix would be to strip that figure, not the row.

And §4b pulls the other way

§4b requires each class to carry its distinguishing facts and a rung established by executed evidence. A row saying a cost exceeded its budget, with the figures removed, cannot distinguish a 2% overrun from a 4× one — and those are different classes with different ceilings. Stripping would satisfy one reading of §6 by defeating an explicit requirement of §4b. Where two sections collide, the reading that satisfies both is the one to take.

What would change this

A demonstration that one of these figures is re-derivable by a live entry point. That would make it an instrument reading and put it squarely under §6, and I would take the loss on that figure immediately. Naming such an entry point is the way to win this.

— sent from bold-ram-844

@gunbai-bot

gunbai-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

One main merge is due, and it is one cycle rather than the loop returning. Posting here rather than over the dashboard because the dashboard is currently unreachable (curl exit 7 on both read and write paths; GitHub is fine).

Main is now at 4f0ad8c6c8c; the merge base with this head is 0c031e6da4e. Exactly one path changed on both sides:

docs/design-failure-modes.md

git merge-tree --write-tree origin/main e0f27316c34 returns rc=1 with a genuine GeneratedArtifactConcurrentDivergence on that path and nothing else. The refusal is real and designed, and it is confined to the projection — no authority file conflicts at all.

The content union is already done. Membership join on both heads, keyed on the identity: field in dag/gunbc/recurring_failure_mode/:

origin/main    authority_ids=98   projection_lines=217   missing=0
e0f27316c34    authority_ids=100  projection_lines=221   missing=0
main identities absent from this branch's projection: NONE

This head already carries every one of main's 98 rows plus its own 2, and stayed a superset across main moving. What has not been done is producing the projection from the merged authorities, which is why the bytes diverge while the membership does not.

So the resolution is the recipe, not a decision. Merge main locally in a hooks-configured clone, let the driver refuse, and regenerate rather than picking a side — the driver's own message enumerates the steps, including the fixed-point pass. Both sides are stale against the merged authority; that is exactly what the refusal asserts.

Timing, and this is the one thing worth honouring: CI is running on e0f27316c34 right now. Don't push the resolve until it settles — a push cancels the run, and this PR has already spent six cycles producing runs nobody could read.

Why this isn't the loop. The loop was a resolution-method problem: each cycle re-derived the projection in a way that dropped the other side's rows, so the union never accumulated. It accumulates now. What remains is periodic and bounded — every roster append on main costs every open branch one regeneration — which is the split roster's known price, not a defect here.

One caveat on the numbers above: the join keys on identity:, not name:. A field name that matches nothing returns 0 ids and 0 missing, which is indistinguishable from success; the check that it is reading something is that the 98/100 counts move independently of the 217/221 line counts.

GitHub reports MERGEABLE because its merge test does not run our driver. That is not licence to let it text-merge a generated projection at squash time — that is precisely the case the driver was landed for.

@gunbai-bot

gunbai-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Adding one piece of evidence to the ruling above, because it is stronger than the corpus count I led with earlier and it is a specific landed precedent rather than an aggregate.

artifact_declares_a_threshold_it_is_not_measured_against is already on main. Verified there:

run 33722461610          required_floor_claim_cost.tsv          2026-09-03
p50=2ms   p90=84ms   p99=364ms   p99.9=514ms   max=541ms

That row carries a run id, the artifact by name, and a date — and then five unit-bearing percentile figures, four bucket counts, and a sentence of the form "21 of those 29 sit within ten percent of it." It is the same construction as mine, in the same carrier, landed.

So the reading in review 59907 does not distinguish my two rows from the practice this carrier was built around. Either it convicts that row too, or the line is where I have been placing it: a figure beside a named, re-derivable producer is not the thing §6 forbids. §6's harm is rot — "unreachable from the thing that owns it" — and a number sitting beside its run is not unreachable; the producer is right there. It is the same shape as §3's own standing rule, which permits a position "as a convenience beside the symbol, never the citation itself." Here the figure sits beside the run, never instead of it.

And the second row already contains the proof that the rule was applied rather than missed — in the file, not in this thread:

"An earlier draft of this row cited a p-value from a fleet census to make the same point; it was removed because no entry point that re-derives it could be named — by DESIGN §6's own test that makes it a one-off rather than an instrument, and a row arguing that receipts must be sourced may not itself carry an unsourceable figure."

The figure with no re-derivable producer is gone. The ones with producers stayed. That is where §6 draws its line, and this finding would now delete the survivors as well.

Compliance would also cost the rows their content. §4b requires a row to carry its distinguishing facts, and for cheap_question the distinguishing fact is the before/after pair — cpu 501 ms and 151,552 steps becoming cpu 0 ms and 35 steps — because the class is that the defect is a cost shape and not a magnitude. Strip the numbers and the row asserts a shape with nothing shaping it: not a smaller claim, a different and weaker one.

The offer stands unchanged: name a live entry point that re-derives any figure in either row and I will remove that figure the same hour. If a figure turns out not to name a producer, I will add the producer rather than delete the number.

— sent from bold-ram-844

…rows

# Conflicts:
#	docs/design-failure-modes.md
briansrls pushed a commit that referenced this pull request Sep 4, 2026
…ign-failure-modes.md are contended by three open PRs

The class is real and stands (a printed remedy mangled by the medium that
prints it, whose failure arm is a vacuous PASS rather than a refusal), but
filing it needs a row file AND an import/entry edit in
gunbc.recurring_failure_mode.roster, plus the regenerated
docs/design-failure-modes.md projection -- and #10317, #10320 and #10326 are
open against exactly those two paths. Landing it here would put this branch
into a driver-refused merge on the very projection whose repair recipe this
branch is fixing.

So the driver repair lands alone, touching no contended path. The row
follows in its own change against whatever roster head survives those three.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BPNfohdhatLvf5HT9jK5k6
@briansrls briansrls closed this Sep 4, 2026
briansrls added a commit that referenced this pull request Sep 5, 2026
…ne of which reported a vacuous PASS (#10460)

* The merge driver's repair recipes: one refuses, one is mangled by the echo that prints it, one never matched half its subject

Three defects in gunbc.generated_artifact_merge_driver, all one class: a
documented command that does not do what it says when run verbatim.

1. AuthorRegeneratesBeforeMerge step 3 ended `claim_executor
   --required-regen-fixed-point` with no --source-root. That binary's
   argument guard sits ABOVE the fixed-point branch, so the run exits 2 on
   `provide at least one --source-root` before reaching a mode that reads no
   roots at all -- which is why the omission looked harmless to write. It is
   the last command of the arm every generated artifact takes except the two
   heal-delegated rosters, so the author has paid two builds and two regen
   passes when it refuses.

2. The heal arm's set-difference command is written between backticks, and
   the driver echoes every recipe line inside DOUBLE quotes (they are
   templates; $merged_path must interpolate). Executed against the committed
   .githooks/generated-artifact-merge: bash ran the capture group as a
   command substitution -- two `([a-z0-9_]*): command not found` lines -- and
   printed the instruction as `sed -n 's/^- .*/\1/p'`, capture group deleted.
   Pasted, that extracts zero rows from both sides and the difference over
   two empty sets is empty, which the recipe's own words read as MUST BE
   EMPTY: the mangled remedy reports the vacuous pass the intact remedy
   exists to prevent. Escaping now happens in emit_driver_stderr_echo, where
   the quoting decision is made; it deliberately differs from
   gunbc.shell_bash_runner bash_escape_for_double_quotes on exactly one
   character ($), and that difference is named in the module rather than
   left to read as a fork.

3. The same command's row extractor only ever matched
   docs/design-failure-modes.md. The other delegated projection,
   docs/design-rung-drops.md, carries `### Title — declared ...` headings,
   not slug bullets: 105 rows extracted from one file, 0 from the other, so
   on the rung-drops path the check was green by construction. One extractor
   now names both row identities.

Evidence: test.claim.generated_artifact_merge_driver_recipe reads the
EMITTED script rather than the authored list -- the second defect is
invisible in the authored string -- and refuses the unescaped form.
gunbc.recurring_failure_mode.printed_remedy_is_mangled_by_the_medium_that
_prints_it files the class, with its boundary against
restoration_promise_names_a_route_that_does_not_exist (there the route does
not exist; here it does, and the rendering is what breaks, so every by-name
instrument agrees the remedy is present).

No emitted artifact hand-edited.

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

* Hold the failure-mode row out of this branch: roster.dag and docs/design-failure-modes.md are contended by three open PRs

The class is real and stands (a printed remedy mangled by the medium that
prints it, whose failure arm is a vacuous PASS rather than a refusal), but
filing it needs a row file AND an import/entry edit in
gunbc.recurring_failure_mode.roster, plus the regenerated
docs/design-failure-modes.md projection -- and #10317, #10320 and #10326 are
open against exactly those two paths. Landing it here would put this branch
into a driver-refused merge on the very projection whose repair recipe this
branch is fixing.

So the driver repair lands alone, touching no contended path. The row
follows in its own change against whatever roster head survives those three.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

* The extractor may not take $1: the driver's own argv was substituting into the instruction it printed

Caught by simulating the emitter over the authored strings and RUNNING the
result, which is the only reading that sees this class at all. The recipe
had been drafted as `rows() { git show "$1:$merged_path" | ... }` -- and $
stays active in the emitted echo by construction, because $merged_path must
interpolate. So $1 was git's %O placeholder, and the printed instruction
read `git show "O:docs/design-rung-drops.md"`: an author pasting it would
have asked git for a ref named O. Escaping does not save it either, since
the escaper doubles backslashes before the reader sees them, so `\$1` prints
as a backslash.

The line now names $merged_path -- the one variable the driver defines --
and pipes into a parameterless function. Witnessed by
heal_recipe_names_only_the_variable_the_driver_defines.

EXECUTED, as rendered, against a real divergence (this branch's base vs
origin/main, which is ahead by a landed roster PR):

  failure-modes  base=112  head=105  and the difference NAMES the seven rows,
  rung-drops     base=35   head=35   difference empty

Seven named rows and a measured empty -- neither of which the recipe could
produce before this branch, on either projection.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

* Dissolve the second escaper into the shared authority, and declare this carrier's medium on the carrier

Answers review 60392 (codex/gpt-5.6-sol, REQUEST_CHANGES) on its two
actionable points.

THE SECOND QUOTING IMPLEMENTATION IS GONE, which was the fair half of the
finding: I had authored an escaper beside gunbc.shell_bash_runner
bash_escape_for_double_quotes, and one concept with two names is what DESIGN
section 3 forbids -- the next fix lands in one of them. But the two callers
genuinely disagree about exactly one character. A literal line must have its
$ escaped or the shell expands a variable the author never wrote; a TEMPLATE
line, which is what a recipe naming $merged_path is, must leave $ active or
the instruction prints a dollar sign instead of the path. So the shared
function is SPLIT rather than copied:
bash_escape_double_quote_specials_except_expansion holds the identical part,
bash_escape_for_double_quotes is now composed from it plus the $ arm, and
this module calls the shared arm. Backslash-first is preserved and annotated
as load-bearing, since every later arm introduces backslashes.

Behaviourally inert, and checked rather than asserted: every emitted heal
line reproduces the committed .githooks bytes exactly, so the projection
does not move. The reordering ($ after backtick instead of before) is
output-identical because no arm introduces a character a later arm escapes.

THE MEDIUM DISPOSITION IS NOW DECLARED ON THIS CARRIER. A git merge driver
is one of the foreign executors DESIGN's shell-to-intent routing names --
git runs it with no gunbc runtime present -- so bash is the emitted medium
and the concat-built spelling is an interim one. That was true before this
branch and unmarked, which is the reviewer's point. It is now
gunbc.local_tidy_spec generated_artifact_merge_driver_emit_scaffold, a
Scaffold binding expected_generated_artifact_merge_driver_sh with
dissolves_to RealizationDispatch, plus a DissolutionCondition on the module.
Stated here rather than inherited from the hook-emit family for the reason
review 45175 gave the pre-push sibling: a family trigger tracked once lets
each member inherit it implicitly.

THE TRIGGER NAMES THE CAPABILITY, NOT THIS ARTIFACT. Emitting this one
script through the grammar path would retire nothing; what retires the row
is the bash medium modelled well enough that a line's variable references
and shell-active characters are DECLARED rather than spelled. That is the
same ceiling this module's defects establish -- every one of them was a
rendering the author could not see in the authored string.

Witnessed by emitted_driver_carries_a_bound_medium_disposition_with_a
_capability_trigger: the Scaffold's bind must name the emitter, and the
trigger must carry the capability clause. A Scaffold binding nothing marks
nothing.

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

* My own witness was written against the authored string, not the emitted bytes -- the exact mistake it exists to catch

CI floor lane: two of the five witnesses returned Bool(false). They were mine
and they were wrong, in the same way the defects they check are wrong.

I asserted the emitted script contains

    s/^- `\([a-z0-9_]*\)`.*/\1/p

which is the AUTHORED spelling. What the emitter actually produces is

    s/^- \`\\([a-z0-9_]*\\)\`.*/\\1/p

because the escaping pass doubles backslashes as well as escaping backticks
-- the backslash arm is the first thing it does, and I read past it while
writing a check whose entire premise is that the rendering differs from the
authored text. The witness was built on the wrong artifact, which is this
module's own failure mode applied to its own evidence.

Now asserted against the real bytes, and every assertion in the file was
EXECUTED against the committed .githooks projection before pushing rather
than reasoned about: seven string reads, four expecting present and three
expecting absent, all agreeing. The RED control is unchanged in meaning --
the raw-backtick form `- `\([a-z0-9_]*` must be absent, and it is, because
that is what the escaper prevents.

Two notes on what this does NOT change. The production fix was always
correct: heal-generated-artifacts passes, so the committed hook is the exact
projection of the authority, and running it prints the extractor intact. And
the build lane's failure is still not mine -- inherited stage0-mirror drift,
which #10467 repairs.

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
gunbai-bot Bot added a commit that referenced this pull request Sep 5, 2026
…ect belongs to (#10505)

* The merge driver's repair recipes: one refuses, one is mangled by the echo that prints it, one never matched half its subject

Three defects in gunbc.generated_artifact_merge_driver, all one class: a
documented command that does not do what it says when run verbatim.

1. AuthorRegeneratesBeforeMerge step 3 ended `claim_executor
   --required-regen-fixed-point` with no --source-root. That binary's
   argument guard sits ABOVE the fixed-point branch, so the run exits 2 on
   `provide at least one --source-root` before reaching a mode that reads no
   roots at all -- which is why the omission looked harmless to write. It is
   the last command of the arm every generated artifact takes except the two
   heal-delegated rosters, so the author has paid two builds and two regen
   passes when it refuses.

2. The heal arm's set-difference command is written between backticks, and
   the driver echoes every recipe line inside DOUBLE quotes (they are
   templates; $merged_path must interpolate). Executed against the committed
   .githooks/generated-artifact-merge: bash ran the capture group as a
   command substitution -- two `([a-z0-9_]*): command not found` lines -- and
   printed the instruction as `sed -n 's/^- .*/\1/p'`, capture group deleted.
   Pasted, that extracts zero rows from both sides and the difference over
   two empty sets is empty, which the recipe's own words read as MUST BE
   EMPTY: the mangled remedy reports the vacuous pass the intact remedy
   exists to prevent. Escaping now happens in emit_driver_stderr_echo, where
   the quoting decision is made; it deliberately differs from
   gunbc.shell_bash_runner bash_escape_for_double_quotes on exactly one
   character ($), and that difference is named in the module rather than
   left to read as a fork.

3. The same command's row extractor only ever matched
   docs/design-failure-modes.md. The other delegated projection,
   docs/design-rung-drops.md, carries `### Title — declared ...` headings,
   not slug bullets: 105 rows extracted from one file, 0 from the other, so
   on the rung-drops path the check was green by construction. One extractor
   now names both row identities.

Evidence: test.claim.generated_artifact_merge_driver_recipe reads the
EMITTED script rather than the authored list -- the second defect is
invisible in the authored string -- and refuses the unescaped form.
gunbc.recurring_failure_mode.printed_remedy_is_mangled_by_the_medium_that
_prints_it files the class, with its boundary against
restoration_promise_names_a_route_that_does_not_exist (there the route does
not exist; here it does, and the rendering is what breaks, so every by-name
instrument agrees the remedy is present).

No emitted artifact hand-edited.

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

* Hold the failure-mode row out of this branch: roster.dag and docs/design-failure-modes.md are contended by three open PRs

The class is real and stands (a printed remedy mangled by the medium that
prints it, whose failure arm is a vacuous PASS rather than a refusal), but
filing it needs a row file AND an import/entry edit in
gunbc.recurring_failure_mode.roster, plus the regenerated
docs/design-failure-modes.md projection -- and #10317, #10320 and #10326 are
open against exactly those two paths. Landing it here would put this branch
into a driver-refused merge on the very projection whose repair recipe this
branch is fixing.

So the driver repair lands alone, touching no contended path. The row
follows in its own change against whatever roster head survives those three.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

* The extractor may not take $1: the driver's own argv was substituting into the instruction it printed

Caught by simulating the emitter over the authored strings and RUNNING the
result, which is the only reading that sees this class at all. The recipe
had been drafted as `rows() { git show "$1:$merged_path" | ... }` -- and $
stays active in the emitted echo by construction, because $merged_path must
interpolate. So $1 was git's %O placeholder, and the printed instruction
read `git show "O:docs/design-rung-drops.md"`: an author pasting it would
have asked git for a ref named O. Escaping does not save it either, since
the escaper doubles backslashes before the reader sees them, so `\$1` prints
as a backslash.

The line now names $merged_path -- the one variable the driver defines --
and pipes into a parameterless function. Witnessed by
heal_recipe_names_only_the_variable_the_driver_defines.

EXECUTED, as rendered, against a real divergence (this branch's base vs
origin/main, which is ahead by a landed roster PR):

  failure-modes  base=112  head=105  and the difference NAMES the seven rows,
  rung-drops     base=35   head=35   difference empty

Seven named rows and a measured empty -- neither of which the recipe could
produce before this branch, on either projection.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

* Dissolve the second escaper into the shared authority, and declare this carrier's medium on the carrier

Answers review 60392 (codex/gpt-5.6-sol, REQUEST_CHANGES) on its two
actionable points.

THE SECOND QUOTING IMPLEMENTATION IS GONE, which was the fair half of the
finding: I had authored an escaper beside gunbc.shell_bash_runner
bash_escape_for_double_quotes, and one concept with two names is what DESIGN
section 3 forbids -- the next fix lands in one of them. But the two callers
genuinely disagree about exactly one character. A literal line must have its
$ escaped or the shell expands a variable the author never wrote; a TEMPLATE
line, which is what a recipe naming $merged_path is, must leave $ active or
the instruction prints a dollar sign instead of the path. So the shared
function is SPLIT rather than copied:
bash_escape_double_quote_specials_except_expansion holds the identical part,
bash_escape_for_double_quotes is now composed from it plus the $ arm, and
this module calls the shared arm. Backslash-first is preserved and annotated
as load-bearing, since every later arm introduces backslashes.

Behaviourally inert, and checked rather than asserted: every emitted heal
line reproduces the committed .githooks bytes exactly, so the projection
does not move. The reordering ($ after backtick instead of before) is
output-identical because no arm introduces a character a later arm escapes.

THE MEDIUM DISPOSITION IS NOW DECLARED ON THIS CARRIER. A git merge driver
is one of the foreign executors DESIGN's shell-to-intent routing names --
git runs it with no gunbc runtime present -- so bash is the emitted medium
and the concat-built spelling is an interim one. That was true before this
branch and unmarked, which is the reviewer's point. It is now
gunbc.local_tidy_spec generated_artifact_merge_driver_emit_scaffold, a
Scaffold binding expected_generated_artifact_merge_driver_sh with
dissolves_to RealizationDispatch, plus a DissolutionCondition on the module.
Stated here rather than inherited from the hook-emit family for the reason
review 45175 gave the pre-push sibling: a family trigger tracked once lets
each member inherit it implicitly.

THE TRIGGER NAMES THE CAPABILITY, NOT THIS ARTIFACT. Emitting this one
script through the grammar path would retire nothing; what retires the row
is the bash medium modelled well enough that a line's variable references
and shell-active characters are DECLARED rather than spelled. That is the
same ceiling this module's defects establish -- every one of them was a
rendering the author could not see in the authored string.

Witnessed by emitted_driver_carries_a_bound_medium_disposition_with_a
_capability_trigger: the Scaffold's bind must name the emitter, and the
trigger must carry the capability clause. A Scaffold binding nothing marks
nothing.

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

* My own witness was written against the authored string, not the emitted bytes -- the exact mistake it exists to catch

CI floor lane: two of the five witnesses returned Bool(false). They were mine
and they were wrong, in the same way the defects they check are wrong.

I asserted the emitted script contains

    s/^- `\([a-z0-9_]*\)`.*/\1/p

which is the AUTHORED spelling. What the emitter actually produces is

    s/^- \`\\([a-z0-9_]*\\)\`.*/\\1/p

because the escaping pass doubles backslashes as well as escaping backticks
-- the backslash arm is the first thing it does, and I read past it while
writing a check whose entire premise is that the rendering differs from the
authored text. The witness was built on the wrong artifact, which is this
module's own failure mode applied to its own evidence.

Now asserted against the real bytes, and every assertion in the file was
EXECUTED against the committed .githooks projection before pushing rather
than reasoned about: seven string reads, four expecting present and three
expecting absent, all agreeing. The RED control is unchanged in meaning --
the raw-backtick form `- `\([a-z0-9_]*` must be absent, and it is, because
that is what the escaper prevents.

Two notes on what this does NOT change. The production fix was always
correct: heal-generated-artifacts passes, so the committed hook is the exact
projection of the authority, and running it prints the extractor intact. And
the build lane's failure is still not mine -- inherited stage0-mirror drift,
which #10467 repairs.

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

* Execute the merge driver's printed recipe, do not read it

test.claim.generated_artifact_merge_driver_recipe asserts over the EMITTED
SCRIPT and says so in its own header: its reads "cannot claim the command
RUNS", and it points at test.claim.generated_artifact_merge_driver_real_execution
as the wet arm that would. That arm carried no recipe claim. This adds it.

The two assertions are different claims and only the second is the one that
matters. A string read over the emitted bytes proves an escape was APPLIED. It
cannot distinguish a correct escape from a wrong one -- doubling the wrong
character, or escaping $ and killing the $merged_path the driver defines, both
produce escaped bytes and a recipe that still does not work. Reading what bash
ACTUALLY PRINTED after expansion is what proves the program survived the medium.

  driver_printed_step_two_carries_the_dark_row_extraction_program drives a real
  refused merge and reads merged.stderr.

  dark_row_extraction_program_names_a_row_that_went_dark runs that same
  declaration through real sed over a fixture ledger and over the same ledger
  with one row removed.

THE SECOND ASSERTS AN IDENTITY JOIN, NOT NON-EMPTINESS, and the fixture is
built FROM gunbc.recurring_failure_mode roster rather than from a hand-written
row list. Non-emptiness proves acquisition and nothing else: it catches the
total-failure mode and passes identically at 1 extracted row, at 40, and at 119
of 120, while the check quietly ranges over a fraction of its subject. The
fixture also reproduces the projection's two-bullet shape -- one index bullet
and one prose bullet per row -- so a program matching every bullet reads twice
the roster count and reds, and one matching none reads zero and reds.

extdeps.tools.sed gains ScriptSuppressAutoPrint: sed -n with the script as an
ARGUMENT, so a caller executing a program it received from somewhere else does
not have that program re-read by a shell on the way in. stdout_lines rather
than stdout, because an empty capture and a refusal are indistinguishable as
one string -- which is the failure its first consumer exists to catch.

Both functions are enrolled in ci_layer_roots bin_wet, floor_route_gap and
local_repo_wet_terminal, so they execute rather than merely exist.

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

* Execute the merge driver's printed recipe, do not read it

#10460 repaired the recipe and enrolled the evidence it could reach:
test.claim.generated_artifact_merge_driver_recipe asserts over the EMITTED
SCRIPT, and its own header says those reads "cannot claim the command RUNS",
naming test.claim.generated_artifact_merge_driver_real_execution as the wet arm
that would. That arm carried no recipe claim. This adds it, and lifts the
extractor so there is one program to execute rather than a copy of one.

A STRING READ PROVES AN ESCAPE WAS APPLIED; ONLY STDERR AFTER EXPANSION PROVES
IT IS CORRECT. Doubling the wrong character, or escaping $ and killing the
$merged_path the driver defines, both produce escaped bytes and a recipe that
still does not work -- and both pass the emitted-bytes assert while failing
driver_printed_step_two_carries_the_row_extractor, which drives a real refused
merge and reads merged.stderr.

THE SECOND TEST ASSERTS A COVERAGE JOIN, NOT NON-EMPTINESS, and that is this
recipe's own history rather than a principle applied from outside. The hole
#10460 found on docs/design-rung-drops.md was a correct program pointed at a row
shape it could not match: it rendered perfectly, read zero of 36 rows, and
reported a pass it never measured. Non-emptiness cannot see that -- it passes at
one extracted row, at forty, and at all-but-one. So the fixture is built FROM
gunbc.recurring_failure_mode roster and gunbc.rung_drop roster, carries BOTH row
spellings, and requires the extraction to name every rostered row on both sides,
with one row of each shape removed on the second side and required to be named
by the first and not the second. Dropping either sed clause reds it.

THE EXTRACTOR IS NOW ONE DECLARATION. The landed step 2 spells a rows() shell
function with two sed -e clauses inside a prose sentence, so the printed program
and any executed copy are two things that can drift. The expressions are lifted
to generated_artifact_merge_driver_row_identity_extraction_expressions; the
printed text is derived from them, the witness executes them, and the emitted
bytes are unchanged -- .githooks/generated-artifact-merge is byte-identical to
main. The -e pairing lives in extdeps.tools.sed beside the -i it already owned,
and the single-quote wrapping is extdeps.posix.shell_command_language
posix_single_quote rather than a literal quote pair.

extdeps.tools.sed gains ScriptsSuppressAutoPrint: sed -n with its scripts as
argv entries, so a caller executing a program it received from somewhere else
does not have that program re-read by a shell on the way in. stdout_lines rather
than stdout, because an empty capture and a refusal are indistinguishable as one
string -- the failure its first consumer exists to catch.

Both functions are enrolled in ci_layer_roots bin_wet, floor_route_gap and
local_repo_wet_terminal, so they execute rather than merely exist.

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

* File the class the driver's own defect belongs to, and hoist an annotation out of a service block

THE ROW. gunbc.recurring_failure_mode.printed_remedy_is_mangled_by_the_medium
_that_prints_it. calm-owl-417 identified this class while repairing #10460 and
deliberately held it out of that branch, because filing needs roster.dag AND the
regenerated projection, both of which were moving under open PRs -- which would
have put the branch into a driver-refused merge on the very projection whose
recipe it was repairing. The follow-up never landed and the session ended, so the
class existed only in a merged pull request body. Their 7a and 7c specimens are
carried here as theirs, with that provenance on the carrier. Section 3's hazard is
a second authority forking an existing one; there was no authority to fork.

WHAT THE ROW CARRIES BEYOND THE TWO ORIGINAL SPECIMENS.

The recognition rule: the sender sees intact text, the recipient gets a silently
shortened sentence, and nothing reports a failure. Every instrument that reads the
AUTHORED artifact agrees the remedy is present, because it is present.

The disproportion, measured: an invalid backreference makes sed refuse the ENTIRE
program, so mangling one character in the first clause silences a second clause
nothing touched. Against a fixture carrying both row spellings and 157 rostered
rows, the intact program names 157 and the mangled program names ZERO -- not 36,
which is what per-clause degradation would predict.

Two further specimens in a different medium, both in messages ABOUT this class:
agent message bodies passed to a double-quoted shell argument, backquoted spans
substituted away, recipients receiving sentences with phrases missing. One was a
message whose subject was instruments that report success without carrying their
claim; the other was sent by the author repairing the first specimen.

THE MANGLING EXECUTES, WHICH IS THE PART THAT CHANGES THE CLASS. Found as physical
residue: a message containing `-> Bool` inside double quotes ran `-` as a command
and `> Bool` as a REDIRECTION, creating an empty file in the repository working
tree. A fragment of English prose was evaluated as a program. The lossy reading is
the benign one; a backquoted span is command substitution, which is arbitrary
execution. It did not reach a commit because the last commit happened to precede
it by fifteen minutes -- recording that as "it did not land" would be luck reported
as safety, so the row records the ordering as the reason.

The check that licenses, which found a different residue in a second tree on its
first application: inspect git status for unexplained worktree changes after any
session that has sent shell-quoted messages, and do not stage with `git add -A`
there. Generalized past messages, because any command that writes into the
worktree as a side effect of verification leaves residue a reviewer cannot
distinguish from intent.

Bounded against empty_capture_read_as_clean_result by the argument that decides
it: a substituted positional argument is not an empty capture at all, so the
medium is the root and the empty operand is one consequence.

THE HOIST. extdeps.tools.sed carried its new operation's annotation INSIDE the
service block. DESIGN section 4c admits standalone leading comment blocks on
module-scope declarations only, so that was a parse error -- invisible in a diff,
indistinguishable from ordinary corpus style, and caught only by running the
compiler over it. Moved above the service block with the operation named in its
first line.

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

* Enroll the positive control and both mutation controls: cited but unexecuted is the class this row files

Answers review 60644 (claude/claude-opus-4-7, REQUEST_CHANGES), which is
correct and finds an instance of the very failure this branch exists to close.

WHAT HAPPENED, because the mechanism is worth naming rather than just fixing.
The first version of this branch had two wet tests and enrolled both. Review
feedback then asked for a stronger reconciliation, so three more landed -- an
accepting positive control and the two count-preserving mutation controls that
are the whole reason the reconciliation is three sets rather than one number.
The enrollment rosters were never revisited. So the file grew from two executed
claims to five claims of which two executed, and the new row's evidence list
cited one of the three that did not.

That is `discriminating_arm_built_but_never_enrolled`, and it is DESIGN section
4b(1) inverted: the row reported a rung established by evidence that no lane
ran. It is also section 5's specification-without-execution trap in its most
deniable form -- the tests are real, correct, and would pass; they simply were
not on any acceptance path, and nothing about reading the file says so.

The mutation controls are the load-bearing ones and that makes the omission
worse rather than lesser. The module header argues they exist BECAUSE a
cardinality check passes on substitution and duplication and only an identity
join separates them. An unenrolled control that the carrier calls load-bearing
is a claim about coverage the tree cannot make.

  row_extractor_reconciles_with_both_rosters_by_real_execution
  row_extractor_refuses_a_substituted_identity_by_real_execution
  row_extractor_refuses_a_duplicated_identity_by_real_execution

now carry bin_wet rows in gunbc.ci_layer_roots, entries in
floor_route_gap_chunk_00, and WetScheduledClaim rows in local_repo_wet_schedule
-- the same three rosters the two original tests were enrolled in. All five wet
functions in the file are now on the acceptance path.

The failure-mode row also cites both mutation controls, not just the positive
one. A row whose evidence names only the accepting case describes half its own
claim.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

Ledger-Repair-Judged: docs/design-failure-modes.md
Ledger-Rows-Repaired: docs/design-failure-modes.md printed_remedy_is_mangled_by_the_medium_that_prints_it
Ledger-Repair-Judged: docs/design-rung-drops.md

* Regenerate the ledger projection locally, and record the substitution firing on the row it belongs to

TWO THINGS, both consequences of the same merge.

THE PROJECTION WAS AUTHORITY-AHEAD BY EXACTLY THIS BRANCH'S ROW. roster.dag
declared printed_remedy_is_mangled_by_the_medium_that_prints_it and
docs/design-failure-modes.md contained it zero times, because an earlier merge
resolution took the base side of the projection per the driver's own step 1 --
the documented state, waiting on heal, which had not pushed. Every by-name
instrument agreed the row was filed, because it was, in the authority; the
document a reader opens did not have it. Shipping that would have been this
row's own subject.

Regenerated with a gunbc built from this tree rather than the installed one.
The installed binary predates DESIGN section 4c source annotations and fails the
corpus at comment positions, which is why six earlier regeneration attempts
emitted nothing at all -- they never reached evaluation. The tree-built binary
writes. Verified by the same three-set reconciliation this branch enrolls:
projection 128 rows, roster 128 entries, and rostered-minus-projected,
projected-minus-rostered and duplicates all EMPTY. A count equality alone would
not have established that, which is the whole argument of the witness.

THE SUBSTITUTION CASE FIRED IN PRODUCTION AND IS NOW A RECEIPT ON THE ROW.
Merging main reached this driver on that projection. It refused as specified --
zero conflict markers, three index stages, ours left clean -- and the repaired
step 2 measured base 126 rows against ours 126 rows, COUNTS EQUAL, with the ours
side dropping exactly one row main had added
(duplicate_record_literal_field_silently_last_wins) and adding one of its own.

A cardinality check passes on that and reports nothing; only the identity join
names the casualty. So the case a review had challenged this branch to cover
arrived unprompted, on the same projection, minutes after the controls for it
were enrolled. It is a discriminating RED on the real acceptance path rather
than a fixture, which is what DESIGN section 4b(1) asks a rung claim to rest on.

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

* Regenerate the projection from the merged authority: neither side's bytes were it

The merge of main reached the generated-artifact driver on this projection and
it refused as designed -- zero conflict markers, three index stages, ours left
clean. Stages 1/2/3 were captured to files BEFORE any resolution, per the
ordering rule that a resolving `git checkout` or `git add` clears the stages and
a later read of them returns nothing.

Measured across the captured stages, with a deletion positive control proving
each direction can produce a non-empty answer:

  base 127 rows, ours 128, theirs 128 -- OURS AND THEIRS COUNT-EQUAL
  theirs carried edit_pass_that_matched_nothing_reports_success, which ours lacked
  ours carried printed_remedy_is_mangled_by_the_medium_that_prints_it, which theirs lacked

So neither side's bytes were the projection of the merged authorities, which is
the precise condition this driver exists to refuse rather than resolve. Taking
either side would have dropped exactly one row at an unchanged total, and a
count check reports nothing on that.

The authority merged cleanly carrying BOTH rows, so the projection is
regenerated from it rather than chosen between the two sides. Verified by the
same three-set reconciliation this branch enrolls: projection 129 rows, roster
129 entries, missing/unexpected/duplicated all EMPTY, with a positive control
that names a row deliberately dropped from the roster side.

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

* Regenerate the projection from the merged authority (three rows, two lanes)

Fourth conflict cycle on this projection. Stages captured to files before any
resolution, compared under one collation, with a deletion positive control so an
empty answer is known to be discriminating:

  base 128, ours 129, theirs 130
  theirs carried a_branch_property_falsified_by_a_derived_push and
    a_deconfliction_plan_does_not_enumerate_its_writers, which ours lacked
  ours carried printed_remedy_is_mangled_by_the_medium_that_prints_it,
    which theirs lacked

Neither side's bytes were the projection of the merged authorities, so neither
was taken as the answer. The authority merged additively with all three rows and
the projection is regenerated from it.

Verified by the three-set reconciliation this branch enrolls: projection 131
rows, roster 131 entries, missing/unexpected/duplicated all EMPTY, with a
positive control that names absorbing_fallback when it is dropped from the
roster side.

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

* Regenerate the failure-mode projection over the merged roster

Cycle-5 regeneration after merging origin/main: the projection now carries
all 133 rostered identities. Verified by three-set reconciliation (missing,
unexpected, duplicated all empty) with a positive control that drops
absorbing_fallback from the roster side and confirms it is named.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

Ledger-Repair-Judged: docs/design-failure-modes.md
Ledger-Rows-Repaired: docs/design-failure-modes.md printed_remedy_is_mangled_by_the_medium_that_prints_it
Ledger-Repair-Judged: docs/design-rung-drops.md

* chore: regenerate drifted generated artifacts (ci auto-heal)

Ledger-Repair-Judged: docs/design-failure-modes.md
Ledger-Rows-Repaired: docs/design-failure-modes.md reported_required_refusal_does_not_precondition_landing
Ledger-Rows-Repaired: docs/design-failure-modes.md printed_remedy_is_mangled_by_the_medium_that_prints_it
Ledger-Repair-Judged: docs/design-rung-drops.md

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
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