diff --git a/dag/gunbc/recurring_failure_mode/a_written_row_is_not_a_firing_mechanism.dag b/dag/gunbc/recurring_failure_mode/a_written_row_is_not_a_firing_mechanism.dag new file mode 100644 index 00000000000..b39f70ee92a --- /dev/null +++ b/dag/gunbc/recurring_failure_mode/a_written_row_is_not_a_firing_mechanism.dag @@ -0,0 +1,14 @@ +module gunbc.recurring_failure_mode.a_written_row_is_not_a_firing_mechanism + +import std.types { NonEmptyStr } +import gunbc.recurring_failure_mode { RecurringFailureMode } + +data a_written_row_is_not_a_firing_mechanism: RecurringFailureMode = RecurringFailureMode { + identity: "a_written_row_is_not_a_firing_mechanism" as NonEmptyStr, + + receipts: [ + "**a written rule is how a LATER READER learns what happened; it is not how a PRESENT AUTHOR is stopped, so a ledger that grows without changing what is easy to type buys documentation and no prevention** (INVALID STATE: a failure class is answered by APPENDING A ROW -- to this roster, to a stall roster, to an annotation -- and the row is then counted as the remedy. The class recurs anyway, because at the moment of authoring the dangerous form is still the shortest thing to type and nothing costs more when it is chosen. RECOGNITION RULE, which is the whole row: after filing, ask WHAT IS NOW HARDER TO DO THAN IT WAS BEFORE. If the honest answer is nothing, the filing was a RECORD and not a REPAIR, the class rung did not move, and it must be reported as UNREMEDIED rather than as covered. WHY IT IS NOT MERELY WEAK BUT ACTIVELY MISLEADING: a filed class gets CITED AS COVERAGE, so a reviewer meeting it reads it as handled and the filing converts an open deficit into a closed-looking one while leaving the deficit exactly where it was -- a DESIGN section 4b(1) rung wearing a 4b(2) costume, which is this ledger own version of rung inflation. An unrepaired filing is therefore WORSE than no filing, not equal to it. WHY THE RECALL DOES NOT FIRE: a rule filed under its SUBJECT MATTER is retrieved by thinking about that subject matter, and an author executing a step attends to THE GOAL, not the class of the step. Nothing in `retire the superseded poller` cues `I am about to type a pattern that can match myself`. THE TEST RUN ON A REAL POPULATION THE SAME NIGHT IT WAS WRITTEN, AND IT CAME BACK MOSTLY NEGATIVE: across ten class-filings required in one day, the identity-join rows made nothing harder (`sort -u` is exactly as easy to type as `sort`); the prose-adjacency, field-adjacency and digest-beside-subject rows made nothing harder (no lens refuses a digest passed beside its subject, and that signature is still the natural one to write); the empty-reading rows made nothing harder (the short read is still shorter than the head-filtered one, which is precisely why four people reached for it). ONE of the ten changed what is easy, and IT WAS NOT A FILING: a schema hazard was answered by computing the affected population and commenting on each of the five pull requests about to hit it, delivering friction to five named authors rather than prose to a ledger. A second was initially scored as a climb and the correction is the sharper result: the carrier ALREADY HAD THE RIGHT SHAPE and nothing about it was built that day; what the day produced was the DISCOVERY that a wrong thing was writable beside it, because an author wrote a fabricated previous-rung into a drop row, A REGEN RAN GREEN OVER IT, and a reader happened to look at the field. NO MECHANISM WAS WATCHING. Corrected score: ONE push-friction instance that expires when five pull requests land, ZERO climbs, ONE discovery -- and the discovery is the least repeatable item in the list, since the next occurrence is written where nobody is reading and the green regen is identical. A LUCKY READ IS NOT COVERAGE. THE TWO KINDS OF FRICTION ARE NOT INTERCHANGEABLE AND ONLY ONE COMPOUNDS: PUSH friction is delivered to named authors at the moment of impact and EXPIRES when their changes land; PULL-PROOF friction removes the constructor, so nothing needs delivering to anyone ever again. A day producing one of each must not report two. THE CONCLUSION THE AUDIT FORCES, STRONGER THAN THIS ROW STARTED: retrieval-by-recall is not a mechanism that becomes adequate at a smaller ledger size -- IT IS THE WRONG MECHANISM AT ANY SIZE, because the retrieval cue never arrives regardless of how few rows there are. Every row real deliverable is THE FRICTION, and the prose is its RECEIPT rather than its product. RUNG FOUND AT: mitigatable, and this row is an instance of what it describes, which is why it carries a trigger rather than resting on having been written. CEILING: structurally impossible for any class whose dangerous form can be removed from the vocabulary entirely -- an unwritable form needs no rule. NEXT-RUNG TRIGGER, a capability and not an artifact: for each filed class, a named ARTEFACT OF FRICTION -- a lens that refuses the shape, a carrier with no unsafe constructor, a wrapper shorter to invoke than the raw form -- so that a filing arrives WITH a change in what is easy, and the obligation is symmetric: whoever ASKS for a row owes the friction artefact or the plain sentence that nothing got harder and the class stands UNREMEDIED.)", + ], + + evidence: [], +} diff --git a/dag/gunbc/recurring_failure_mode/ceiling_never_exercised_for_a_population_the_census_cannot_plan.dag b/dag/gunbc/recurring_failure_mode/ceiling_never_exercised_for_a_population_the_census_cannot_plan.dag new file mode 100644 index 00000000000..2aa9ba63de1 --- /dev/null +++ b/dag/gunbc/recurring_failure_mode/ceiling_never_exercised_for_a_population_the_census_cannot_plan.dag @@ -0,0 +1,14 @@ +module gunbc.recurring_failure_mode.ceiling_never_exercised_for_a_population_the_census_cannot_plan + +import std.types { NonEmptyStr } +import gunbc.recurring_failure_mode { RecurringFailureMode } + +data ceiling_never_exercised_for_a_population_the_census_cannot_plan: RecurringFailureMode = RecurringFailureMode { + identity: "ceiling_never_exercised_for_a_population_the_census_cannot_plan" as NonEmptyStr, + + receipts: [ + "**a bound is never EVALUATED for a whole population, so the first unrelated edit that makes one of them run discovers the line as a merge block** (INVALID STATE: an identity that the ordinary floor never plans is subject to a ceiling that has therefore never been exercised against it. Specimen: `test.claim.witness_floor_workflow_consolidation_witness_test.w_RED_fabric_evidence_executes_without_gating` has ZERO planned rows on main -- checked in the `required-floor-claim-cost` artifact of two consecutive main runs, 0 of 3549 -- because it executes ONLY as a CHANGED witness. Its 500ms CPU line was first exercised by gunbc#9725, a change about the wet execution route, which touched `gunbc.witness_floor_workflow` and thereby made the witness changed; it refused at 504ms and 505ms on two heads. HARM: the discovering PR is not the causing PR in any sense its author can act on. The block arrives on a change that has nothing to do with cost, the author has no baseline to compare against because none was ever produced, and the only available dispositions are to enroll a debt row or to stall. THE NEIGHBOUR THIS IS NOT, and the distinction is the whole row: the NEAR-LINE family says a bound is MISPLACED -- measured over the whole corpus by the FLOOR-COST-500MS lane, 21 of the ~29 identities that can approach the line at all sit within +/-10% of it with nothing beyond 541ms, so the threshold was drawn through a cluster. This row says a bound was NEVER EVALUATED for a population at all. Different invalid state, different trigger, and the repairs diverge: a per-witness declared cost envelope fixes the misplaced line, and does NOT by itself cause the ceiling to be exercised for identities the ordinary floor does not plan. WHY IT IS STRUCTURALLY INVISIBLE TO THE OBVIOUS INSTRUMENT: a census that samples what the ordinary floor PLANS has this population outside its denominator BY CONSTRUCTION -- the cost lane's own survey could not see the class, and found it only when a lane that had tripped the line reported it. This is [[green_reported_over_a_population_the_instrument_does_not_own]] in the cost dimension: the survey was accurate about the rows it enumerated and silent about the rows it could not. RECOGNITION RULE: when a bound is declared per-identity but enforcement is gated on a SELECTION (changed, affected, sampled, scheduled), ask WHICH IDENTITIES THE SELECTION NEVER SELECTS ON THE MAINLINE. Those carry unevaluated bounds, and the population is discoverable in advance -- it is the declared identities minus the planned ones, both of which are already published per run. NEXT-RUNG TRIGGER, a capability and not an artifact: the ceiling is EXERCISED AND ITS RESULT PUBLISHED for every identity carrying one, including those the ordinary floor does not plan -- sufficient that a bound's first contact with an identity is a measurement someone chose to take, not a merge block on an unrelated change. Until then the class is discovered one PR at a time by whoever happens to edit the triggering authority. RUNG FOUND AT: mitigatable, and the mitigation is a debt row written after the fact. CEILING: mechanically preventable -- the unplanned population is a decidable set difference over data each run already emits.)", + ], + + evidence: [], +} diff --git a/dag/gunbc/recurring_failure_mode/closure_subject_with_no_enumerable_membership.dag b/dag/gunbc/recurring_failure_mode/closure_subject_with_no_enumerable_membership.dag new file mode 100644 index 00000000000..40851071175 --- /dev/null +++ b/dag/gunbc/recurring_failure_mode/closure_subject_with_no_enumerable_membership.dag @@ -0,0 +1,14 @@ +module gunbc.recurring_failure_mode.closure_subject_with_no_enumerable_membership + +import std.types { NonEmptyStr } +import gunbc.recurring_failure_mode { RecurringFailureMode } + +data closure_subject_with_no_enumerable_membership: RecurringFailureMode = RecurringFailureMode { + identity: "closure_subject_with_no_enumerable_membership" as NonEmptyStr, + + receipts: [ + "**a subject defined by a CLOSURE with no enumerable membership cannot be protected in advance, only violated in arrears** (INVALID STATE: a receipt, cache key, or admission is pinned to a digest computed over a TRANSITIVE CLOSURE -- here the wet lane's `semantic_subject`, over the per-entry closure of 23 routed witness entries plus `v2.workflow.floor_wet_route`. The digest is a perfectly good detector and a useless protector: it reports a MISMATCH AFTER THE FACT rather than a MEMBERSHIP LIST BEFORE it. HARM: a two-hour dispatch completed and its receipt arrived uncommittable as `ReceiptSubjectDifferent`, because a commit landed inside the closure after the run's head. The lane that would break such a subject cannot decide for itself whether its diff intersects one, so the only available discipline is asking the holder afterwards -- which is not a discipline, it is a post-mortem. THE VISIBLE SURFACE IS NOT THE SUBJECT, and reporting it as one is the same defect in a different costume: the wet subject's visible surface is 19 files, while the resolver's own lines report 47 modules and 1180 resolved items for ONE entry, reaching transitively into `src/v2/std/` and `src/v2/compiler/`. A lane can invalidate the receipt while touching none of the 19 and doing nothing wrong. A list handed a completeness property by the mere fact that it is a list is the trap; the resolver's numbers are what refute it, which is why they are quoted rather than estimated. THE CONSEQUENCE FOR ANNOUNCEMENTS, recorded because it is the half that fools the announcer: a hold announced over an unenumerable subject is not protection, and the artifact recording that the announcement happened is indistinguishable from the protection existing. A hold nobody can check is WORSE than no hold, because its holder then treats the subject as protected. SCOPE, and it is wider than the specimen: EVERY subject-pinned receipt in this repository has this hole; the others have not noticed because none has yet burned a long run to it. RECOGNITION RULE: when a digest pins a subject, ask WHETHER ANYTHING PRINTS THE SUBJECT'S MEMBERSHIP. If the only instrument that knows the membership is the comparison itself, the subject is detectable and not defendable, and any fence described over it is a request rather than a constraint. NEXT-RUNG TRIGGER, a capability and not an artifact: a producer that PRINTS the closure membership for a routed entry, SUFFICIENT that a lane can decide FOR ITSELF, BEFORE LANDING, whether its diff intersects a live subject. THE POINTED PART, CORRECTED ONCE ALREADY AND THE CORRECTION IS THE WHOLE VALUE: the set is not merely computed and discarded, it is COMPUTED, HELD, AND RETURNED TO THE CALLER. In `v1_compiler.claim_batch` `resolve_timed`, the resolved graph is bound, its `modules` and `item_registry` are read for their LENGTHS to print the `[resolve]` line, and the whole graph is then handed back to the caller. Nothing is thrown away except THE NAMES, and only at the `eprintln!`. So the missing thing is an EMITTER over a set the process already holds and the caller already receives -- not an analysis, not a resolver change. THIS DISTINCTION IS THE ROW'S RUNG HONESTY AND 4b(2) TURNS ON IT: `nobody can determine this in advance` and `nobody has printed it` are different claims. The first is a permanent ceiling under which every future lane pays the same cost again; the second is an unbuilt next rung one emitter away. Filed as the former this row would sound honest and be wrong, and would foreclose its own repair -- which is this very class applied to our own tooling, a claim about a population made by an instrument that never enumerated it. RUNG FOUND AT: mitigatable, and the mitigation is a message. CEILING: mechanically preventable -- membership is decidable and computed, but a lane's intersection with a LIVE subject depends on which runs are in flight, which is external state observed at a boundary.)", + ], + + evidence: [], +} diff --git a/dag/gunbc/recurring_failure_mode/content_digest_makes_annotations_semantically_load_bearing.dag b/dag/gunbc/recurring_failure_mode/content_digest_makes_annotations_semantically_load_bearing.dag new file mode 100644 index 00000000000..f96200fc8a7 --- /dev/null +++ b/dag/gunbc/recurring_failure_mode/content_digest_makes_annotations_semantically_load_bearing.dag @@ -0,0 +1,14 @@ +module gunbc.recurring_failure_mode.content_digest_makes_annotations_semantically_load_bearing + +import std.types { NonEmptyStr } +import gunbc.recurring_failure_mode { RecurringFailureMode } + +data content_digest_makes_annotations_semantically_load_bearing: RecurringFailureMode = RecurringFailureMode { + identity: "content_digest_makes_annotations_semantically_load_bearing" as NonEmptyStr, + + receipts: [ + "**a subject digest taken over RAW FILE CONTENT makes annotations semantically load-bearing, which is the property DESIGN section 4c declares impossible** (INVALID STATE: a receipt, cache key or admission is pinned to a digest computed by `v1_compiler.resolved_graph_cache` `closure_content_digest`, which folds each source's `content` -- the authored bytes -- rather than anything the annotation-erased projection would produce. So ADDING, DELETING OR REFLOWING A COMMENT in a module inside such a subject moves the digest. 4c states the opposite in terms: annotation capture is disjoint from semantic occurrence allocation, and adding, deleting or moving an annotation cannot alter any semantic occurrence identity, semantic graph, resolution result, SEMANTIC HASH, or target-program bytes. HARM, MEASURED RATHER THAN IMAGINED: on gunbc#9725 the wet lane's semantic subject folds `v2.workflow.floor_wet_route`'s own closure content, a receipt from a 2h31m dispatch was pinned to that digest, and an operator-granted one-shot lease pinned the same value as `exact_semantic_subject_digest`. Repairing a one-word COMMENT in that module would have voided the grant and forced a re-dispatch plus a second operator grant. Three real defects were therefore repaired in the seed and left standing in the substrate authority, which is filed separately as `gunbc.guarantee_stall` `wet_route_model_lags_seed_stall`. The next occurrence will not be so visible: someone reflows a paragraph and silently invalidates a receipt with no diagnostic connecting the two. THE DISJUNCTION, because only one of these can be true and neither is currently written down. EITHER the closure content digest is NOT a semantic hash in 4c's sense -- in which case it must stop being read as one, and the distinction between a CONTENT identity (what bytes were on disk) and a SEMANTIC identity (what program they denote) has to be authored somewhere a reader meets before pinning anything to it. OR 4c's guarantee genuinely does not hold for this carrier, and 4c is overclaiming for every consumer that digests sources rather than the erased projection. RECOGNITION RULE: when a digest is described as a subject, a semantic subject, or a program identity, ask WHAT IT FOLDS. If the answer is file content, then comments, whitespace and formatting are inside it, and every guarantee stated about annotations being semantically inert is false of that digest -- while reading exactly like a guarantee about the program. The tell is a digest whose name says semantic and whose producer takes `content`. NEXT-RUNG TRIGGER, a capability and not an artifact: a subject digest folded over the ANNOTATION-ERASED projection that semantic passes already receive -- the same erasure 4c requires those passes to consume -- so that the digest is invariant under comment edits by construction and 4c's guarantee is true of it rather than merely stated near it. Failing that, the weaker form: the content digest is RENAMED to say it is a content identity and every pinning consumer is re-read against that meaning. RUNG FOUND AT: mitigatable, and the mitigation is that authors happen to know. CEILING: structurally impossible -- an erased-projection digest cannot move on an annotation edit, because the annotation is not in the input.)", + ], + + evidence: [], +} diff --git a/dag/gunbc/recurring_failure_mode/per_argument_exhaustive_matrix_blind_to_a_cross_argument_relation.dag b/dag/gunbc/recurring_failure_mode/per_argument_exhaustive_matrix_blind_to_a_cross_argument_relation.dag new file mode 100644 index 00000000000..f43c600deae --- /dev/null +++ b/dag/gunbc/recurring_failure_mode/per_argument_exhaustive_matrix_blind_to_a_cross_argument_relation.dag @@ -0,0 +1,14 @@ +module gunbc.recurring_failure_mode.per_argument_exhaustive_matrix_blind_to_a_cross_argument_relation + +import std.types { NonEmptyStr } +import gunbc.recurring_failure_mode { RecurringFailureMode } + +data per_argument_exhaustive_matrix_blind_to_a_cross_argument_relation: RecurringFailureMode = RecurringFailureMode { + identity: "per_argument_exhaustive_matrix_blind_to_a_cross_argument_relation" as NonEmptyStr, + + receipts: [ + "**a per-argument exhaustive matrix cannot see a cross-argument relation, and it READS as exhaustive precisely because it is** (INVALID STATE: a gate function takes two independently derived arguments -- here `wet_route_gate_disposition(standing:admission:)`, whose `standing` came from one receipt envelope and whose `admission` came from a lease pinned to a DIFFERENT envelope. Every arm of `admission` was enumerated and refused correctly for that argument in isolation; every arm of `standing` likewise. The reachable OFF-DIAGONAL state -- lease-admits-A composed with standing-derived-from-B -- inhabits no single argument, so no per-argument enumeration contains it. HARM: the author reports the enumeration as complete, and the report is TRUE. That is what makes this worse than a false completeness claim: a false one is refuted by any counterexample within its stated domain, while a true one over an UNSTATED domain has no counterexample inside the domain it names, so the reader cannot separate `all cases of the argument` from `all cases of the decision`. SPECIMEN (gunbc#9725): five refusal arms of the bootstrap-lease admission were each shown going red under mutation, and `six arms of one argument is not the gate; the gate is the relation between two` was the correction. The repair was structural rather than another arm -- FUSE THE DOOR: the gate no longer accepts a pre-computed admission, it derives the admission itself from the envelope it is judging, so the mismatched pair has no constructor. RECOGNITION RULE: when a matrix is enumerated per argument, ask WHICH RELATIONS BETWEEN ARGUMENTS THE FUNCTION SIGNATURE ADMITS. If two parameters can be derived from different subjects, the product space -- not the union of the axes -- is the domain, and an axis-wise sweep is exhaustive over a projection of it. The tell is a decision function whose arguments are each independently derivable by a caller. THE NEIGHBOUR THIS IS NOT: [[check_subject_narrower_than_its_declared_claim]] is a subject mismatch that a reader can catch by comparing the claim to the check; here the claim and the check agree exactly, and the narrowing is in the DOMAIN both of them share. NEXT-RUNG TRIGGER, a capability and not an artifact: deriving a decision's dependent inputs INSIDE the decision rather than accepting them, wherever two parameters name the same subject -- which is the fused-door move generalized, and makes the off-diagonal unconstructible instead of merely unenumerated. RUNG FOUND AT: mechanically preventable, by a probe that had to be written to construct the state. CEILING: structurally impossible, and reached for this specimen.)", + ], + + evidence: [], +} diff --git a/dag/gunbc/recurring_failure_mode/roster.dag b/dag/gunbc/recurring_failure_mode/roster.dag index 6f407f96f98..369ce7ad8a3 100644 --- a/dag/gunbc/recurring_failure_mode/roster.dag +++ b/dag/gunbc/recurring_failure_mode/roster.dag @@ -97,6 +97,12 @@ import gunbc.recurring_failure_mode.exact_duplicate_match_arm_not_refused { exac import gunbc.recurring_failure_mode.premise_that_a_shared_subject_means_disagreement { premise_that_a_shared_subject_means_disagreement } import gunbc.recurring_failure_mode.live_argument_threaded_past_the_arm_that_decides { live_argument_threaded_past_the_arm_that_decides } import gunbc.recurring_failure_mode.check_subject_shape_cannot_represent_the_state_the_check_detects { check_subject_shape_cannot_represent_the_state_the_check_detects } +import gunbc.recurring_failure_mode.per_argument_exhaustive_matrix_blind_to_a_cross_argument_relation { per_argument_exhaustive_matrix_blind_to_a_cross_argument_relation } +import gunbc.recurring_failure_mode.closure_subject_with_no_enumerable_membership { closure_subject_with_no_enumerable_membership } +import gunbc.recurring_failure_mode.ceiling_never_exercised_for_a_population_the_census_cannot_plan { ceiling_never_exercised_for_a_population_the_census_cannot_plan } +import gunbc.recurring_failure_mode.content_digest_makes_annotations_semantically_load_bearing { content_digest_makes_annotations_semantically_load_bearing } +import gunbc.recurring_failure_mode.subject_and_its_digest_as_independent_parameters { subject_and_its_digest_as_independent_parameters } +import gunbc.recurring_failure_mode.a_written_row_is_not_a_firing_mechanism { a_written_row_is_not_a_firing_mechanism } data recurring_failure_mode_roster: List = [ censored_estimator_drops_its_own_tail, @@ -185,4 +191,10 @@ data recurring_failure_mode_roster: List = [ premise_that_a_shared_subject_means_disagreement, live_argument_threaded_past_the_arm_that_decides, check_subject_shape_cannot_represent_the_state_the_check_detects, + per_argument_exhaustive_matrix_blind_to_a_cross_argument_relation, + closure_subject_with_no_enumerable_membership, + ceiling_never_exercised_for_a_population_the_census_cannot_plan, + content_digest_makes_annotations_semantically_load_bearing, + subject_and_its_digest_as_independent_parameters, + a_written_row_is_not_a_firing_mechanism, ] diff --git a/dag/gunbc/recurring_failure_mode/subject_and_its_digest_as_independent_parameters.dag b/dag/gunbc/recurring_failure_mode/subject_and_its_digest_as_independent_parameters.dag new file mode 100644 index 00000000000..ffa56614bc9 --- /dev/null +++ b/dag/gunbc/recurring_failure_mode/subject_and_its_digest_as_independent_parameters.dag @@ -0,0 +1,14 @@ +module gunbc.recurring_failure_mode.subject_and_its_digest_as_independent_parameters + +import std.types { NonEmptyStr } +import gunbc.recurring_failure_mode { RecurringFailureMode } + +data subject_and_its_digest_as_independent_parameters: RecurringFailureMode = RecurringFailureMode { + identity: "subject_and_its_digest_as_independent_parameters" as NonEmptyStr, + + receipts: [ + "**a value and a summary of it -- a digest, a count, a view, an annotation -- placed side by side without a join can disagree silently, and the corroboration the reader believes they are getting was never computed** (INVALID STATE: a signature takes a value AND a summary of that value as two peer arguments -- `envelope` beside `envelope_digest`, `roster_identities` beside `roster_digest` -- with no arm relating them. The signature admits a digest of something OTHER than the value beside it; nothing refuses; and every downstream guarantee that cites the digest is then citing a summary of a different object, while reading exactly like a guarantee about the value. DISTINGUISHING FACTS: the two arguments are supplied by the same caller from the same site TODAY, so the pairing is held by lexical proximity rather than by anything the type system or a fold can see; the defect is constructible without touching a single caller, by supplying a correct digest of a different subject. EVIDENCE, TWO INSTANCES IN ONE MODULE, which is what makes it a class rather than a coincidence: `v2.workflow.floor_wet_route` `wet_route_gate_disposition_for_receipt` carries BOTH the envelope/digest pair and the roster-identities/roster-digest pair. The first was demonstrated live -- `v2.test.floor_wet_route` `wet_lease_admits_an_envelope_whose_content_the_digest_does_not_name` constructs an envelope whose content the pinned digest does not name, and the lease gate ADMITS. THE SAME DEFECT READ FROM THE OTHER END: agreement among derived views is vacuous when the views share one reader. A projection was nearly shipped with a row silently deleted because FOUR derived views agreed, all fed by a single reader -- one source feeding many views made agreement carry no information, exactly as a digest and its subject being independent lets them disagree unnoticed. THE THIRD FACE, AND THE ONE THAT SURVIVED REVIEW LONGEST: PROSE ADJACENCY IS NOT A JOIN EITHER. `wet_route_identity_rows_block_with_publication` carried an annotation stating that EXACTLY TWO per-identity classes are waived under a valid publication transaction, three lines above a body that returned false unconditionally and waived FOUR -- so `no_verdict`, the ABSENCE of a verdict, was converted into a green merge path. The prose and the code disagreed by a factor of two IN THE SAME FUNCTION and FOUR APPROVALS READ PAST IT. An annotation is not checked against the body it sits above by anything: it READS as documentation and FUNCTIONS as an assertion, and by DESIGN section 4c no `Accepted` program can read one, so nothing in the toolchain will ever disagree with it. Provider count is not attention -- four approvals is not four readings of that function. AND FIELD ADJACENCY IS NOT A JOIN EITHER, which is the same claim one scale down: in `v1_compiler.bin.claim_batch`'s two pre-execution refusal arms the annotation two lines above `WetReceiptIdentityRow` was RIGHT, and the neighbouring fields `observed_entry_rel` and `observed_function` were RIGHT -- Optional, and correctly None on exactly those arms -- and `wall_ms`, two fields later in the SAME STRUCT LITERAL, fabricates a 0 for a duration nothing measured. PROXIMITY TO A CORRECT THING IS NOT CORRECTNESS: a reader scanning that literal gets three signals of care and one fabrication, with nothing in the text distinguishing them. And 0 is the WORST available fabricated value for that field rather than a neutral placeholder, because it is THE FASTEST OBSERVABLE EXECUTION -- so a consumer that averages, thresholds or ranks on wall_ms without first branching on the outcome wire reads the ABSENCE of a measurement as the BEST measurement in the corpus. An anomalous-looking fabrication is found by whoever first sorts the column; this one sorts to the top and is found by nobody. All three faces are one defect: A JOIN THAT WAS NEVER MADE, so the corroboration a reader believes they are getting was never computed. RECOGNITION RULE: whenever a parameter list contains a value and a summary, hash, count, digest or identity OF that value, ask what refuses when they disagree. If the answer is nothing, the summary is unverified input wearing the costume of a derived fact. The mirror question for agreement: when N sources agree, ask how many INDEPENDENT reads produced them; if the answer is one, the agreement is a copy agreeing with itself. THE REPAIR, already built once and therefore not speculative: DERIVE THE DIGEST FROM THE VALUE AT THE POINT THE VALUE IS OBTAINED, NEVER ACCEPT IT AS A PEER PARAMETER. The seed`s `read_wet_receipt_envelope` now returns the decoded envelope and the digest of the bytes it decoded FROM, in one call, so the two cannot name different objects; its control `carried_digest_names_the_bytes_the_envelope_was_decoded_from` rewrites the file between reads and asserts the carried digest still names its own bytes. RUNG FOUND AT: mitigatable -- a comment and a caller convention. CEILING: structurally impossible, because a digest produced by the same operation that produces the value has no constructor that lets it name a different one. NEXT-RUNG TRIGGER, a capability: a carrier type that pairs a value with a digest DERIVED at construction, so no signature anywhere can accept the two separately -- the `.dag` instances named in `gunbc.guarantee_stall` `wet_route_model_lags_seed_stall` are the population that trigger retires.)", + ], + + evidence: [], +} diff --git a/docs/design-failure-modes.md b/docs/design-failure-modes.md index 72bb67a2359..49b3104759e 100644 --- a/docs/design-failure-modes.md +++ b/docs/design-failure-modes.md @@ -90,6 +90,12 @@ The exact `RecurringFailureMode.identity` population, which no other projection - `premise_that_a_shared_subject_means_disagreement` - `live_argument_threaded_past_the_arm_that_decides` - `check_subject_shape_cannot_represent_the_state_the_check_detects` +- `per_argument_exhaustive_matrix_blind_to_a_cross_argument_relation` +- `closure_subject_with_no_enumerable_membership` +- `ceiling_never_exercised_for_a_population_the_census_cannot_plan` +- `content_digest_makes_annotations_semantically_load_bearing` +- `subject_and_its_digest_as_independent_parameters` +- `a_written_row_is_not_a_firing_mechanism` --- @@ -191,3 +197,9 @@ The landing measurement partitions the 31 parser-visible identities into **2 cit - **A PREMISE THAT MAKES A COST LOOK CORRECT RENDERS THE REGION BEHIND IT UNEXAMINABLE, AND THE TELL IS REPEATED REPAIRS THAT ALL STOP AT THE SAME BOUNDARY.** The invalid state is a stated justification -- not a check, not a type -- that classifies an observed cost as intended, so no instrument is ever pointed at it and its absence looks like the absence of a problem rather than the absence of a measurement. SPECIMEN, and it is this carrier's own history: `gunbc.recurring_failure_mode` was repaired twice for merge contention -- blob to `data` rows, then rows to one line each -- and BOTH repairs measured only the APPEND OF A WHOLE ROW. Both rested on a premise stated in the first: that two lanes editing the SAME class conflicting is "correct, because that is real disagreement about one fact." THE PREMISE IS FALSE FOR THIS CARRIER, and the discriminator is what actually accretes on a class. What lands is INDEPENDENT RECEIPTS from unrelated lanes -- a second specimen, a climb receipt, a corroboration reached from the opposite direction -- not competing claims about one fact. On 2026-09-02/03 three lanes appended three independent receipts to `state_space_conflation` and resolved it by hand-negotiating byte order; that row reached 23,023 characters. Independent accretion is not disagreement, so the conflict was textual contention wearing the mask the premise had fitted for it. **WHAT MAKES THIS A CLASS RATHER THAN ONE MISTAKE IS THE SHAPE OF THE EVIDENCE: the premise was load-bearing for two repairs, and neither repair's author looked inside a row.** A false premise does not merely produce a wrong answer -- it produces NO answer, because it removes the question. That is why it survived a measurement campaign that was otherwise careful: the same lane that measured `git merge-file` at a named merge base to characterise the block-tail defect never measured an intra-row edit, because the premise said the result would be correct. RECOGNITION RULE: when a repair of a recurring cost is being scoped, find the sentence that explains why the ADJACENT cost is acceptable, and ask what measurement would falsify it. If no measurement was ever run against it -- and especially if the same boundary has now been re-approached more than once -- the premise is a candidate, not a finding, and the cheap discriminator is to run the instrument the premise made look unnecessary. Here that was one `git merge-file` on two lanes editing one row: 0 conflicts on different receipts, 1 minimal conflict on two appends. **WHAT IS NOT CLAIMED.** This is not the claim that stated justifications are suspect in general, which would be unusable. The class is narrower and its two conditions are jointly required: a premise that classifies an observed, RECURRING cost as intended, AND a repair history in which the same boundary was approached more than once without that cost being measured. One repair stopping at a boundary is ordinary scoping. RUNG: mitigatable, and honestly so. The harm is deferred author time -- three lanes hand-negotiating byte order on one row -- and it is contained only by someone eventually re-deriving the premise, which is a review practice and not a mechanism. CEILING, derived rather than aspirational: this cannot climb to construction, because whether a stated justification is true is not decidable from the tree -- the premise here was refuted by an empirical fact about how lanes ACTUALLY append, which no property of the source expresses. It is a ratchet forever in the sense of DESIGN section 5. NEXT-RUNG TRIGGER, a capability and not an artifact: the ability to measure contention on a carrier CONTINUOUSLY rather than at repair time -- a per-declaration conflict count over merge history -- so that a region the premise renders unexaminable still produces a number that rises. That is what would have made the intra-row cost visible without anyone doubting the sentence. - **a live argument threaded past the arm that actually decides the verdict** (INVALID STATE: a check is named and cited as LIVE because one of its arguments is read from the real tree, while the predicate it asserts is already settled by a different, hand-authored argument that the live one cannot influence -- so the live input is threaded into a call whose answer does not depend on it. HARM: the row is permanently green with respect to the tree it claims to observe, and its name is what a reader consults when asking whether the class is covered live, which is exactly the decoration DESIGN section 4b calls worse than absent because it will be cited as coverage. It also BUYS THE COST OF LIVENESS WITHOUT THE SIGNAL -- the live producer here is a whole-tree fill -- so the row looks expensive enough to be doing something. DISTINGUISHING FACT, and it is what separates this from an ordinary weak assertion: THE DECIDING ARM AND THE LIVE ARM ARE DISJOINT INPUTS TO ONE TOTAL FUNCTION, so nothing at the call site looks wrong; every argument is well-typed, the live producer is genuinely called, and the fixture argument is genuinely a fixture. The tell is structural and mechanical -- find the arm that can produce the asserted outcome ALONE, and ask whether the live argument is an input to it. SPECIMEN, gunbc 2026-09-03: v2.test.claim.long.effect_reach_test effect_reach_live_03_normalize_witness_derived_host_reading_holds asserted v2.lens.effect_reach derived_host_reading over effect_reach_classification_from_facts with decls bound to v2.std.fn_index fn_arrow_decl_facts_live and data_inits bound to a hand-authored one-element live_03_normalize_data_inits. In that function the data-init arm closure_data_init_path_flows consumes only closure_modules and data_inits: a path-shaped literal_fp in any closure module yields a GunbcCompileEntrySink flow with no reachability and no decls, and any non-empty flow list is HostEffectReach, hence derived_host_reading. The module also carried an annotation asserting that this row LEGITIMATELY READS the live producer, so the false claim was stated in prose beside the code that falsified it. DISCRIMINATING RED AND POSITIVE CONTROL, BOTH EXECUTED rather than argued, via claim_batch on the lens: substituting decls to the EMPTY list while holding the hand data_inits fixed leaves derived_host_reading TRUE -- the live argument is non-discriminating; and holding the LIVE decls while substituting data_inits to EMPTY yields derived_host_reading FALSE with effect_reach_flow_count 0 -- the live scan contributes ZERO flows from this entry, so the row had no live content at all rather than merely a weak one. The unmodified row PASSES, which is the positive control that the harness and the lens were both working. THE PAIR IS THE METHOD AND NOT AN INCIDENT OF THIS SPECIMEN: neither substitution alone decides the question, because a passing empty-decls arm is consistent with the live arm merely being redundant, and only the second substitution shows it was empty. RESOLUTION AND WHY IT IS A DELETION: the row was removed rather than renamed, because its deciding arm was already enrolled over the identical literal_fp as effect_reach_path_data_init_derived_host_reading_holds in the same module, so a rename would have kept a DESIGN section 2 duplicate spelled with real module names; and no live row is authorable on that lens today, since its closure comes from ModuleImportFact, which v2.lens.live_read_classification g2_live_production_boundary_law declares FIXTURE-FACING with no live producer in the corpus. THE SHAPE OF THE MISTAKE IS AUTHORABLE BEFORE THE PRODUCER EXISTS, which is why the name of the missing producer is the trigger and not the excuse. RUNG FOUND AT: 1, mitigatable -- nothing silent is produced, the row simply asserts less than its name, and the only thing containing the harm is that a reader may read the call. CEILING: 2, mechanically preventable. The question -- does the asserted outcome change when this argument is replaced by its type identity or an empty value -- is decidable by EXECUTION per argument and is exactly the coverage-is-per-argument grain, but it is not derivable from the call shape alone, because whether an argument is influential depends on the callee body over the actual fixture values. Not higher: a caller may pass any well-typed value to any parameter and forbidding a non-influential argument would forbid ordinary total functions, so the invalid state stays writable. NEXT-RUNG TRIGGER, named as the capability and covering BOTH directions: a per-argument influence check that, for each argument of an enrolled witness call, re-executes the witness with that argument substituted and refuses when the verdict is unchanged for an argument the row NAMES -- sufficient for reddening both a non-discriminating live argument and a row whose live arm contributes nothing, since the specimen needed both substitutions to be characterised. A convention that live rows must be named live would be satisfied while the capability stayed dead. BOUNDARY against neighbouring classes: check_subject_narrower_than_its_declared_claim is about a subject that is a strict subset of what the row claims to range over, and the repair there is widening the subject; here the subject is right and one INPUT is inert, and the repair is either removing the inert input or supplying the producer the name promises. It is likewise not incidental_denominator_as_wall, which is about the wall being computed over the wrong population. AND IT IS SHARPER THAN THE ASSERTED-NOT-PRODUCED SHAPE IT MOST RESEMBLES, which is the reason it is filed rather than folded in: there the producer is IMPORTED AND UNCALLED, so the tell is visible at the call site -- a hand-built value stands where a produced one should. HERE THE PRODUCER IS GENUINELY CALLED and its result is genuinely passed, and what fails is REACHABILITY INSIDE THE CALLEE, so no reading of the call site can see it and the tell is only recoverable from the callee's arm structure or from substitution. THE GENERAL FORM IS WORTH MORE THAN ANY ONE ROW: a verdict DISJOINED over a live arm and a fixture arm silently becomes the fixture arm, and nothing goes red, because the disjunction is satisfied before the live arm is consulted. BOUNDARY against the three adjacent roster rows, none of which is this: absorbing_fallback is a FAILURE arm that widens instead of refusing, and here no arm fails at all -- the wrong answer is a TRUE one reached without the input it names; empty_observation_narrow is a CENSUS whose population is narrower than its claim, where the subject is the defect, while here the subject is right and one input is inert; and predicate_vacuously_true_on_an_empty_domain is green because its domain is EMPTY, whereas this predicate ranges over a perfectly non-empty fixture domain and is simply not a function of the argument the row is named for. The repairs are disjoint in all three directions, which is DESIGN section 4b's keying-on-the-repair test.) - **a lens is correct and live over a subject shape that cannot represent the state it detects** (a check reaches its subject, executes on every run, and is enrolled as coverage -- and its RED is UNAUTHORABLE there, because the representation the subject is expressed in has no constructor for the state the check matches on. Nothing is skipped, nothing is absorbed, no population is withheld, and the check is not wrong: hand it a value of the shape it expects and it fires correctly. It is the SUBJECT that cannot carry the state, so the check is permanently green over that subject while reading as verified. **THE BOUNDARY AGAINST check_subject_narrower_than_its_declared_claim DECIDES THE REMEDY AND THEY ARE NOT THE SAME DEFECT.** There the subject is a SMALLER POPULATION than the claim -- widen it and the missing instances appear, so the repair is a scope edit. Here the population is exactly right and every member is structurally incapable of exhibiting the state; widening adds more members that equally cannot exhibit it, so a scope edit is guaranteed to change nothing while looking like a fix. It is also NOT absorbing_fallback: nothing widens on failure and no arm degrades -- the check runs its ordinary path to an honest verdict over a subject that could only ever produce one answer. **SPECIMEN WITH A RECEIPT, measured 2026-09-03 on gunbc#10245 against origin/main 8b2323f414 and reproduced on 8bfae78d78.** v2.lens.determinism classifies a call through node_callee_symbol, which requires node_is_call, which matches ComputationNode { behavior: Transform }. Its live subject is the fn-arrow body skeletons built by v1_compiler.coproduct_reflection marshal_skeleton, which returns conj_record at both return sites, i.e. TypeNode { connective: Conj }, for EVERY node. A Conj TypeNode cannot satisfy that match, so no skeleton node is ever a call, every body classifies Deterministic by non-membership, and determinism_transitive_holds over a fn_arrow_decl_facts_live population is green by construction. The same mismatch holds four production_qualification_origin_probe_witness frontier rows red, which is what makes it a class rather than an incident: one representation mismatch darkens every consumer of that subject at once. **WHY IT SURVIVES REVIEW, and this is the dangerous part.** The check is real, the lens is correct, the subject is live and non-empty, and a positive control asserting the population is non-empty PASSES -- so every ordinary vacuity guard agrees. A NON-EMPTY SUBJECT IS A NECESSARY PRECONDITION MASQUERADING AS THE CHECK. Nine approving reviews passed over the specimen and none exercised the body skeletons; it was found by planting a violation and watching nothing happen. **THE BOUNDARY AGAINST live_argument_threaded_past_the_arm_that_decides, filed the same day and easy to conflate with this.** There the check CAN go red -- a different, hand-authored argument decides the verdict and the live argument is threaded past it, so the row is inert with respect to the tree while the predicate itself still discriminates. Here NO argument can produce the refused state, because the subject's representation cannot express it; there is no other arm carrying the verdict, and substituting inputs changes nothing. The two are distinguished by one question: is there an arm that could produce the asserted outcome alone? If yes and the live input is not one of its inputs, that is the threaded-argument class and the remedy is to delete or re-source the row. If no arm can produce the refused outcome at all, this is the class and the remedy is a representation change, which is why its trigger names a shape rather than a call site. **RECOGNITION RULE, which is DESIGN 4b's own question asked BEFORE the check is written rather than after: name the state the check refuses, then construct a value in the subject's OWN representation that exhibits it.** If you cannot construct one, the check is a decoration over that subject however correct its logic. The construction is cheap and is the whole test: two values differing only in the field the check keys on, asserting it FIRES on one and is BLIND to the other. Both arms passing is the executing record of the gap; when the representation lands, the blind arm reds and names itself. **THE REPORTING RULE THAT FOLLOWS: a class's rung is the minimum across its in-scope paths (4b(1)), so a fixture path where the RED is authorable does NOT stand in for a live path where it is not.** Citing the fixture rung while the live path is dark is rung inflation. **AND IT IS NOT A 4b(3) DECLARED DROP -- filing one is its own error**, which is where the specimen nearly went: 4b(3) governs a REGRESSION, with a previous rung and a population that LOST a guarantee. When the shape mismatch predates the check, the wall was never lit through that path, and a capability that was never real cannot be dropped. The honest instruments are 4b(1) rung honesty and 4b(2) an untracked stall made tracked. **RUNG: 1 (mitigatable) -- the gap is nameable and, once found, held open by the two-arm control. CEILING: 4, since whether a subject's representation can inhabit the state a check matches on is decidable from two declarations the tree already carries. NEXT-RUNG TRIGGER, a CAPABILITY and not an artifact: a check declares the subject representation it matches over, and a check whose match is unsatisfiable by that representation fails to compile -- so the decoration cannot be authored at all, rather than being found later by someone constructing the value by hand.**) +- **a per-argument exhaustive matrix cannot see a cross-argument relation, and it READS as exhaustive precisely because it is** (INVALID STATE: a gate function takes two independently derived arguments -- here `wet_route_gate_disposition(standing:admission:)`, whose `standing` came from one receipt envelope and whose `admission` came from a lease pinned to a DIFFERENT envelope. Every arm of `admission` was enumerated and refused correctly for that argument in isolation; every arm of `standing` likewise. The reachable OFF-DIAGONAL state -- lease-admits-A composed with standing-derived-from-B -- inhabits no single argument, so no per-argument enumeration contains it. HARM: the author reports the enumeration as complete, and the report is TRUE. That is what makes this worse than a false completeness claim: a false one is refuted by any counterexample within its stated domain, while a true one over an UNSTATED domain has no counterexample inside the domain it names, so the reader cannot separate `all cases of the argument` from `all cases of the decision`. SPECIMEN (gunbc#9725): five refusal arms of the bootstrap-lease admission were each shown going red under mutation, and `six arms of one argument is not the gate; the gate is the relation between two` was the correction. The repair was structural rather than another arm -- FUSE THE DOOR: the gate no longer accepts a pre-computed admission, it derives the admission itself from the envelope it is judging, so the mismatched pair has no constructor. RECOGNITION RULE: when a matrix is enumerated per argument, ask WHICH RELATIONS BETWEEN ARGUMENTS THE FUNCTION SIGNATURE ADMITS. If two parameters can be derived from different subjects, the product space -- not the union of the axes -- is the domain, and an axis-wise sweep is exhaustive over a projection of it. The tell is a decision function whose arguments are each independently derivable by a caller. THE NEIGHBOUR THIS IS NOT: [[check_subject_narrower_than_its_declared_claim]] is a subject mismatch that a reader can catch by comparing the claim to the check; here the claim and the check agree exactly, and the narrowing is in the DOMAIN both of them share. NEXT-RUNG TRIGGER, a capability and not an artifact: deriving a decision's dependent inputs INSIDE the decision rather than accepting them, wherever two parameters name the same subject -- which is the fused-door move generalized, and makes the off-diagonal unconstructible instead of merely unenumerated. RUNG FOUND AT: mechanically preventable, by a probe that had to be written to construct the state. CEILING: structurally impossible, and reached for this specimen.) +- **a subject defined by a CLOSURE with no enumerable membership cannot be protected in advance, only violated in arrears** (INVALID STATE: a receipt, cache key, or admission is pinned to a digest computed over a TRANSITIVE CLOSURE -- here the wet lane's `semantic_subject`, over the per-entry closure of 23 routed witness entries plus `v2.workflow.floor_wet_route`. The digest is a perfectly good detector and a useless protector: it reports a MISMATCH AFTER THE FACT rather than a MEMBERSHIP LIST BEFORE it. HARM: a two-hour dispatch completed and its receipt arrived uncommittable as `ReceiptSubjectDifferent`, because a commit landed inside the closure after the run's head. The lane that would break such a subject cannot decide for itself whether its diff intersects one, so the only available discipline is asking the holder afterwards -- which is not a discipline, it is a post-mortem. THE VISIBLE SURFACE IS NOT THE SUBJECT, and reporting it as one is the same defect in a different costume: the wet subject's visible surface is 19 files, while the resolver's own lines report 47 modules and 1180 resolved items for ONE entry, reaching transitively into `src/v2/std/` and `src/v2/compiler/`. A lane can invalidate the receipt while touching none of the 19 and doing nothing wrong. A list handed a completeness property by the mere fact that it is a list is the trap; the resolver's numbers are what refute it, which is why they are quoted rather than estimated. THE CONSEQUENCE FOR ANNOUNCEMENTS, recorded because it is the half that fools the announcer: a hold announced over an unenumerable subject is not protection, and the artifact recording that the announcement happened is indistinguishable from the protection existing. A hold nobody can check is WORSE than no hold, because its holder then treats the subject as protected. SCOPE, and it is wider than the specimen: EVERY subject-pinned receipt in this repository has this hole; the others have not noticed because none has yet burned a long run to it. RECOGNITION RULE: when a digest pins a subject, ask WHETHER ANYTHING PRINTS THE SUBJECT'S MEMBERSHIP. If the only instrument that knows the membership is the comparison itself, the subject is detectable and not defendable, and any fence described over it is a request rather than a constraint. NEXT-RUNG TRIGGER, a capability and not an artifact: a producer that PRINTS the closure membership for a routed entry, SUFFICIENT that a lane can decide FOR ITSELF, BEFORE LANDING, whether its diff intersects a live subject. THE POINTED PART, CORRECTED ONCE ALREADY AND THE CORRECTION IS THE WHOLE VALUE: the set is not merely computed and discarded, it is COMPUTED, HELD, AND RETURNED TO THE CALLER. In `v1_compiler.claim_batch` `resolve_timed`, the resolved graph is bound, its `modules` and `item_registry` are read for their LENGTHS to print the `[resolve]` line, and the whole graph is then handed back to the caller. Nothing is thrown away except THE NAMES, and only at the `eprintln!`. So the missing thing is an EMITTER over a set the process already holds and the caller already receives -- not an analysis, not a resolver change. THIS DISTINCTION IS THE ROW'S RUNG HONESTY AND 4b(2) TURNS ON IT: `nobody can determine this in advance` and `nobody has printed it` are different claims. The first is a permanent ceiling under which every future lane pays the same cost again; the second is an unbuilt next rung one emitter away. Filed as the former this row would sound honest and be wrong, and would foreclose its own repair -- which is this very class applied to our own tooling, a claim about a population made by an instrument that never enumerated it. RUNG FOUND AT: mitigatable, and the mitigation is a message. CEILING: mechanically preventable -- membership is decidable and computed, but a lane's intersection with a LIVE subject depends on which runs are in flight, which is external state observed at a boundary.) +- **a bound is never EVALUATED for a whole population, so the first unrelated edit that makes one of them run discovers the line as a merge block** (INVALID STATE: an identity that the ordinary floor never plans is subject to a ceiling that has therefore never been exercised against it. Specimen: `test.claim.witness_floor_workflow_consolidation_witness_test.w_RED_fabric_evidence_executes_without_gating` has ZERO planned rows on main -- checked in the `required-floor-claim-cost` artifact of two consecutive main runs, 0 of 3549 -- because it executes ONLY as a CHANGED witness. Its 500ms CPU line was first exercised by gunbc#9725, a change about the wet execution route, which touched `gunbc.witness_floor_workflow` and thereby made the witness changed; it refused at 504ms and 505ms on two heads. HARM: the discovering PR is not the causing PR in any sense its author can act on. The block arrives on a change that has nothing to do with cost, the author has no baseline to compare against because none was ever produced, and the only available dispositions are to enroll a debt row or to stall. THE NEIGHBOUR THIS IS NOT, and the distinction is the whole row: the NEAR-LINE family says a bound is MISPLACED -- measured over the whole corpus by the FLOOR-COST-500MS lane, 21 of the ~29 identities that can approach the line at all sit within +/-10% of it with nothing beyond 541ms, so the threshold was drawn through a cluster. This row says a bound was NEVER EVALUATED for a population at all. Different invalid state, different trigger, and the repairs diverge: a per-witness declared cost envelope fixes the misplaced line, and does NOT by itself cause the ceiling to be exercised for identities the ordinary floor does not plan. WHY IT IS STRUCTURALLY INVISIBLE TO THE OBVIOUS INSTRUMENT: a census that samples what the ordinary floor PLANS has this population outside its denominator BY CONSTRUCTION -- the cost lane's own survey could not see the class, and found it only when a lane that had tripped the line reported it. This is [[green_reported_over_a_population_the_instrument_does_not_own]] in the cost dimension: the survey was accurate about the rows it enumerated and silent about the rows it could not. RECOGNITION RULE: when a bound is declared per-identity but enforcement is gated on a SELECTION (changed, affected, sampled, scheduled), ask WHICH IDENTITIES THE SELECTION NEVER SELECTS ON THE MAINLINE. Those carry unevaluated bounds, and the population is discoverable in advance -- it is the declared identities minus the planned ones, both of which are already published per run. NEXT-RUNG TRIGGER, a capability and not an artifact: the ceiling is EXERCISED AND ITS RESULT PUBLISHED for every identity carrying one, including those the ordinary floor does not plan -- sufficient that a bound's first contact with an identity is a measurement someone chose to take, not a merge block on an unrelated change. Until then the class is discovered one PR at a time by whoever happens to edit the triggering authority. RUNG FOUND AT: mitigatable, and the mitigation is a debt row written after the fact. CEILING: mechanically preventable -- the unplanned population is a decidable set difference over data each run already emits.) +- **a subject digest taken over RAW FILE CONTENT makes annotations semantically load-bearing, which is the property DESIGN section 4c declares impossible** (INVALID STATE: a receipt, cache key or admission is pinned to a digest computed by `v1_compiler.resolved_graph_cache` `closure_content_digest`, which folds each source's `content` -- the authored bytes -- rather than anything the annotation-erased projection would produce. So ADDING, DELETING OR REFLOWING A COMMENT in a module inside such a subject moves the digest. 4c states the opposite in terms: annotation capture is disjoint from semantic occurrence allocation, and adding, deleting or moving an annotation cannot alter any semantic occurrence identity, semantic graph, resolution result, SEMANTIC HASH, or target-program bytes. HARM, MEASURED RATHER THAN IMAGINED: on gunbc#9725 the wet lane's semantic subject folds `v2.workflow.floor_wet_route`'s own closure content, a receipt from a 2h31m dispatch was pinned to that digest, and an operator-granted one-shot lease pinned the same value as `exact_semantic_subject_digest`. Repairing a one-word COMMENT in that module would have voided the grant and forced a re-dispatch plus a second operator grant. Three real defects were therefore repaired in the seed and left standing in the substrate authority, which is filed separately as `gunbc.guarantee_stall` `wet_route_model_lags_seed_stall`. The next occurrence will not be so visible: someone reflows a paragraph and silently invalidates a receipt with no diagnostic connecting the two. THE DISJUNCTION, because only one of these can be true and neither is currently written down. EITHER the closure content digest is NOT a semantic hash in 4c's sense -- in which case it must stop being read as one, and the distinction between a CONTENT identity (what bytes were on disk) and a SEMANTIC identity (what program they denote) has to be authored somewhere a reader meets before pinning anything to it. OR 4c's guarantee genuinely does not hold for this carrier, and 4c is overclaiming for every consumer that digests sources rather than the erased projection. RECOGNITION RULE: when a digest is described as a subject, a semantic subject, or a program identity, ask WHAT IT FOLDS. If the answer is file content, then comments, whitespace and formatting are inside it, and every guarantee stated about annotations being semantically inert is false of that digest -- while reading exactly like a guarantee about the program. The tell is a digest whose name says semantic and whose producer takes `content`. NEXT-RUNG TRIGGER, a capability and not an artifact: a subject digest folded over the ANNOTATION-ERASED projection that semantic passes already receive -- the same erasure 4c requires those passes to consume -- so that the digest is invariant under comment edits by construction and 4c's guarantee is true of it rather than merely stated near it. Failing that, the weaker form: the content digest is RENAMED to say it is a content identity and every pinning consumer is re-read against that meaning. RUNG FOUND AT: mitigatable, and the mitigation is that authors happen to know. CEILING: structurally impossible -- an erased-projection digest cannot move on an annotation edit, because the annotation is not in the input.) +- **a value and a summary of it -- a digest, a count, a view, an annotation -- placed side by side without a join can disagree silently, and the corroboration the reader believes they are getting was never computed** (INVALID STATE: a signature takes a value AND a summary of that value as two peer arguments -- `envelope` beside `envelope_digest`, `roster_identities` beside `roster_digest` -- with no arm relating them. The signature admits a digest of something OTHER than the value beside it; nothing refuses; and every downstream guarantee that cites the digest is then citing a summary of a different object, while reading exactly like a guarantee about the value. DISTINGUISHING FACTS: the two arguments are supplied by the same caller from the same site TODAY, so the pairing is held by lexical proximity rather than by anything the type system or a fold can see; the defect is constructible without touching a single caller, by supplying a correct digest of a different subject. EVIDENCE, TWO INSTANCES IN ONE MODULE, which is what makes it a class rather than a coincidence: `v2.workflow.floor_wet_route` `wet_route_gate_disposition_for_receipt` carries BOTH the envelope/digest pair and the roster-identities/roster-digest pair. The first was demonstrated live -- `v2.test.floor_wet_route` `wet_lease_admits_an_envelope_whose_content_the_digest_does_not_name` constructs an envelope whose content the pinned digest does not name, and the lease gate ADMITS. THE SAME DEFECT READ FROM THE OTHER END: agreement among derived views is vacuous when the views share one reader. A projection was nearly shipped with a row silently deleted because FOUR derived views agreed, all fed by a single reader -- one source feeding many views made agreement carry no information, exactly as a digest and its subject being independent lets them disagree unnoticed. THE THIRD FACE, AND THE ONE THAT SURVIVED REVIEW LONGEST: PROSE ADJACENCY IS NOT A JOIN EITHER. `wet_route_identity_rows_block_with_publication` carried an annotation stating that EXACTLY TWO per-identity classes are waived under a valid publication transaction, three lines above a body that returned false unconditionally and waived FOUR -- so `no_verdict`, the ABSENCE of a verdict, was converted into a green merge path. The prose and the code disagreed by a factor of two IN THE SAME FUNCTION and FOUR APPROVALS READ PAST IT. An annotation is not checked against the body it sits above by anything: it READS as documentation and FUNCTIONS as an assertion, and by DESIGN section 4c no `Accepted` program can read one, so nothing in the toolchain will ever disagree with it. Provider count is not attention -- four approvals is not four readings of that function. AND FIELD ADJACENCY IS NOT A JOIN EITHER, which is the same claim one scale down: in `v1_compiler.bin.claim_batch`'s two pre-execution refusal arms the annotation two lines above `WetReceiptIdentityRow` was RIGHT, and the neighbouring fields `observed_entry_rel` and `observed_function` were RIGHT -- Optional, and correctly None on exactly those arms -- and `wall_ms`, two fields later in the SAME STRUCT LITERAL, fabricates a 0 for a duration nothing measured. PROXIMITY TO A CORRECT THING IS NOT CORRECTNESS: a reader scanning that literal gets three signals of care and one fabrication, with nothing in the text distinguishing them. And 0 is the WORST available fabricated value for that field rather than a neutral placeholder, because it is THE FASTEST OBSERVABLE EXECUTION -- so a consumer that averages, thresholds or ranks on wall_ms without first branching on the outcome wire reads the ABSENCE of a measurement as the BEST measurement in the corpus. An anomalous-looking fabrication is found by whoever first sorts the column; this one sorts to the top and is found by nobody. All three faces are one defect: A JOIN THAT WAS NEVER MADE, so the corroboration a reader believes they are getting was never computed. RECOGNITION RULE: whenever a parameter list contains a value and a summary, hash, count, digest or identity OF that value, ask what refuses when they disagree. If the answer is nothing, the summary is unverified input wearing the costume of a derived fact. The mirror question for agreement: when N sources agree, ask how many INDEPENDENT reads produced them; if the answer is one, the agreement is a copy agreeing with itself. THE REPAIR, already built once and therefore not speculative: DERIVE THE DIGEST FROM THE VALUE AT THE POINT THE VALUE IS OBTAINED, NEVER ACCEPT IT AS A PEER PARAMETER. The seed`s `read_wet_receipt_envelope` now returns the decoded envelope and the digest of the bytes it decoded FROM, in one call, so the two cannot name different objects; its control `carried_digest_names_the_bytes_the_envelope_was_decoded_from` rewrites the file between reads and asserts the carried digest still names its own bytes. RUNG FOUND AT: mitigatable -- a comment and a caller convention. CEILING: structurally impossible, because a digest produced by the same operation that produces the value has no constructor that lets it name a different one. NEXT-RUNG TRIGGER, a capability: a carrier type that pairs a value with a digest DERIVED at construction, so no signature anywhere can accept the two separately -- the `.dag` instances named in `gunbc.guarantee_stall` `wet_route_model_lags_seed_stall` are the population that trigger retires.) +- **a written rule is how a LATER READER learns what happened; it is not how a PRESENT AUTHOR is stopped, so a ledger that grows without changing what is easy to type buys documentation and no prevention** (INVALID STATE: a failure class is answered by APPENDING A ROW -- to this roster, to a stall roster, to an annotation -- and the row is then counted as the remedy. The class recurs anyway, because at the moment of authoring the dangerous form is still the shortest thing to type and nothing costs more when it is chosen. RECOGNITION RULE, which is the whole row: after filing, ask WHAT IS NOW HARDER TO DO THAN IT WAS BEFORE. If the honest answer is nothing, the filing was a RECORD and not a REPAIR, the class rung did not move, and it must be reported as UNREMEDIED rather than as covered. WHY IT IS NOT MERELY WEAK BUT ACTIVELY MISLEADING: a filed class gets CITED AS COVERAGE, so a reviewer meeting it reads it as handled and the filing converts an open deficit into a closed-looking one while leaving the deficit exactly where it was -- a DESIGN section 4b(1) rung wearing a 4b(2) costume, which is this ledger own version of rung inflation. An unrepaired filing is therefore WORSE than no filing, not equal to it. WHY THE RECALL DOES NOT FIRE: a rule filed under its SUBJECT MATTER is retrieved by thinking about that subject matter, and an author executing a step attends to THE GOAL, not the class of the step. Nothing in `retire the superseded poller` cues `I am about to type a pattern that can match myself`. THE TEST RUN ON A REAL POPULATION THE SAME NIGHT IT WAS WRITTEN, AND IT CAME BACK MOSTLY NEGATIVE: across ten class-filings required in one day, the identity-join rows made nothing harder (`sort -u` is exactly as easy to type as `sort`); the prose-adjacency, field-adjacency and digest-beside-subject rows made nothing harder (no lens refuses a digest passed beside its subject, and that signature is still the natural one to write); the empty-reading rows made nothing harder (the short read is still shorter than the head-filtered one, which is precisely why four people reached for it). ONE of the ten changed what is easy, and IT WAS NOT A FILING: a schema hazard was answered by computing the affected population and commenting on each of the five pull requests about to hit it, delivering friction to five named authors rather than prose to a ledger. A second was initially scored as a climb and the correction is the sharper result: the carrier ALREADY HAD THE RIGHT SHAPE and nothing about it was built that day; what the day produced was the DISCOVERY that a wrong thing was writable beside it, because an author wrote a fabricated previous-rung into a drop row, A REGEN RAN GREEN OVER IT, and a reader happened to look at the field. NO MECHANISM WAS WATCHING. Corrected score: ONE push-friction instance that expires when five pull requests land, ZERO climbs, ONE discovery -- and the discovery is the least repeatable item in the list, since the next occurrence is written where nobody is reading and the green regen is identical. A LUCKY READ IS NOT COVERAGE. THE TWO KINDS OF FRICTION ARE NOT INTERCHANGEABLE AND ONLY ONE COMPOUNDS: PUSH friction is delivered to named authors at the moment of impact and EXPIRES when their changes land; PULL-PROOF friction removes the constructor, so nothing needs delivering to anyone ever again. A day producing one of each must not report two. THE CONCLUSION THE AUDIT FORCES, STRONGER THAN THIS ROW STARTED: retrieval-by-recall is not a mechanism that becomes adequate at a smaller ledger size -- IT IS THE WRONG MECHANISM AT ANY SIZE, because the retrieval cue never arrives regardless of how few rows there are. Every row real deliverable is THE FRICTION, and the prose is its RECEIPT rather than its product. RUNG FOUND AT: mitigatable, and this row is an instance of what it describes, which is why it carries a trigger rather than resting on having been written. CEILING: structurally impossible for any class whose dangerous form can be removed from the vocabulary entirely -- an unwritable form needs no rule. NEXT-RUNG TRIGGER, a capability and not an artifact: for each filed class, a named ARTEFACT OF FRICTION -- a lens that refuses the shape, a carrier with no unsafe constructor, a wrapper shorter to invoke than the raw form -- so that a filing arrives WITH a change in what is easy, and the obligation is symmetric: whoever ASKS for a row owes the friction artefact or the plain sentence that nothing got harder and the class stands UNREMEDIED.)