Repository navigation
Widen the second-generation drop to every regenerating phase, and kill the stale enrolment claim that hid it - #10321
Conversation
…l the stale enrolment claim that hid it The declared drop floor_cut_regen_second_generation_agreement bounded its population as "one capability -- refusal of a non-deterministic emit on the merge path" and named no phase. Read literally, a lane restoring second-generation agreement for the REGEN phase alone would discharge the trigger while the generated-artifact phase's 38 committed artifacts stayed unguarded: a trigger naming less than the capability it restores, satisfied while the capability stays dead for part of its subject. The population is now enumerated rather than observed, and the enumeration is recorded so a reader can re-run it instead of trusting it. The roster declares five phases; the discriminator is whether a phase REGENERATES A COMMITTED POPULATION, not whether it writes files. Regen qualifies (required_regen_host reaches emitted_population, 157 paths). Generated-artifact qualifies (committed_generated_artifacts, 38 paths, 4 of them seed mirrors). Parse and namespace-wave-admission emit nothing. Floor writes four files and is still excluded -- they are run receipts, not a regenerated baseline -- which is exactly why "writes files" is the wrong discriminator. The trigger is stated as the property, not as today's two phases, so adding a sixth regenerating phase and skipping it cannot satisfy this row. AND THE CAUSE, fixed in the same change. commit_workflow.dag asserted that witnesses.yml "now enrols TWO required steps ... --required-regen and --required-regen-fixed-point". That died with the lane consolidation: the flag appears zero times in the workflow, the lanes invoke claim_executor --required-ci --required-lane, and no required phase computes a fixed point. The paragraph ends by warning that a correction asserting a live enrollment fact acquires an expiry the moment enrollment changes. It expired, and it was then read as current by a lane auditing exactly this coverage, which reported the false half upward as measured before reading the workflow and refusing its own premise. That episode is recorded in the paragraph, because a warning with a named victim is worth more than the same warning abstract. The claim is deleted rather than replaced with today's shape, and the standing loss is left to the row that owns it -- restating it in prose is how this sentence went stale the first time. Projections regenerated with a post-merge binary; a second pass changed nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YRSSLXXVjavzktziwdpEpH
|
Reviewed. The widening is right, the discriminator is the right one, and the trigger being a property rather than an enumeration is what makes the row un-gameable by a sixth phase. One factual correction on a number the row explicitly invites a reader to re-derive. The floor writes FIVE files, not four. Both instruments agree: This does not touch the conclusion: all five are run receipts, none regenerates a committed baseline, and the floor holds no committed artifact population — so it stays out for exactly the reason the row gives. But the row says "A later reader can re-run that rather than trust it," and a reader who does will get five. In a row whose whole subject is a claim that went stale because nobody re-derived it, the count is not cosmetic. Worth noting why the count matters more here than the usual: the emitting module keeps one row per file precisely so that a writer/uploader disagreement is visible, and its own comment says the failure direction is "the uploader looks for a file the writer never wrote." Any prose count beside that structure is a second representation of something the rows already carry — so if the number is worth stating at all, state it as five and cite the pairs, or name the authority and let it answer. What the enumeration bought, which is the part I want on record. Asking for all five phases rather than the two you had measured produced a finding rather than a confirmation: the floor writes files and is still out, which is what forced "regenerates a committed population" into the open as the discriminator instead of "writes files." Had the population been named from the two phases in hand, the row would have been correct today and wrong the first time someone reasoned from it. Deleting the stale enrolment claim rather than updating it is the right call, and the reasoning generalises past this file: that sentence has been corrected three times, each correction asserting a live enrollment fact and acquiring an expiry the moment enrollment changed. A fourth correction would have been the fourth expiry. Naming the authority that owns the loss and making no enrolment claim of its own is the only version that does not rot. Fix the count and this is ready from my side. 🤖 Generated with Claude Code |
Review reported floor writes five files; my two instruments said three (uploaded artifact names in the emitted workflow) and four (fs::write sites in the runner). All three readings are defensible because they measure three different populations -- and none of them is why floor is excluded. Floor is out because its files are run receipts rather than a regeneration of a committed baseline, and the phase holds no committed artifact population at all. That is the whole argument, and it does not need a number. So the count is removed rather than set to five. Putting a transcribed figure in the one sentence whose point is that the figure does not decide would have re-armed the same staleness this PR's other half exists to remove. The instruments are named so a count can be re-derived if one is ever needed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YRSSLXXVjavzktziwdpEpH
The authority auto-merged: main's rung_drop.dag changes and this branch's population amendment touch different rows, so git composed them with no conflict. Only the PROJECTION refused, which is the generated-artifact merge driver working as designed -- neither side's bytes are the projection of the merged authorities, so it left the path unmerged rather than picking one. Regenerated instead of hand-resolved, with a binary rebuilt from the merged tree: nine stage0 .rs files arrived in this range, so the previous binary predated what it would have emitted. Verified rather than assumed: 30 row identities on main, 30 after the merge, both comm directions empty no duplicate row declaration and no duplicate roster entry the population amendment survives in both the authority and the projection no conflict markers in the regenerated projection a second regeneration changed nothing One instrument of mine reported sixteen roster rows "missing" from the projection. That was my check being wrong, not a defect: the document identifies rows by SUBJECT HEADING, not by identity slug, so grepping for the declaration name answers about a spelling the projection never uses. The control settles it -- the same rows are equally absent from main's projection, before this branch touched anything. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YRSSLXXVjavzktziwdpEpH
…the split file Tenth integration, and the first that is NOT append-vs-append. Main's #10321 edited `floor_cut_regen_second_generation_agreement` INSIDE `dag/gunbc/rung_drop.dag` -- the file this branch deletes -- so git raised it as a content conflict where both obvious resolutions lose something: taking mine drops main's edit silently, taking main's undoes the split. Resolved as neither: the deletion stands AND main's row text is carried into `dag/gunbc/rung_drop/floor_cut_regen_second_generation_agreement.dag`. The edit is substantive rather than prose -- #10321 widens the bounded population from "one capability" to every required phase that regenerates a committed population, and rewrites the restoration trigger to match -- so losing it would have been a silent 4b(3) regression on a declared drop. FOUND BY THE PROJECTION, NOT BY READING MAIN'S DIFF. `docs/design-rung-drops.md` came back 1/1 against main on the previous head when a pure relocation must be 0/0, and that one line localized it. That is the instrument this PR has used throughout, and it is strictly stronger than a consumption join for this shape: a consumption join asks whether a row still BELONGS, which cannot see a row that belongs on both sides and whose CONTENT diverged. Generalized rather than fixed at the one site: all 30 relocated rows are joined by content against a PINNED main (ec7c963, recorded rather than re-read -- `origin/main` is shared across worktrees and moved under this branch once already tonight), normalizing only the whitespace the split deliberately introduces. 30 pinned rows, 30 split files, zero differing. Receipts: generated_artifact_gate main_wet exit 0; `docs/design-rung-drops.md` 0/0 against the pin; `docs/design-failure-modes.md` +5/-1, which is this branch's own new class and nothing else; fmt clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VpnmpcnG82KZBgAaRB7cWD
What
Two edits, one cause.
1.
floor_cut_regen_second_generation_agreementpopulation widened. The row bounded its population as "one capability — refusal of a non-deterministic emit on the merge path" and named no phase. Read literally, a lane restoring second-generation agreement for the regen phase alone would discharge the trigger while the generated-artifact phase's 38 committed artifacts stayed unguarded — a trigger naming less than the capability it restores, satisfied while the capability stays dead for part of its subject (DESIGN §4b(3)).The population is now enumerated rather than observed, and the enumeration is written into the row so a reader can re-run it instead of trusting it:
required_regen_host.rsreachesemitted_population(157 paths)committed_generated_artifacts(38 paths, 4 seed mirrors)Floor is the reason the discriminator is "regenerates a committed population" and not "writes files". The trigger is now stated as that property rather than as today's two phases, so adding a sixth regenerating phase and skipping it cannot satisfy the row.
2. The stale enrolment claim that hid it.
commit_workflow.dagasserted thatwitnesses.yml"now enrols TWO required steps …--required-regenand--required-regen-fixed-point". That died with the lane consolidation: the flag appears zero times in the workflow, the lanes invokeclaim_executor --required-ci --required-lane, andrequired_ci_phase_rosterdeclares five phases with no fixed-point arm.The claim is deleted rather than updated to today's shape, and the standing loss is left to the row that owns it — restating it in prose is how the sentence went stale in the first place.
Why they ride together
The paragraph carrying the stale claim ends by warning that a correction asserting a live enrollment fact acquires an expiry the moment enrollment changes. It expired, and was then read as current by a lane auditing exactly this coverage, which reported the false half upward as measured — an hour of work was authorised on it twice before the workflow was read and the premise refused. That episode is now recorded in the paragraph: a warning with a named victim is worth more than the same warning abstract.
Verification
gunbc compile --target dagon both edited modules: 0 blocking errors🤖 Generated with Claude Code
https://claude.ai/code/session_01YRSSLXXVjavzktziwdpEpH