Skip to content
Merged
6 changes: 6 additions & 0 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ At a service boundary, rung honesty has a commercial consequence: a dimension ma

Every newly discovered error class — incident, review finding, runtime exception, falsifier divergence — files or updates one row: invalid state, harm, distinguishing facts, rung found at, ceiling with reason, next trigger. Declared drops are rostered in full — previous rung, temporary rung, reason, population, restoration trigger — in [docs/design-ledgers.md](docs/design-ledgers.md), authority `gunbc.rung_drop`. A drop is retired BY ITS TRIGGER AND BY NOTHING ELSE, so the trigger is the whole check. The ones standing today:

- **Heal job for generated artifacts** — declared 2026-09-01
- **Six of the seven effect gates (one restored)** — declared 2026-09-01
- **Rust fmt as a merge-path gate** — declared 2026-09-01
- **Merge-admission stamping: the receipt has no producer** — declared 2026-09-01
- **Falsifier cadence: exposure open, disposition NOT decided** — declared 2026-09-01
- **Stable per-claim cost qualification under a shared execution envelope** — declared 2026-09-01
- **Emitted-bytes fixture witnesses in a required lane** — declared 2026-09-01
- **Direct-call argument TYPE-COMPAT judgment inside v2.* modules (one of two arms; inhabitance still runs)** — declared 2026-09-01
Expand Down Expand Up @@ -230,6 +235,7 @@ One row per class, each carrying its recognition rule and its receipts, in [docs
- `alias_resolution_collides_with_kernel_spelling`
- `restored_bytes_reviewed_as_authorship`
- `review_summary_inverts_roles_and_affirms_the_join`
- `fabricated_debt`
- `yaml_inline_comment_ingested_as_scalar_content`
- `accepted_source_emits_uncompilable_target`
- `incidental_denominator_as_wall`
Expand Down
3 changes: 3 additions & 0 deletions dag/gunbc/recurring_failure_mode.dag
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ data admitted_module_without_judged_standing: RecurringFailureMode = RecurringFa
evidence: [],
}

data fabricated_debt: RecurringFailureMode = RecurringFailureMode { identity: "fabricated_debt" as NonEmptyStr, authored: "**fabricated debt** (a declaration is authored for an exposure that does not exist, or that is already declared elsewhere, so the ledger grows a row whose trigger CANNOT FIRE because there is nothing to restore. It is the exact inverse of the unfiled gap and it is the more comfortable mistake: filing reads as diligence, the row survives review because every reviewer checks whether a declared drop is HONEST about its loss and none checks whether the loss is REAL, and the cost lands on whoever later tries to retire it. **THE HARM IS NOT MERELY CLUTTER, WHICH IS WHY IT IS A CLASS.** A drop is retired BY ITS TRIGGER AND BY NOTHING ELSE, so a row for a non-existent exposure is permanent by construction; it inflates the standing-drops list that DESIGN projects on every turn of every session, and the next reader plans against an exposure nobody has. A row DUPLICATING an existing declaration is worse still: it forks the single authority for one safety fact, so the two can be retired independently and the tree ends up asserting both that the class is dropped and that it is restored. **THE ORIGIN IS ALWAYS THE SAME, and naming it is the recognition rule: the population was read from a PARAGRAPH rather than measured from the tree.** A loss clause enumerates what was unguarded on the day it was written; capabilities return, get re-homed, or acquire their own declarations, and the sentence does not move. So the rule is: before authoring a drop, resolve every named item against the tree -- is this exposure live NOW, and does it already have a row? **TWO RECEIPTS, both caught before authoring, 2026-09-01, while splitting `gunbc.rung_drop` `floor_cut`'s six-capability loss into capability-grain rows.** (1) GENERATED-ARTIFACT DRIFT was on the loss clause's list and is RESTORED -- gunbc#9415 enrolled a required `generated-artifact` phase adjudicating every member of `committed_generated_artifacts`; the same paragraph elsewhere admits the phase took it off the list, so the row contradicted itself and a reader following the enumeration would have declared a drop for a live gate. It is now stated as a FRACTION, 1 of 7 discharged and 6 outstanding, because a population that shrinks silently cannot be checked. (2) THE PER-WITNESS EVAL DEADLINE was on the same list and ALREADY CARRIES ITS OWN DROP at `gunbc.witness_row_cost` `gunbc_ci_fast_lane_rule_note`; a second row would have been the section 3 fork, and it is cited from the sibling rows rather than re-declared. Six items on the paragraph, five real rows. **NEIGHBOURS, and the boundaries are what keep this from absorbing them.** Distinct from `unbacked_execution_claim`: there prose asserts a live relation that no authority backs, and the subject EXISTS while the claim about it is false; here the subject itself is absent and the claim of loss is the fabrication. Distinct from `rung inflation`, which reports a class as SAFER than its evidence supports -- this reports the tree as MORE EXPOSED than it is, and both mislead the same reader in opposite directions. Distinct from `restoration_promise_names_a_route_that_does_not_exist`, which is a REAL exposure with an unsatisfiable trigger; this is an unreal exposure, and the two are found by the same question asked at different ends -- does the trigger name something that exists, and does the LOSS name something that exists. **RUNG: 1 (mitigatable) -- caught by a reader resolving the population, which is exactly what happened here and is not a mechanism. CEILING: 3, since `does this exposure exist` is decidable for any loss expressed as a citation to a mechanism rather than as prose. NEXT-RUNG TRIGGER, a CAPABILITY: a drop row whose lost capability is carried as a resolvable citation to the mechanism that provided it, so a row declaring the loss of something the tree still has -- or something another row already declares -- fails to compile. Enumerating populations more carefully by hand does not retire it; it only executes this row's recognition rule once more.)" as NonEmptyStr, evidence: [] }
data alias_resolution_collides_with_kernel_spelling: RecurringFailureMode = RecurringFailureMode { identity: "alias_resolution_collides_with_kernel_spelling" as NonEmptyStr, authored: "**an instrument resolves an alias, lands on a name that COLLIDES with a kernel spelling, and attributes the result to the kernel** (the reference under measurement is authored QUALIFIED and points at a type alias; the reader resolves the alias, arrives at the alias declaration's own name, and that name is also a kernel name -- so the row is attributed to the kernel identity, naming THE EXACT CARRIER THE QUALIFICATION WAS WRITTEN TO MOVE AWAY FROM. **IT DOES NOT FAIL TO ANSWER; IT ANSWERS CONFIDENTLY AND WRONGLY**, and that is the whole severity: a missing answer is visible to its consumer and an inverted one is not, so the two rank completely differently and only the second can be cited as evidence for the opposite of what holds. **Distinct from `instrument_output_read_as_subject_content`, and the boundary is worth stating because they were found in the same instrument in the same hour**: there a report is COMPLETE for the reporter and read as complete for the consumer, so the defect is in the READING; here the report is wrong on a specific row it does examine, so the defect is in the INSTRUMENT and no amount of careful reading recovers it. Also distinct from `hollow_alias`, which is about a second name minted for one concept: the alias here is legitimate modelling, and what fails is a reader of it. **SPECIMEN, with a discriminating probe executed on covered ground (2026-09-01, gunbc#9907 follow-up).** `v1.tests.claim.carrier_realization_census` reports, for two functions appended to `v2.compiler.tokenize` on adjacent lines with identical position kind, differing only in alias-versus-concrete: a param authored `std.determinism.Determinism` keeps its dotted name, while a param authored `v2.std.text.String` comes back as bare `String` attributed to `<kernel:String>`. `v2.std.text` declares `type String = FreeMonoid<Char>`, so the alias name collides with the kernel spelling. Both probes produced rows (17661 -> 17663), which is what makes the negative half evidence rather than absence -- the positive control is the whole discriminator, and the same census had already produced a null result on an uncovered fixture whose emptiness was indistinguishable from confirmation. **CONSEQUENCE MEASURED, NOT IMAGINED**: read naively, the census contradicted the namespace wall about nine function declarations and would have been read as nine admission rows asserting a binding the carrier lacks, on a merged PR. The wall was right; the contradiction was this bug. **RUNG: MECHANICALLY PREVENTABLE AT BEST TODAY AND CURRENTLY UNENROLLED** -- the wrong answer is produced silently and nothing executes over it. The next-rung trigger is that two-line probe being ENROLLED as a discriminating RED in any covered module, which is cheap; a class whose RED is two lines and still does not execute has no excuse, and naming the cheapness is what makes it rank rather than sit. **Recognition rule**: wherever a reader resolves through an alias, ask whether the resolved name could collide with a name in a DIFFERENT namespace the reader also knows -- kernel, prelude, or ambient -- because at that point the reader cannot tell them apart and will pick one silently.)", evidence: [] }
data yaml_inline_comment_ingested_as_scalar_content: RecurringFailureMode = RecurringFailureMode {
identity: "yaml_inline_comment_ingested_as_scalar_content" as NonEmptyStr,
Expand Down Expand Up @@ -261,6 +262,8 @@ data recurring_failure_mode_roster: List<RecurringFailureMode> = [
alias_resolution_collides_with_kernel_spelling,
restored_bytes_reviewed_as_authorship,
review_summary_inverts_roles_and_affirms_the_join,

fabricated_debt,
yaml_inline_comment_ingested_as_scalar_content,
accepted_source_emits_uncompilable_target,
incidental_denominator_as_wall,
Expand Down
16 changes: 15 additions & 1 deletion dag/gunbc/rung_drop.dag

Large diffs are not rendered by default.

Loading
Loading