From d7cc6ae252380ef32ff18e17be4b81a571c92fe7 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Tue, 1 Sep 2026 09:12:21 +0000 Subject: [PATCH 1/3] File the accepted-source-emits-uncompilable-target class: a unit variant in a non-applied type position gunbc accepts a coproduct's unit variant standing in a field, parameter or return type and emits a Rust program rustc refuses. That is section 5 silent wrongness on the source-to-target path: the only wall that fires belongs to the target's compiler, and section 7 makes that gunbc's floor rather than rustc's problem. The row carries both halves of the evidence. The field specimen (neat-otter-332) is `type NonApplied { value: Time }` over `type Quantity = Time | Memory`, refusing E0573 at the emitted field under the narrow emitter classifier; under the broad classifier a phantom marker struct import made the same source COMPILE, and extending it across its declared parent boundary refuses E0308 expected Quantity found Time -- so the narrow classifier's E0573 is the class becoming visible, not a regression. Independently reproduced here at parameter position on baeabbbf80: `fn take(stamp: StampClass) -> StampMode` compiles with 0 blocking errors and one import-hygiene advisory, and cargo check on the emitted crate refuses E0308. One source defect, three target behaviours, so the rustc code is not the class. Rung found at: below the ladder, by execution at the emission boundary. Ceiling 4, because constructor identity and type identity are distinct modelled facts with decidable membership from the declaration. Next-rung trigger is the capability -- type-position resolution over the type namespace alone -- not a fixture or either specimen's repair. Row and ledger authorities only; no emitter edit. DESIGN.md and docs/design-ledgers.md are the regenerated projections. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01AsNTMSgjX8EPvGHVNo2sNC --- DESIGN.md | 1 + dag/gunbc/recurring_failure_mode.dag | 7 +++++++ docs/design-ledgers.md | 1 + 3 files changed, 9 insertions(+) diff --git a/DESIGN.md b/DESIGN.md index e0acd8598b1..c69771d8435 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -213,6 +213,7 @@ One row per class, each carrying its recognition rule and its receipts, in [docs - `executed_conjunct_discriminates_nothing` - `unbacked_execution_claim` - `mitigation_injected_where_judgment_declined` +- `accepted_source_emits_uncompilable_target` ## Building & checks diff --git a/dag/gunbc/recurring_failure_mode.dag b/dag/gunbc/recurring_failure_mode.dag index 1ac1f81384d..2242dae4728 100644 --- a/dag/gunbc/recurring_failure_mode.dag +++ b/dag/gunbc/recurring_failure_mode.dag @@ -228,6 +228,12 @@ data unbacked_execution_claim: RecurringFailureMode = RecurringFailureMode { evidence: [], } +data accepted_source_emits_uncompilable_target: RecurringFailureMode = RecurringFailureMode { + identity: "accepted_source_emits_uncompilable_target" as NonEmptyStr, + authored: "**accepted source emits uncompilable target** (INVALID STATE: a .dag construction the front end accepts with zero blocking diagnostics, whose emission is a target program the target compiler refuses. The instance filed here is a coproduct's UNIT VARIANT standing in a NON-APPLIED TYPE POSITION -- a field, parameter or return type spelled with a constructor rather than a type. HARM: section 5 silent wrongness on the source-to-target path. gunbc says Accepted and hands over a program that cannot build, so the only wall that fires belongs to the target's compiler; where a target has no such wall, or where the emitted artifact is never compiled, nothing fires at all. Section 7 makes this the seed's floor and not the target's problem: the .dag graph is the authority and Rust is one realization, so 'rustc catches it' is exactly the outsourcing this project exists to end. THE SPECIMEN, CARRIED HERE BECAUSE THE FIXTURE THAT PRODUCED IT WAS DISCARDED (neat-otter-332, 2026-09-01; the measured tree lived in session-local /tmp and is gone). Authored source, two modules: `scope.provider` declares `type Quantity = Time | Memory`; `scope.consumer` does `import scope.provider \{ Quantity, Time \}`, `type NonApplied \{ value: Time \}`, `fn field_as_quantity(subject: NonApplied) -> Quantity \{ subject.value \}`. gunbc accepts it. DISTINGUISHING FACT, and the reason this class must not be read off the target's error code: WHAT rustc says is decided by what else the emitter minted, not by the source defect. Under the NARROW emitter classifier the consumer emits `pub use crate::scope_provider::\{Quantity\};` then `use crate::scope_provider::Quantity::\{Time\};` with no marker binding, and `pub struct NonApplied \{ pub value: Time \}` refuses `error[E0573]: expected type, found variant Time` at `src/scope_consumer.rs:15:16` on `pub value: Time,`, label `not a type`, help `consider importing this struct instead`. Under the BROAD classifier the consumer instead emits `pub use crate::scope_provider::\{Time\};` beside `\{Quantity\}` -- the provider having emitted `pub enum Quantity \{ Time, Memory \}` AND `pub struct Time;` -- so the field declaration COMPILES, and the refusal moves to the function: `error[E0308]: mismatched types` at `src/scope_consumer.rs:20:5` on `subject.value.clone()`, `expected Quantity, found Time`, against `expected Quantity because of return type`. INDEPENDENTLY REPRODUCED AT PARAMETER POSITION on this branch, 2026-09-01 on gunbc baeabbbf80, by a single-file source handed to the compiler: `type StampMode = StampClass | StampOther` with `fn take(stamp: StampClass) -> StampMode \{ stamp \}`. `gunbc compile --target rust` exits 0 with 0 blocking errors, emits `pub fn take(stamp: StampClass) -> StampMode` beside `pub struct StampClass;`, and `cargo check` on the emitted crate refuses `E0308 expected StampMode, found StampClass`. One source defect; E0573, E0308-at-the-parent, and E0308-at-the-body depending on emission. THE MASK IS THE SHARP HALF, and it is fabricated plausible output rather than a lucky green: the broad classifier's marker import made the FIELD-ONLY source compile by substituting a distinct struct for a variant. It never preserved the modelled meaning, and extending the SAME accepted source across its declared parent boundary -- the function returning `Quantity` -- is what exposes it. So the narrow classifier's E0573 is this class becoming VISIBLE, not a regression the narrowing introduced. GENERAL FORM: a green obtained because the emitter manufactured a target-only entity for a source name is not evidence the source is well-typed, and the discriminator is to extend the source past the boundary the manufactured entity does not model. THE ONE .dag-SIDE SIGNAL IS ABOUT THE WRONG QUESTION: on the parameter reproduction the compile printed the ADVISORY `unlisted import use 'StampClass' (referenced but not in any import's name list)`. It fires because the name was not found among types -- the front end reached the exact fact that decides this case and reported it as import hygiene. It is not a partial wall: it is advisory, it names listing rather than type position, and the field specimen above IMPORTS `Time` explicitly, so it does not fire there at all (see `diagnostic_name_mechanism_silent`). RUNG FOUND AT: below the ladder, established by execution at the emission boundary -- the compile accepts and the emitted crate refuses. Section 4b's rung-1 mitigations are absent: nothing at the .dag boundary is typed, located or countable about this construction. CEILING: 4, structurally impossible, and the reason is that constructor identity and type identity are two distinct modelled facts whose membership is decidable from the coproduct declaration -- a variant name is reachable from that declaration as an ARM and never as a type, so the type-position slot has no constructor that admits it. No undecidable predicate is involved, so this is a wall now and not a ratchet. NEXT-RUNG TRIGGER, phrased as the capability that retires the row rather than an artifact that would contribute to one: type-position name resolution that consults the TYPE namespace alone and refuses a name resolving to a constructor with a located diagnostic, sufficient that NO Accepted program contains a variant name in any non-applied type position -- field, parameter or return. Repairing either specimen, narrowing the emitter classifier, or adding a fixture satisfies less than that and does not retire this row. RECOGNITION RULE: when the target compiler names a symbol at a type position, check whether that symbol is declared as an ARM of a coproduct in the source; if it is, the defect is in accepted .dag and the target compiler is the only wall that fired. SCOPE STATED RATHER THAN GENERALISED: executed for a unit arm at a field type and at a parameter type, Rust target only. Record-shaped arms, applied positions such as `List