Repository navigation
A composition edge: two rostered absence classes firing in sequence - #10835
Conversation
A receipt on `predicate_vacuously_true_on_an_empty_domain`, filed as a follow-up rather than pushed onto an open PR at a decision gate. THE ROW'S TAXONOMY OF WHERE THE VACUOUS CASE COMES FROM -- "the end of a line, the end of a buffer, a remainder shorter than the window, an empty selection, the last chunk" -- is every entry a boundary of a REAL SEQUENCE that ran out. The second origin is not a boundary at all: THE READ FAILED. That is a swallowed error wearing a boundary's shape, and no care about sequence ends anticipates it. SPECIMEN, measured. A verification script required every sentence an authority GAINED between two commits to appear in the regenerated projection -- a sound check, carrying a negative control. It was pointed at a SHA that did not exist, because that SHA had been ASSERTED IN A MESSAGE RATHER THAN READ BACK FROM THE PRODUCER. Re-derived on the same nonexistent SHA: `git show` writes ZERO BYTES and exits 128. The reader ignored the exit code and returned "", the splitter produced the empty set, and "every sentence appears" held vacuously and reported all authored content present. Zero versus zero compares equal. IT IS A CHAIN OF TWO ROSTERED CLASSES, which is why it is one receipt with a cross-link and not two rows. `empty_capture_read_as_clean_result` fired FIRST and says why the set was empty -- a failed read consumed as content, the same shape as its own `gh run view` specimen. This row fired SECOND and says why empty produced PASS. Two guards, each defective in a way the other made invisible. WHERE IT APPEARS is the transferable part: exactly when verifying an artifact identity you were TOLD rather than READ. A fabricated, stale or mistyped identity does not fail at the verifier -- it fails at the read, silently, and reaches the predicate as an empty domain indistinguishable from a real one. The repair is two cheap obligations: assert on the read so a failed fetch refuses instead of returning empty, and carry a positive control so a non-discriminating matcher cannot report a pass. Verified: projection regenerated, and re-running the generator on the committed tree leaves no diff. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MuB8wHjijaFwNoyzm78stF
briansrls
left a comment
There was a problem hiding this comment.
Exact-head review of cd9b6e7: REQUEST_CHANGES.
The causal decomposition is good: empty_capture_read_as_clean_result explains why the downstream set became empty; predicate_vacuously_true_on_an_empty_domain explains why that manufactured empty set then produced PASS. One receipt with a cross-link is the right shape; I do not want two new failure-mode rows.
Three content corrections are required.
-
The novelty claim is historically false against the row being amended. The existing
predicate_vacuously_true_on_an_empty_domainauthority already carries an explicit upstream-failure generator, in nearly the exact distinction this PR claims is absent:THE EMPTY DOMAIN PRODUCED BY AN UPSTREAM FAILURE RATHER THAN BY A BOUNDARY IN THE DATA, including a failed shell extraction whose empty output made a verification join pass vacuously. SoA BOUNDARY SOURCE THIS ROW DOES NOT LIST/AN EMPTY DOMAIN HAS A SECOND ORIGINcannot stand as the contribution. Reframe this as a NEW SPECIMEN / narrower subcase of the already-recorded upstream-failure origin: an artifact-identity read refused, its refusal was dropped, and the resulting empty capture fed the vacuous predicate. The two-class chain may be new evidence even though the origin category is not. -
WHERE IT APPEARS ... exactly when VERIFYING AN ARTIFACT IDENTITY YOU WERE TOLD RATHER THAN READis too narrow and not causal. A producer-read identity can later fail to resolve because the object vanished, the repository/context changed, permissions changed, or the read itself refused.told rather than readis a useful hazard source for fabricated/stale/mistyped identities, but the class boundary is: a refusing read is collapsed to empty content and that content is then consumed by a predicate whose empty-domain answer is acceptance. State the message-supplied identity as this specimen's producer of the bad read, not the exact recurrence surface. -
carry a positive control ... this catches every other originweakens the existing row's actual capability. A synthetic positive control can prove that the matcher is capable of matching while the REAL checked domain is still empty; it does not establish a denominator for the subject being certified. The existing row already has the stronger trigger: a POSITIVE DENOMINATOR on every completion/coverage predicate. Keep the two obligations at different grains: assert/read-success closes this failed-read origin; establish a positive denominator on the actual checked domain closes vacuity regardless of origin. If the proposed positive control is itself a guaranteed member of the actual domain, say that explicitly and treat it as the denominator rather than as a generic matcher control.
The measured git show <unknown rev> shape (zero stdout, exit 128) supports the specimen, and the exit-code guard is the right repair for the first class. The current two-file scope and projection regeneration are otherwise coherent.
Current main is bd1603f, exactly this PR's base, so there is no integration freshness issue at review time. Exact-head CI is still in progress and remains a separate gate. No merge action taken.
…erified The reviewer found that this receipt's PREMISE was historically false, and it was: the row already owns the upstream-failure generator, at sentence 166 on origin/main, in stronger words than the receipt proposed -- "A SECOND AND WORSE GENERATOR ... THE EMPTY DOMAIN PRODUCED BY AN UPSTREAM FAILURE RATHER THAN BY A BOUNDARY IN THE DATA" and it already carries a failed-read instance. So "a boundary source this row does not list" and "an empty domain has a second origin" are false and are removed, along with every sentence resting on them. HOW THE FALSE PREMISE GOT IN, recorded in the receipt rather than fixed silently: its author grepped this row for ONE SENTENCE -- the taxonomy line -- and reasoned about the row from it, having never read the row. That is the artifact-verification defect rostered at `green_reported_over_a_population_the_instrument_does_not_own`, committed while filing a receipt about verification. WHAT SURVIVES, each checked against origin/main before being re-asserted rather than taken on report: THE LOCUS is new. The generator paragraph describes a pipeline STAGE failing open. Here nothing failed -- the pipeline was pointed at a subject that did not exist, a SHA asserted in a message rather than read back from the producer. `git show` on it writes zero bytes and exits 128. The locus is: verifying an artifact identity you were TOLD rather than READ. THE CHAIN is new. `empty_capture_read_as_clean_result` is named nowhere in this row (checked), and the generator paragraph describes emptiness arising WITHIN one procedure rather than handed across a class boundary. AND THE REPAIR IS CORRECTED TO THIS ROW'S OWN DOCTRINE, which the first draft contradicted. "Assert the read succeeded" is the artifact-grained guard this row has refused twice already -- one more guarded site, validation, the empty state still in the procedure. The construction- grained repair at this locus is to stop accepting a TOLD identity: resolve the subject from its producer, so a name denoting nothing cannot enter and the empty domain has no constructor from this origin. The positive control stays, orthogonal, because it covers every other origin. Verified: regen clean, and re-running the generator on the committed tree leaves no diff. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MuB8wHjijaFwNoyzm78stF
… fork it The reviewer's full decomposition against current main: one thing survives, two do not. SURVIVES -- THE COMPOSITION EDGE. Main already owns the general sequence (an upstream failure manufactures an empty domain, a downstream universal certifies it). What it does not say is that on this measured incident the two legs have DIFFERENT rostered owners firing in sequence: `empty_capture_read_as_clean_result` owns the refusing read consumed as content, this row owns the universal over the resulting empty domain. Two rostered classes composing is a RELATION, not another class. DOES NOT SURVIVE -- the artifact-identity subcase. It explains why THIS read refused; it changes no mechanism, recognition rule or repair, and wrong paths, wrong windows and refusing reads are already covered. The bad SHA stays as specimen provenance only. DOES NOT SURVIVE -- the novelty claim, withdrawn in the previous commit. WHICH ABSENCE ROW OWNS LEG ONE is now stated, because three absence rows touch this incident: the discriminator is whether the read SIGNALLED failure. Exit 128 is a swallowed refusal, which is `empty_capture_read_as_clean_result`. `absent_reads_identically_to_never_looked` is the case where nothing errors and the instrument never reached its subject -- which is why its specimens are a wrong path, a wrong window and a wrong directory rather than a non-zero exit. THE SECOND OBLIGATION IS CITED, NOT RE-DERIVED, and the earlier wording was weaker than the rule it paraphrased. "A positive control catches every other origin" is false: a matcher can pass a synthetic control while the actual checked domain stays empty, since the control proves only that the MATCHER discriminates. The correct obligation is a POSITIVE DENOMINATOR ON THE ACTUAL DOMAIN -- already rostered as `absent_reads_identically_to_never_looked`'s tell, and already this row's own next-rung trigger. Restating it here would have forked a repair that has an authority. AND THE SPLIT IS ONLY HONEST WITH THIS SAID: either guard alone would have prevented this exact false pass. Both are required to repair the COMPOSED CHAIN rather than this instance -- the first preserves and LOCATES the original fault, the second closes vacuity from every other origin. One hole closable twice, and a chain needing both ends held. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MuB8wHjijaFwNoyzm78stF
briansrls
left a comment
There was a problem hiding this comment.
Exact-head review of 5a164b2: REQUEST_CHANGES.
The aggressive reduction is the right direction, and I do think one thing survives: the measured COMPOSITION EDGE. This incident specifically traverses the narrower empty_capture_read_as_clean_result mechanism first (refusing read, empty stdout consumed as content) and then predicate_vacuously_true_on_an_empty_domain second (empty sentence set makes the universal pass). Recording that sequential composition is a relation between existing classes, not a new class, and is not already stated at that exact grain on current main.
Three corrections remain.
-
The proposed discriminator between
empty_capture_read_as_clean_resultand its parentabsent_reads_identically_to_never_lookedis false. The parent is NOT thenothing errorscase: current main explicitly includes loud abort/panic/non-zero-exit specimens whose failure is then filtered into apparent absence.empty_capture_read_as_clean_resultitself declares that it is a specialization ofabsent_reads_identically_to_never_looked. So do not claim exit-signalled-failure as an exclusive class boundary. State instead that THIS specimen matches the narrower specialization's specific mechanism — a refusing read whose empty captured bytes were consumed as a result — while the broader parent also owns the general unreached/read-as-absence family. -
Obligation (2) should cite the vacuity row's OWN positive-denominator trigger as its authority.
absent_reads_identically_to_never_lookeddoes mention a denominator/positive control as ways to establish that its instrument resolved its subject, but that is not the same guarantee aspositive denominator on the ACTUAL CHECKED DOMAINfor the downstream vacuity predicate. The receipt can cite the parent for the first-leg family relation; it should not borrow the parent's reachability tell as authority for the second-leg repair. -
The PR title still carries the novelty claim the body and authority correctly withdrew:
An empty domain has two origins, and only one of them is a boundary. Current main already has the upstream-failure origin, so the title is historically false. Rename the PR to the surviving subject — the measured composition of two rostered absence/vacuity classes — rather than leaving the superseded premise as the highest-salience surface.
The either guard alone prevents this exact false pass; both ends are required to repair the composed chain paragraph is sound and should remain after correction 2.
Exact-head workflow 34227695290 is in progress at review time; CI is separate. No merge action taken.
…own trigger Two of the three findings are corrections to claims this receipt asserted about other rows without reading them. (1) THE DISCRIMINATOR WAS FALSE. The receipt said the boundary between `absent_reads_identically_to_never_looked` and its specialization is WHETHER THE READ SIGNALLED FAILURE, with the parent as the no-error case. THE PARENT'S OWN TEXT REFUTES IT: it carries arms that are LOUD -- "ALL THREE ARMS ARE LOUD -- stderr, non-zero exit" -- and its sharper statement is that THE SILENCE WAS MANUFACTURED BY THE READER'S FILTER. The false boundary came from reading three specimen LABELS instead of the row, which is this ledger's own artifact-verification defect committed against its own roster, for the second time on this PR. The actual relation is SPECIFICITY, and the specialization states it itself: `empty_capture_read_as_clean_result` is a specialization of that parent, narrowed to the mechanism where the refusal is well-formed and honest and simply travels on a CHANNEL NOBODY KEPT. This specimen matches that narrower mechanism -- exit 128 on a channel the reader discarded -- so it is cited to the specialization because the specialization is more specific, NOT because a test separates the classes. (2) THE CITATION TARGET WAS WRONG. Obligation (2) was cited to `absent_reads_identically_to_never_looked`. It belongs to THIS row's own next-rung trigger, which already names the positive denominator as its capability. The parent's denominator-and-control language establishes THAT THE READER REACHED ITS SUBJECT -- a different fact, at a different point in the pipeline, from THE NON-EMPTINESS OF THE DOWNSTREAM PREDICATE'S ACTUAL CHECKED DOMAIN. Collapsing them is how one obligation gets taken for the other and neither gets built. The either-guard-alone distinction is unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MuB8wHjijaFwNoyzm78stF
briansrls
left a comment
There was a problem hiding this comment.
Exact-head review of a600f2b: APPROVE on content.
All three prior blockers are closed. The PR title now names only the surviving subject: a measured composition edge between two existing rostered classes. The authority no longer invents an error/no-error discriminator between empty_capture_read_as_clean_result and its parent absent_reads_identically_to_never_looked; instead it records the parent’s own loud/non-zero specimens and cites the specialization because this incident matches its narrower mechanism. That is the correct parent/specialization relation.
The second repair obligation is also now grounded at the right authority: predicate_vacuously_true_on_an_empty_domain owns the positive-denominator capability for the downstream checked domain. The receipt explicitly distinguishes that from the parent absence row’s reachability/observation discipline, so the two pipeline obligations are no longer collapsed.
The composition receipt itself remains worth keeping: failed/refusing read consumed as content first, vacuous universal over the manufactured empty domain second. Neither new class nor artifact-identity subcase is claimed. The statement that either guard would prevent this exact false pass while both capabilities are needed to hold both ends of the broader composed failure remains appropriately scoped.
Current main is bd1603f, exactly this PR's base. Exact-head workflow 34229262118 is still pending at review time; CI remains a separate gate. No merge action taken.
…rojection #10822 made recurring-failure-mode membership the row DIRECTORY and stopped committing docs/design-failure-modes.md, which is exactly the shared append region this branch kept conflicting on. Resolution accepts the deletion: this branch's whole contribution is 8 added lines in the row file itself, which is now the only place the class is filed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MuB8wHjijaFwNoyzm78stF
…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>
What
One receipt appended to
gunbc.recurring_failure_mode.predicate_vacuously_true_on_an_empty_domain, plus its regenerated projection. No new class, and — after a full decomposition against current main — substantially less than this PR originally claimed.What this PR originally claimed, and why it was false
It asserted that the row's taxonomy listed only boundaries of real sequences and that an upstream-failure origin was a gap. That is historically false. The row already carries, at sentence 166:
— in stronger words than the receipt proposed, and with a failed-read instance of its own. The premise was reached by grepping one sentence of the row rather than reading it: the artifact-verification defect rostered at
green_reported_over_a_population_the_instrument_does_not_own, committed while filing a receipt about verification. It is withdrawn, and the withdrawal is recorded in the row rather than applied silently.What survives: a composition edge
Main owns the general sequence. What it does not say is that on this measured incident the two legs have different rostered owners firing in sequence:
empty_capture_read_as_clean_resultgit show <unknown revision>exited 128 with empty stdout; the exit status was discarded and the empty bytes consumed as contentNeither class alone explains the incident. Two rostered classes composing is a relation, not another class.
Why leg one is cited to the specialization rather than its parent — and an earlier draft of this PR got the reason wrong. It claimed the boundary was whether the read signalled failure, with
absent_reads_identically_to_never_lookedas the no-error case. That is false, and the parent's own text refutes it: it carries arms that are loud — "ALL THREE ARMS ARE LOUD — stderr, non-zero exit" — and its sharper statement is that the silence was manufactured by the reader's filter. The false boundary came from reading three specimen labels instead of the row.The actual relation is specificity, stated by the specialization itself:
empty_capture_read_as_clean_resultis a specialization of that parent, narrowed to the mechanism where the refusal is well-formed and honest and simply travels on a channel nobody kept. This specimen matches that narrower mechanism — exit 128 on a channel the reader discarded — so it is cited to the specialization because the specialization is more specific, not because a test separates the classes.What does not survive
The two obligations — one of them cited, not re-derived
Preserve or refuse the failed read — inspect the exit status so an upstream fault cannot become content.
Require a positive denominator on the actual checked domain. An earlier draft said "a positive control catches every other origin", which is false: a matcher can pass a synthetic control while the checked domain stays empty, since the control proves only that the matcher discriminates.
The receipt cites this row's own next-rung trigger, which already names the positive denominator as its capability — every completion or coverage predicate requiring one, so a zero-size population refuses as not-yet-started rather than passing as settled. It deliberately does not cite
absent_reads_identically_to_never_looked, as an earlier draft did: that row's denominator-and-control language establishes that the reader reached its subject, which is a different fact at a different point in the pipeline from the non-emptiness of the downstream predicate's actual checked domain. Collapsing the two is how one obligation gets taken for the other and neither gets built.And the split is only honest with this said: either guard alone would have prevented this exact false pass. Both are required to repair the composed chain rather than this instance — the first preserves and locates the original fault, the second closes vacuity from every other origin. One hole closable twice, and a chain needing both ends held.
Verification on this head
docs_projection_gate --function regen— clean.Both instruments, because neither subsumes the other:
Fixed point — re-ran the generator on the committed tree and required no diff;
git status --porcelainempty. Proves the projection is what this generator produces from this tree. Misses a generator that deterministically drops content.Authored-delta arrival — diffed the authority across the commit, extracted the 19 sentences it gained, and required each present in the projection: 19/19, zero missing, with a fabricated sentence confirmed absent as the negative control. Proves the authored content reached the artifact a reader consumes. Misses anything outside the delta.
🤖 Generated with Claude Code
https://claude.ai/code/session_01MuB8wHjijaFwNoyzm78stF