Repository navigation
Two failure-mode rows: authored quotation terminates its own string, and unresolved callee conflated with dispatched-elsewhere - #10710
Conversation
…ved callee FOUR .dag ROWS IN THE SUBSTRATE. This is not a document change: the authority is gunbc.recurring_failure_mode, these are rows in it, and docs/design-failure-modes.md is their derived projection. The projection is DELIBERATELY NOT IN THIS COMMIT -- see the last paragraph. authored_quotation_terminates_the_string_it_is_authored_in (new). The .dag lexer has no string escaping, so a double quote inside a string literal is not expressible -- it is avoided by convention. A receipt that QUOTES a phrase therefore terminates the string it is authored in, and the row filing the evidence is the row the evidence disables. The harm is not the parse error: an unparseable authority does not empty its projection, the projector refuses and the committed markdown stays at its previous vintage while its own header still says it is generated from the authority. Nothing in the rendered file distinguishes "this row has no new receipt" from "this row stopped compiling". Its ceiling is structurally impossible and NOT reachable by diligence, and its trigger names the capability: string escaping in the .dag lexer, sufficient to make a double quote expressible inside a string literal -- not a lint, not a convention, not a projection gate, each of which leaves the state writable and merely reports it. The projection gate under construction elsewhere makes this class LOUD within one commit, which is a real improvement to detection and is not the climb; the row says so. The specimen is a real un-staged occurrence, and the sharpest receipt cuts against its own author: seven doubled apostrophes in the same rows, defending against a hazard that does not exist -- an apostrophe inside a double-quoted string is ordinary text, written plainly across the roster. One author defended the case that was safe and left the fatal one undefended. A convention misapplied in both directions at once is not held by diligence, it is guessed at. unresolved_callee_conflated_with_dispatched_elsewhere (new). One unresolved-callee state carries both ANSWERED BY ANOTHER DISPATCH PATH and DECLARED SOMEWHERE BUT UNREACHABLE FROM HERE, so the second can never refuse -- and a delete-first census that rests on loud refusal undercounts by the ratio of the two. stale_claim_survives_its_own_correct_edit (append). One receipt: an import is not a consumer, so a census of a symbol's consumers that counts import lines measures the wrong form. THE PROJECTION IS NOT REGENERATED HERE, ON PURPOSE. docs/design-failure-modes.md is a generated artifact, and another branch is appending to this same roster and regenerating this same file. Bytes derived from a roster missing their rows would merge CLEAN AND WRONG -- no conflict, their rows silently gone. The .dag edits are the authority and merge on their own terms; the doc is regenerated once, on top of whichever authority lands last. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF
Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md stale_claim_survives_its_own_correct_edit Ledger-Rows-Repaired: docs/design-failure-modes.md unresolved_callee_conflated_with_dispatched_elsewhere Ledger-Rows-Repaired: docs/design-failure-modes.md authored_quotation_terminates_the_string_it_is_authored_in Ledger-Repair-Judged: docs/design-rung-drops.md
Both conflicts were the shape this branch was built to expect. ROSTER: a pure union. Main's two rows and this branch's two, added at the same insertion point. Both sides kept, main's first, in the import block and the roster alike. PROJECTION: the generated-artifact merge driver REFUSED, exactly as specified -- the path came back unmerged with ZERO conflict markers rather than answering with either side. It is resolved the only way it can be: regenerated from the merged authority, so the committed bytes are derived from a roster containing all four rows rather than picked from a side. A RETRACTION, RECORDED BECAUSE THE FALSE VERSION WAS NEARLY COMMITTED. A first attempt at this merge produced a CLEAN take-theirs on the projection that silently dropped this branch's rows, and it was about to be committed with a message calling that a driver failure -- the driver is configured here, `git check-attr merge` resolves the path to `generated-artifact`, and the script is byte-identical between this branch's base and main, so the inference looked sound. It was wrong. That merge ran from a branch position that did not yet contain the CI auto-heal commit, so THIS SIDE HAD NEVER MODIFIED THE PROJECTION: ours equalled the merge base, only theirs had changed, and a clean take-theirs is correct git behaviour that never reaches a low-level driver at all. The driver is reached only when BOTH sides changed the path since the base, which DESIGN states plainly. The comparison that produced the false finding measured the merge result against ours, theirs and the base, and never asked whether OUR side had changed the path since the base. A push rejected as non-fast-forward is what exposed it. With the auto-heal commit in history the same merge conflicts and the driver refuses, which is the executed positive control for the behaviour the retracted claim denied. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF
gunbc#10734 measured, on 2026-09-07, that eight of nine members of the absence family named no sibling at all, and that the one existing edge was invisible to the identity join because it was spelled as a NICKNAME -- a nickname being a DELETED EDGE rather than a weaker citation. Landing two new rows with zero sibling edges would add to that debt on the day it was published, in the same ledger the measurement is about. So both rows now cite by IDENTITY, never by description: authored_quotation_terminates_the_string_it_is_authored_in names docs_markdown_projections_have_no_completing_actuator as the DETECTOR GAP for the same incident -- a projection with no completing actuator, so a stale artifact and an unbuildable authority are indistinguishable from the committed markdown alone -- while this row is the AUTHORING INJURY. That gate makes this class loud within one commit and does not make it unwritable, which is why the repairs are non-substitutable. unresolved_callee_conflated_with_dispatched_elsewhere records that it is NOT a member of the absence family, tested against the audit's own membership rule rather than by resemblance: membership needs an EMPTINESS consumed AS AN AFFIRMATIVE VERDICT, and the repair here is partitioning one state into two constructors so the declared-but-unreachable case can refuse -- which neither a positive control nor a denominator supplies. THE REVERSE EDGE IS MISSING AND IS DELIBERATELY NOT REPAIRED HERE. docs_markdown_projections_have_no_completing_actuator names this row by description -- "a neighbouring class they are filing separately" -- which is exactly the shape the audit condemns. That row is merged and is not this lane's to edit; a follow-up owes it, and both the row and the PR body say so rather than leaving the obligation silently half-done. AND THE DEFECT THE FIRST ROW EXISTS TO NAME WAS COMMITTED WHILE WRITING IT, FOR THE SECOND TIME. Five doubled apostrophes went into these two receipts -- defending against a hazard that does not exist -- and were caught before commit by the same scan the row prescribes. Recorded here rather than quietly fixed, because a class whose author reproduces it twice while documenting it is better evidence for the lexer trigger than either occurrence alone. Projection regenerated from the authority. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF
BLOCKING CONTRADICTION, INSIDE ONE ROW. The CEILING paragraph of
unresolved_callee_conflated_with_dispatched_elsewhere justified
"structurally guaranteed, reachable now" from two ingredients the row
itself refutes further down:
1. that the state is already partitioned because CallTargetOutcome
carries CallableUnresolved as its own constructor -- while the
ABSORBER paragraph says in capitals that this constructor is NOT the
absorber, that an earlier revision looked at the wrong seam, and that
the constructor legitimately means the direct classifier did not give
the final answer.
2. that corpus membership decides whether a callee is declared -- which
is the leaf-name predicate the row explicitly WITHDRAWS, because it
makes corpus population into naming input.
THE DECISIVE TELL WAS THAT THE TRIGGER NAMED A DIFFERENT MECHANISM. The
NEXT-RUNG TRIGGER calls for structural declaration-kind evidence at the
ExprCall tail, removal of the bare whole-pool fallback, and an exact
reference-resolution arm it describes as "independent of pool population,
which is exactly what the withdrawn leaf-name predicate was not". The
trigger contrasted itself against the very predicate the ceiling still
rested on: ceiling and trigger disagreed about what the climb consists of.
WHY THAT BLOCKS RATHER THAN READING AS A WORDING NIT. DESIGN 4b(1) requires
a ceiling be DERIVED rather than aspirational, and a class below its ceiling
is ranked for climbing by exactly this paragraph. A ceiling derived from a
withdrawn mechanism sends the next reader to the seam this row already
established is the wrong one -- in a row whose whole content is that a
population sized by the wrong measure is the wrong number.
THE REPAIR IS RESTATEMENT, NOT RETREAT. The ceiling stays at structurally
guaranteed and reachable now; it is not weakened to mechanically preventable
to dodge the contradiction, and the paragraph is not deleted. It now derives
from the two structural facts the trigger names and the compiler already
carries: the DECLARATION KIND, which settles whether a callee is a callable
type or a data constructor without consulting what else the corpus happens
to declare, and an EXACT OCCURRENCE-TO-DECLARATION AUTHORITY saying this
occurrence binds this declaration, independent of pool population. Both are
decidable at the ExprCall tail, which is what makes the class a wall rather
than a ratchet.
BOTH WITHDRAWN INGREDIENTS ARE RECORDED RATHER THAN QUIETLY REPLACED, since
a ceiling that changes its derivation without saying so is the same class of
defect one revision later. And the one TRUE fact that survives the
withdrawal is kept as EVIDENCE rather than as the remaining work:
declared_formal_authority_failed is false for CallableUnresolved, so the
refusal reason is computed and never emitted -- a fact about the REPORTING
seam that says nothing about the absorbing one, which is precisely the
substitution the absorber paragraph exists to prevent.
Projection regenerated through the projector, not hand-edited.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF
…anscribed counts TWO COUNTS FOR ONE POPULATION, AT UNSTATED GRAIN, IN THE SAME ROW. The POSITIVE CONTROL receipt licensed "the reading of the 67 sites that emit nothing"; SCOPE NOT CLAIMED said "the other 70 emit nothing". Only one population exists and the row states how it is built: the MEASURED receipt finds 73 distinct callees among the branch-only pairs, three of which fabricate visibly, leaving 70. THERE IS NO DERIVATION THAT REACHES 67 -- it was a transcription with no denominator behind it, and a reader could not tell which population either sentence denominated. CORRECTING THE DIGIT WOULD HAVE LEFT THE DEFECT. DESIGN section 6 says to name the producer that re-derives a measurement rather than copy its numbers into prose, for the reason this row demonstrates: a transcribed number is unreachable from the thing that owns it, so it rots without anyone touching either end. Writing 70 in place of 67 would have produced a correct sentence with the same failure mode, one edit from going stale again. So both sentences now name the SILENT REMAINDER and how it is obtained -- the MEASURED receipt's branch-only distinct-callee population less the three whose failure is visible, re-derived by re-running that instrumentation of call_target_for_direct_call over the two-root corpus. No transcribed count survives in either sentence. This is the row whose whole content is that a population sized by the wrong measure is the wrong number; an unnamed denominator inside it was the same defect one paragraph over. AND THE CEILING DEFECT REPAIRED IN THE PREVIOUS COMMIT IS FILED AS A RECEIPT ON stale_claim_survives_its_own_correct_edit -- the class this same PR adds. Both premises the ceiling rested on were TRUE WHEN WRITTEN and were falsified by correct edits made elsewhere IN THE SAME ROW, which is that class exactly. The transferable part is not the incident but the mechanical tell: a ceiling and its next-rung trigger are the one pair in a row that must agree, so checking them against each other is a cheap executable instance of that row's recognition rule. Stated flatly -- a row long enough to withdraw its own premises can outlive them internally, needing neither a second author nor a second file. Projection regenerated through the projector. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF
…ed fact, and stale tense ITEM A -- THE CEILING REPAIR REPEATED THE DEFECT IT REPAIRED. The restated CEILING said the compiler ALREADY CARRIES BOTH structural facts, including the exact occurrence-to-declaration authority. The same row says, in its qualified-reference receipt, that NOTHING PERFORMS THAT JOIN TODAY -- which is why the segments of a qualified reference stay unrelated rows and the qualified arm is unreachable. A nearby true fact promoted one rung, which is this paragraph's original defect in a new sentence. Narrowed, not lowered: the compiler carries the INGREDIENTS FROM WHICH both are DERIVABLE WITHOUT NEW EXTERNAL GROUNDING. The ceiling still stands, because DESIGN section 5's wall-after-grounding case is about a MISSING AUTHORITY, and derivable-from-what-exists is exactly what makes this class reachable now rather than blocked behind one. The overstatement is recorded in the paragraph rather than quietly swapped. ITEM B -- THE HEADLINE'S CAUSAL DERIVATION WAS REFUTED BY THIS ROW'S OWN TRIGGER. It said one state carries both meanings SO THE SECOND CAN NEVER REFUSE. But the final `function not found in scope` diagnostic is ALREADY WRITTEN at the ExprCall tail and reachable once every legitimate dispatch path has missed -- and the repair this row proposes KEEPS CallableUnresolved, lets those authorities answer, and refuses there. Sharing an intermediate constructor does not imply the unreachable case can never refuse. What actually happens is that the direct-call miss is ABSORBED LATER, by generic-type and whole-pool lookup running after the legitimate paths have missed, so a targetless call acquires a fabricated answer instead of arriving at the refusal that exists for it. NEVER is DESIGN section 5's named trap word -- it lets a ratchet masquerade as a wall -- and here it asserted an impossibility the row disproves three paragraphs later. The class identity and its recognition name are unchanged; it was the derivation that was wrong. ITEM C -- THE QUOTATION ROW'S CEILING WAS INFLATED, AND ESCAPING DOES NOT REACH IT. The paragraph argued that once a string can CARRY a quotation the failure has nothing to be built from. It does not follow. ESCAPING MAKES THE CORRECT INTENT EXPRESSIBLE; IT DOES NOT MAKE THE BAD STATE UNWRITABLE. After escaping lands an author can still type a bare delimiter where they meant content, terminate the literal, and reproduce the failure exactly, so 4b rung 4 -- no constructor in the canonical model -- is not reached. That is the construction-versus-diligence distinction this row exists to enforce, committed by the row. Split rather than lowered. The ceiling is now derived from a carrier where delimiter escaping is CONSTRUCTION-OWNED rather than author-owned: structured content rendered by a serializer, or any carrier in which content cannot become its own delimiter. Lexer escaping remains a real next-rung trigger that removes today's forced workaround, with one sentence separating what it buys from what it does not, because conflating those is how the paragraph was wrong. ITEM D -- STALE TENSE, TRUE AT THE INCIDENT AND FALSE ON THIS TREE. The row said docs projections are gated NOWHERE, red in no lane, class under repair. #10701 has landed and this branch carries the completing comparison. Historicalized: no required content gate existed at the time of the incident; the failure is now loud within the required run, which closes the DETECTOR gap and not the AUTHORING injury. The rung reads as REACHED rather than conditional. Projection regenerated. The two surviving occurrences of the withdrawn wordings are inside the sentences that retract them, quoted deliberately. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF
… rung BLOCKER 1 -- THREE LATER PIECES OF THE UNRESOLVED ROW STILL TAUGHT THE MODEL THE HEADLINE, CEILING AND TRIGGER HAD ABANDONED. The instrument-recurrence receipt called "the seam returns its diagnostics as part of its result" the DURABLE REPAIR and the next-rung candidate; the BOUNDARY said the repair is partitioning one state into two constructors so the declared-but-unreachable case can refuse; the recognition rule's tell was a failure constructor whose consumer computes a refusal and does not use it. Those no longer described history, they PRESCRIBED -- and they prescribe what the corrected trigger says not to do. Making the direct-classifier diagnostics undiscardable removes neither ExprCall-tail absorber, and partitioning CallableUnresolved cannot be the wall when methods, builtins and variant constructors legitimately inhabit that state. The instrument incident is KEPT, because it is a genuine receipt, and given its disposition explicitly: an INSTRUMENTATION AND WIRING defect discovered while measuring this class, not this class's repair. The durable-repair and next-rung-candidate framing is gone. The BOUNDARY and the recognition rule are restated against the actual absorber -- after every legitimate authority misses, a later fallback fabricates an answer instead of letting the terminal refusal that is already written fire. The recognition tell is now a terminal refusal that EXISTS AND IS NEVER REACHED, with the instruction to ask what runs between the last legitimate authority and it. BLOCKER 2(b) -- STRING ESCAPING CANNOT BE THE NEXT-RUNG TRIGGER, AND THIS ROW'S OWN CEILING IS WHAT REFUTES IT. The ceiling now says correctly that escaping makes the intent expressible and leaves the bad state writable. A capability that leaves the invalid state writable changes no rung. So the trigger is the construction-owned carrier, and escaping is recorded as what it is: a real authoring capability that removes the forced backtick workaround, an EXPRESSIBILITY climb rather than a ladder climb. Naming it as the trigger was the third instance in this row of one paragraph being correct in isolation and refuted by another. BLOCKER 2(c) -- the sibling edge still spoke in present tense. It now reads that docs_markdown_projections_have_no_completing_actuator WAS the detector gap for this incident and #10701 closed it, with the identity still cited because a failure-mode row survives its own repair. BLOCKER 2(a) IS NOT IN THIS COMMIT AND IS BEING MEASURED RATHER THAN DECIDED. The row reports mitigatable while claiming the failure is loud within the required run; 4b defines that combination as rung 2. Nothing had driven an unparseable quotation through the post-#10701 REQUIRED acceptance path, so the claim was stronger than its evidence. #10782 plants exactly that break and is running now; the rung will be set from what it reports. The probe refuses locally with three `undefined variable` diagnostics, so it is discriminating rather than inert, and main plus this branch's parent are the executed positive control. Blocker 3, the stale PR body, is fixed on the PR rather than in the tree. Projection regenerated through the projector. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF
…isting The row reported MITIGATABLE while also claiming the failure is LOUD WITHIN THE REQUIRED RUN. Those cannot both stand: DESIGN 4b defines rung 2 as a gate that reliably exposes and blocks a still-writable invalid state, which is exactly what "loud within the required run" describes. And 4b(1) requires the reported rung equal the rung established by EXECUTED evidence on the real acceptance path -- which nothing had produced, because no unparseable quotation had ever been driven through the post-#10701 required run. MEASURED RATHER THAN DECIDED (#10782). A receipt carrying a bare double-quoted phrase inside a double-quoted string was planted in one ledger row and pushed. The required run REFUSED: error: resolve failed for dag/gunbc/instruments/generated_artifact_gate.dag cause: .../absorbing_fallback.dag:10:62: undefined variable 'unresolved' .../absorbing_fallback.dag:10:73: undefined variable 'AND' .../absorbing_fallback.dag:10:77: undefined variable 'declared' Located to file, line and column. Two required jobs failed on it. THE CONTROLS THAT MAKE THAT READ AS A MEASUREMENT. The probe was confirmed to refuse LOCALLY before being pushed, so it was discriminating rather than inert -- a probe that cannot fail proves the harness works, not the claim. The positive control is the same required lane green on main and on this branch's parent, so the red is attributable to the planted break rather than to the tree. TWO THINGS ALMOST MADE THIS PROBE INERT WHILE LOOKING ARMED, and both are worth knowing: witnesses.yml triggers on push only for main, so the branch push alone would never have run; and the auto-created PR was a DRAFT, which skips CI gates entirely. Either would have produced a probe that executed nothing and a conclusion drawn from its silence. RUNG IS NOW: below the ladder at the incident, MECHANICALLY PREVENTABLE now. Rung 2 and not higher, for 4b's own reason -- the state REMAINS WRITABLE and safety depends on that gate executing and staying enrolled. The ceiling and the trigger are unchanged: structural impossibility still needs a carrier where delimiter escaping is construction-owned. Projection regenerated through the projector. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF
The row said it cited the doubled apostrophe -- "seven occurrences, `row''s`, `class''s` and the like" -- and displayed `row's`, `class's`. The blanket regex that repaired the seven real occurrences REWROTE THE EXHIBIT TOO, leaving a sentence that claimed to cite a defect while showing its correct form. FOUND BY READING AN APPROVAL, NOT BY DISTRUSTING IT. A review confirmed `grep "''"` over the roster returns empty and read that as the residue being genuinely zero. It is zero -- including in the sentence whose whole job was to be non-zero. The mechanical test that verified the tree is the same test that had destroyed the evidence, so it could only agree. THE GENERAL FORM IS RECORDED IN THE ROW BECAUSE IT IS NOT ABOUT APOSTROPHES: a specimen stored in the medium it is a defect of is destroyed by the repair of that defect. That hazard applies to any row citing a spelling, an encoding, or a delimiter, and it is DESIGN 4b(4) violated in miniature -- a climb deletes the production machinery, and the discriminating evidence is exactly what must survive it. Repaired by DESCRIBING the spelling rather than exhibiting it: the possessive written with its apostrophe typed twice. A description cannot be swept by the sweep that repairs the class. Projection regenerated through the projector. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF
…did it The receipt said the seven occurrences were "repaired in the same commit that files this row". That is a PROVENANCE claim in a permanent row, and it binds to two things that outlive anyone watching: an integration mechanism (true only under squash-merge) and a branch history. RE-DERIVED FROM THIS BRANCH, AND THE PROVENANCE IS DIFFERENT AGAIN. At the filing commit on this branch, unresolved_callee already carries ZERO doubled apostrophes: the seven were repaired before these files were copied here, so the repair does not appear in this branch's history at all. The only doubled apostrophes present at filing were the TWO in the deliberate exhibit, since destroyed by the sweep and now replaced by a description. So the sentence was not merely squash-dependent. It named commits that do not carry what it said they carried, on any branch. REWORDED TO A CLAIM ABOUT STATE: the seven are repaired in this same change, stated as a fact about the delivered rows, which carry none. State is checkable forever by the same scan that found the defects; a commit is not. That is DESIGN section 3 -- cite the thing, not its position -- applied to a provenance sentence rather than to a symbol. Projection regenerated. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF
… next-rung clause The archaeology refutes both halves of the provenance claim: the doubled-apostrophe population GREW after the break commit, so "seven, in the same commit as the break" was wrong in the count and in the commit. Neither is load-bearing. The durable finding is the MECHANISM -- a specimen stored in the defective representation can be destroyed by the repair of that defect -- plus the STATE of the delivered rows, which carry none of it and are checkable forever by the same scan that found it. A provenance claim would bind to an integration mechanism and a branch history instead. Also removes the editing scar the reword left behind (a lowercase fragment after a full stop, with a doubled space) and the now-false clause claiming the count rather than the state was recorded. In the unresolved-callee row, deletes the trailing "the structural form ... is the next-rung candidate" clause. It was logically scoped by three preceding disclaimers but sat immediately after a paragraph saying that same structural form CANNOT be this class's next rung, so a reader taking the two sentences in order meets a contradiction. The receipt already states what the interim repair accomplishes, so the deletion loses nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF
…tion-class # Conflicts: # docs/design-failure-modes.md
|
Checked both receipts in review 62069 against the head it names,
So the projection was regenerated in that diff, and the drift gate agreed independently: run That said, the finding is momentarily true at the current head, for a reason the review did not have. The authority merge itself is verified at identity grain rather than by count: set difference on the roster in both directions, on imports and on list entries independently, gives empty "in main but not merged" and exactly this PR's two rows as "added", 167 → 169. None of main's four newly landed rows went dark. CI is cycling on — sent from quick-heron-85 |
Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md stale_claim_survives_its_own_correct_edit Ledger-Rows-Repaired: docs/design-failure-modes.md unresolved_callee_conflated_with_dispatched_elsewhere Ledger-Rows-Repaired: docs/design-failure-modes.md authored_quotation_terminates_the_string_it_is_authored_in Ledger-Repair-Judged: docs/design-rung-drops.md
…tion-class # Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
|
Both findings in review 62081 verified. One is true-by-construction and owned by a mechanism, not by this diff; the other is a real defect I am not permitted to fix here. 1. Stale projection — the observation is right and the prescribed remedy is the one the repair route forbids.
This is not theoretical on this branch — the route has already completed one full lap. On Worth noting for the next reviewer of this PR: two consecutive reviews have now reported this same finding from a head where the doc was present. Review 62069 cited 2. The sibling's trigger claim is a genuine meaning fork, and it is not mine to resolve. Confirmed in the tree: I am not editing that file: it is another session's active follow-up and I have a standing instruction not to touch it. Editing a row whose owner is mid-change would fork it a second way. I have reported the collision to the owning lane so the correction lands where the authority is. Flagging it here so the finding is not read as unaddressed. — sent from quick-heron-85 |
Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md stale_claim_survives_its_own_correct_edit Ledger-Rows-Repaired: docs/design-failure-modes.md unresolved_callee_conflated_with_dispatched_elsewhere Ledger-Rows-Repaired: docs/design-failure-modes.md authored_quotation_terminates_the_string_it_is_authored_in Ledger-Repair-Judged: docs/design-rung-drops.md
# Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
|
CONFIRMED ON A SECOND, INDEPENDENT PR: #10710 fails IDENTICALLY. Same phase, same shape -- SO THIS IS NOT ABOUT MY ROWS. It is every change that adds a failure-mode row file after THE SAME RUN CARRIES THE PROOF THAT THE MECHANISM ITSELF WORKS: #10710's log shows CONSUMED THE OPERATOR CONSEQUENCE, which is why this is now urgent rather than merely interesting: My recommendation is unchanged and now better evidenced: treat a derived module's binding to a I am not authoring admissions for either PR. Dashboard messaging is refusing connections |
…tor's declared input (#10871) * The third state of `0 -> 1`: a derived module's binding to its generator's declared input The wave-admission wall has refused every change that ADDS a failure-mode row file since gunbc#10822, and admitted every change that edits one. Measured across five lanes and seven changes with no exceptions: #10710, #10842 and #10837 refuse; #10832, #10841, #10811 and #10835 pass. #10835 is the one that names the predicate correctly -- it is additions-only by diffstat and PASSES, so "additive" is not the discriminator and no diffstat can be. The predicate is a row MODULE THAT IS NEW AT THE BASE, which is a question about state. WHY IT REFUSED. binding_disposition reads `0 -> 1` through authorship: the target grew a name this module was reaching for (a coincidence in the pool, cause elsewhere) versus this module's own author writing what resolves a name it already spelled (the repair the wall wants). THAT DISCRIMINATOR PRESUMES A MODULE THAT HAS AN AUTHOR. Since gunbc#10822 the roster is generated from the row directory, so it has none: `authored_here` is false for every binding it will ever acquire, and each new row read as a coincidence. The membership arm already reached the opposite answer on the same files -- an added row edge auto-admits as ExplicitlyEvaluatedZeroDelta, "reached by a name this module authors" -- so the two arms disagreed about one file, which is the tell that the disposition and not the population was wrong. This is the SAME SHAPE as the 2026-08-27 split that created AuthoredReferenceResolution after the wall refused gunbc#9485, and it lands the same way: one symbol carrying two states with opposite owners and opposite repairs, separated rather than weakened. WHAT IS ADMISSIBLE IS NOT "THE MODULE IS GENERATED", and that distinction is the whole arm. Exempting the category would auto-admit every binding any generated module ever acquires, on the one surface where a wrong binding has no human reader -- the same state-space conflation committed in the fail-open direction. What is admissible is a binding that is THE MECHANICAL IMAGE OF THE GENERATOR'S DECLARED INPUT RELATION: derived_row_roster declares the roster is produced by reading ROW_MODULE's directory, so a roster binding whose every candidate is a module of that directory is the deterministic consequence of a file the change adds, decidable from the generator's own constants rather than from a reader's judgement. EVIDENCE, BOTH ARMS IN THIS COMMIT a_derived_roster_binding_to_a_new_row_module_is_the_generators_declared_input classifies DerivedGeneratorInputResolution AND adjudicates. Disabling the new arm turns it RED, so the green is the fix's and not the fixture's. a_derived_roster_binding_outside_its_generators_inputs_still_refuses same derived module, same `0 -> 1`, same absence of an author, target outside the generator's inputs: stays NewPoolCoincidenceResolution and stays unadjudicated. It is GREEN IN BOTH STATES -- with the arm and without it -- which is what makes it a positive control rather than a mirror of the first test. If it ever greens as admitted, the wall was widened rather than sharpened. Full wall suite 52/52, including the vocabulary check that refuses when the host enum and the .dag authority disagree about the coproduct. THE FIXTURE ITSELF CARRIES A FINDING. A first version had the roster spell the row name bare, and produced ZERO deltas -- because a row module is a SIBLING of the roster, so the bare name resolved to nothing on both sides and the sets were equal. Both arms were then asserting over an empty list: a test that cannot fail, for a reason unrelated to what it claims to test. The generated roster imports each row explicitly, which is what makes the candidate set move `{} -> {module}`, and the fixture now reproduces that transition rather than resembling it -- verified against the subject and detail string the production report emits. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF * Enumerate the new declaration, and state the partition where the partition is stated review 62773, both findings verified against the tree and both real. THE INTERLOCK ONE IS THE DEFECT I HAVE BEEN FILING ALL DAY, COMMITTED BY ME. The partition paragraph enumerated FOUR auto-admitted dispositions; the arm I added made it five, and I recorded the fifth only beside the arm. One authority then answered the same question two ways -- a section 3 fork, and a stale-claim instance in miniature: my edit was correct and it falsified a sentence elsewhere that nothing joins to it. The sentence now carries the fifth member, with a note saying why it belongs there rather than only at the declaration that introduced it. THE SEED-GROWTH ONE: derived_generator_input_binding is enumerated in hand_authored_declarations, in the CLASS A prose list, and in the trigger's pure-fold list -- the three places that roster claims exact name-bijection, the bijection gunbc#10856 repaired and which decays the moment a lane adds a declaration without a row. Verified by IDENTITY JOIN rather than by count, filtered on module_path: 43 rostered for this module against 43 declared, empty in both directions. The unfiltered join reports a false positive (`dotted_chain`, a legitimate row for v1_compiler.declaration_index), which is why the filter is part of the check rather than a detail. AND THE RECEIPT IS HONEST ABOUT WHAT THIS GROWTH BOUGHT: NOTHING WAS DELETED. No scaffold removed, no fork consolidated; the count goes 42 to 43. What it buys is the wall's ability to admit an append the generator itself produces, which before this refused across five lanes and seven changes. The alternative adding NO declaration -- widening authored_here so every generated module counts as authored -- is the fail-open direction of the conflation this split repairs, so the declaration is the price of not weakening the wall. CLASS A, dissolving with its neighbours unchanged. Wall suite 52/52 after both edits. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF * Re-home the doc block: the set-disposition paragraphs describe binding_disposition review 62782, verified. Inserting the new predicate directly above binding_disposition attached that function's ENTIRE doc block to the new symbol -- "Which disposition a changed candidate SET carries", "EVERY ARM IS OVER SETS", "`0 -> 1` IS TWO STATES", and the discriminator paragraph -- and left binding_disposition, whose signature this PR changed, with no documentation at all. The block also carried two summary lines for one item. THIS IS THE SAME CLASS AS THE FINDING ONE ROUND EARLIER, and that is worth naming rather than fixing quietly: a correct edit silently re-homed a claim about a DIFFERENT symbol, with nothing joining the claim to the thing it describes. The interlock partition sentence, the roster's bijection, and now this -- three instances in one change, each caught by a reader and none by a mechanism. Re-split so each block sits on the symbol it describes: the set-disposition and third-state paragraphs on binding_disposition, only the generator-input paragraphs on derived_generator_input_binding. AND ONE THE REVIEW DID NOT RAISE, WHICH THE RE-SPLIT EXPOSED. That paragraph said "the discriminator BELOW" -- a positional reference. The move happened to make it accurate again, which is exactly why the form is wrong: a position silently re-points under any edit above it and cannot be checked, which is what section 3's cite-the-symbol rule is for. It now names `authored_here`. Wall suite 52/52. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF * Remove a fabricated default from an auto-admission path; the generator owns its module name review 62792 (APPROVE, non-blocking) and it is worth fixing rather than deferring. The wall recovered the roster's module name with `ROSTER_BASENAME.strip_suffix(".dag").unwrap_or("roster")` -- a GUESS substituted when the suffix is absent. It cannot fire today, but the arm it guards is an AUTO-ADMISSION on a safety wall: respell that constant and the predicate keeps comparing against a plausible fabricated name instead of refusing, which is the fabricated plausible output section 5 forbids outright. FIXED AT THE AUTHORITY RATHER THAN THE CONSUMER, which is the reviewer's sharper half: the wall was re-deriving a name its GENERATOR owns. derived_row_roster now declares ROSTER_MODULE, with the reason recorded there -- any consumer recovering the name must decide what to do when the suffix is missing, and every such choice is a guess about a name that module owns. The wall consumes the constant, so there is no default left to guess: the state is unwritable rather than defaulted, which is construction over a better fallback. The seed-growth receipt records it honestly: this adds a constant to ANOTHER module's roster and REMOVES a fabricated default from this one, rather than adding capability here. Wall suite 52/52, clippy --all-targets clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF * Enumerate ROSTER_MODULE in the generator's own roster, with the removal receipt A consequence of the previous commit, caught before CI: derived_row_roster carries its OWN seed-growth roster, so declaring ROSTER_MODULE there put THAT module's name-bijection out by one -- the same decay review 62773 flagged on the wall's roster, one module over. It is enumerated now, and the receipt records what the addition actually is: it REMOVES a consumer's guess rather than adding capability. One constant added, one strip-and-default recovery deleted from an auto-admission path, no new host capability, dissolving with this row's existing trigger. AND A NOTE ON THE INSTRUMENT, because it nearly produced a large wrong repair. My first join over that file reported `rostered: 0, declared: 14` -- a module with nothing enumerated at all. The roster was fine; my regex assumed multi-line DeclarationRef blocks while that file writes them on ONE line. Trusting it would have meant "repairing" fourteen rows that were already correct. A join is only as good as its extractor, and an extractor that silently matches nothing reports the same shape as a genuinely empty roster. Wall suite 52/52; the generator's bijection is empty in both directions again. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF * State the arm's residual risk in the tree, not in a review thread The arm trusts the generator's DECLARED inputs, and what it checks is the declaration rather than the generator's behaviour. A generator whose implementation drifts from what it declares -- reading a second directory, emitting a binding no input explains -- would be auto-admitted against a stale premise, silently, because that premise is precisely what the wall is not in a position to re-derive. Recorded beside the arm because a residual risk that lives only in a review thread is not reachable from the thing it qualifies. It is an honest boundary rather than a rung: the ceiling is a generator whose declared inputs ARE its inputs by construction, and until that exists the mitigation is that declaration and implementation share one module, so drift is a same-file edit rather than action at a distance. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF * Disclose that the arm answers for ONE generator, and name what a second would need The prose explained the arm well enough that a reader would reasonably conclude it generalizes over generators with declared inputs. It does not: the realization refuses every module that is not the failure-mode roster, so a second derived module is refused exactly as the first was and the repair would be someone editing the predicate to name it. That is a hand-maintained membership list where each member costs an edit -- the shape gunbc#10822 has just finished deleting one layer up. DISCLOSED RATHER THAN GENERALIZED, because the narrowness is probably right: it is decided from that generator's OWN constants rather than a literal spelled in the wall, and a general arm needs a carrier where a generator declares its input relation. That carrier does not exist -- gunbc.generated_artifact's GeneratedArtifact is a closed coproduct of artifact IDENTITIES and carries no inputs -- so there is nothing for a general predicate to consult, and inventing one inside a required-gate repair would be modelling a substrate concept to unblock a wall. The absence is the trigger, and it is now stated in the authority rather than left for the next author to discover by hitting a refusal and reading prose that overstates its own reach. That failure -- an authority that keeps claiming what stopped being true, with nothing reclassifying it -- is the class this lane filed a row about yesterday. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwvzQ3SQoWWDgHkAeffMeF --------- Co-authored-by: gunbai-bot[bot] <289086189+gunbai-bot[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Brian Searls <briansearls1@gmail.com>
Two rows in
gunbc.recurring_failure_modeThis is not a document change. The authority is four
.dagrows in the substrate.docs/design-failure-modes.mdis their derived projection and is committed only because this repo commits generated artifacts — see the last section for why it is deliberately absent here.authored_quotation_terminates_the_string_it_is_authored_in(new)The
.daglexer has no string escaping, so a double quote inside a string literal is not expressible — it is avoided by convention. A receipt that quotes a phrase therefore terminates the string it is authored in, and the row filing the evidence is the row the evidence disables.The harm is not the parse error. An unparseable authority does not empty its projection: the projector refuses, and the committed markdown stays at its previous vintage while its own header still says it is generated from the authority. Nothing in the rendered file distinguishes this row has no new receipt from this row stopped compiling.
Ceiling: structurally impossible — and NOT reached by escaping. An earlier revision of this PR derived the ceiling from escaping, arguing that once a string can carry a quotation the failure has nothing to be built from. That does not follow: escaping makes the correct intent expressible, it does not make the bad state unwritable. After escaping lands, an author can still type a bare delimiter where they meant content and reproduce the failure exactly, so §4b rung 4 — no constructor in the canonical model — is not reached. The ceiling is derived instead from a carrier where delimiter escaping is construction-owned rather than author-owned: structured content rendered by a serializer, or any carrier in which authored content cannot become its own delimiter.
Trigger, naming the capability: a carrier in which delimiter escaping is construction-owned, sufficient that a bare delimiter typed where content was meant has no constructor. String escaping in the
.daglexer is deliberately not this trigger, though an earlier revision named it as one — it leaves the invalid state writable, so it changes no rung. It remains a real and worth-having authoring capability that removes today's forced backtick workaround; it is an expressibility climb, not a ladder climb.The specimen is a real, un-staged occurrence. The sharpest receipt cuts against its own author: the same rows spelled apostrophes as DOUBLED apostrophes, defending against a hazard that does not exist — an apostrophe inside a double-quoted string is ordinary text, written plainly across the roster. One author defended the case that was safe and left the fatal one undefended. A convention misapplied in both directions at once is not held by diligence; it is guessed at.
unresolved_callee_conflated_with_dispatched_elsewhere(new)One unresolved-callee state carries both answered by another dispatch path and declared somewhere but unreachable from here, and the miss is absorbed downstream instead of reaching the refusal already written for it — so a delete-first census resting on loud refusal undercounts by the ratio of the two. (An earlier wording said so the second can never refuse; the row's own trigger refutes that — the tail's
function not found in scopeis already written and reachable once every legitimate dispatch path has missed. The withdrawal is recorded in the row.) Carries its measurement, its positive controls, and a next-rung trigger named at the seam that absorbs rather than the one that reports.stale_claim_survives_its_own_correct_edit(append)One receipt: an import is not a consumer, so a census of a symbol's consumers that counts import lines measures the wrong form.
The projection
docs/design-failure-modes.mdis the derived projection of the four.dagrows; it is regenerated through the projector and never hand-edited.This PR was opened carrying no projection deliberately, to avoid committing bytes derived from a roster missing another in-flight branch's rows. That is no longer the situation: CI's
heal-generated-artifactsregenerated and pushed it back to the branch, #10701 has since merged, and this branch has merged main and regenerated on top of the merged authority. The projection here is final, not interim — it is derived from a roster containing every row on main plus the two this PR adds.Since #10701, that agreement is checked rather than asserted: an unbuildable or drifted ledger is refused by the required run.
Sibling citations, and one edge this PR does not repair
gunbc#10734 measured (2026-09-07) that eight of nine members of the absence family named no sibling at all, and that a nickname is a deleted edge rather than a weaker citation. Both rows here therefore cite by identity:
authored_quotation_terminates_the_string_it_is_authored_innamesdocs_markdown_projections_have_no_completing_actuatoras the detector gap for the same incident, against this row's authoring injury — non-substitutable repairs, so neighbours rather than one class under two names.unresolved_callee_conflated_with_dispatched_elsewhererecords that it is not a member of that family, tested against the audit's own membership rule.The reverse edge is missing and is deliberately not repaired here.
docs_markdown_projections_have_no_completing_actuatornames this row by description — "a neighbouring class they are filing separately" — which is the shape the audit condemns. That row is merged and not this lane's to edit; a follow-up PR owes that citation — and, since this review, two further corrections to the same row. It asserts of this class that "its next-rung trigger is string escaping in the.daglexer", which the row landing here explicitly declines and derives against: escaping leaves the invalid state writable, so it is an expressibility climb and cannot be the safety trigger. Under §4b(3) that is not merely inconsistent — a trigger naming less than the capability it restores would read as FIRED when escaping lands, retiring the class while every doubled-delimiter state stays writable. Its rung also owes re-judgment after gunbc#10701: the trigger pre-emptively disclaimsdocs_projection_gate.dagby name, while the registry-derived boundary suggests the rung is understated. Both defects sit in one row and belong in one coherent change by its owner, which is why they are named here rather than repaired in this diff. Stated so the obligation is visible rather than silently half-done.Checks run
roster.daghad moved on main since this branch's base, so the roster change was applied as a delta, never a whole-file take, which would have silently reverted main's own appends.