Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module gunbc.recurring_failure_mode.resolved_value_computed_then_discarded_for_the_authored_one

import std.types { NonEmptyStr }
import std.decl_ref { decl_ref }
import gunbc.recurring_failure_mode { RecurringFailureMode }

data resolved_value_computed_then_discarded_for_the_authored_one: RecurringFailureMode = RecurringFailureMode {
identity: "resolved_value_computed_then_discarded_for_the_authored_one" as NonEmptyStr,

receipts: [
"**a phase computes the resolved form of a value, keeps only a by-product of it (its diagnostics), and rebuilds its output from the AUTHORED input** (the phase's result is structurally indistinguishable from a resolved one, so every consumer downstream reads an unresolved value as if the phase had run on it).",

"**SPECIMEN, 2026-09-17 (CARRIER-KEY-1, tidy-bee-696).** `v1.compiler.infer_resolve` `resolve_item_types`, in its record (Conj) and coproduct (Disj) field arms, computes `tr = resolve_node(n: authored_type)` for each field. It then rebuilds the field with `children: child.children` and `inferred: child.inferred`, keeping only `tr.diagnostics` and `tr.resolved.properties`. The resolved type is thrown away. Its sibling `resolve_field`, which does carry the resolved type, has no callers.",

"**THE CONSEQUENCE IS A MIS-KEYED IDENTITY, NOT A CRASH.** A field-position type reference reaches emission unresolved and carrying its own span. So `v1.std.core` `type_reference_provenance` keys it on the file the REFERENCE sits in. On the typed tree, the same kernel `String`, `Int` and `Bool` are keyed correctly as function parameters, which go through a path that keeps the resolved node, and wrongly as record fields. Re-derived by `v1.tests.claim.carrier_realization_census` over a closure: join `position_kind` to `split_identity`.",

"**THE SYMPTOM WAS ALREADY PATCHED ONE LINK DOWNSTREAM**, which is `symptom_link_patched_without_the_earliest_unjustified_boundary` exactly. `v1.compiler.emit_rust` `type_reference_provenance_in_env` re-resolves an unresolved leaf through the environment because `field type exprs are not inferred`. That note states the upstream fact as a given instead of naming it as the defect.",

"**RECOGNITION RULE.** A phase that calls the resolving function and reads only `.diagnostics` from its result, or rebuilds its output from the input it was handed. Ask what field of the result is dropped, and who downstream compensates for it. A second function that keeps the result and has no callers is the tell that the keeping version was written and then routed around.",

"**NOT REPAIRED WHERE FOUND.** Carrying the resolved type into the field changes what every renderer sees at every field position, so it is measured under the step-3 renderer reroute of docs/plans/carrier-realization-arbiter-repair-design.md, not landed as a local fix. The interim is `gunbc.rung_drop` `type_reference_location_fallback_keys_production_realization`. Rung found at: outside the ladder (silent). Ceiling: structurally impossible, since the phase's output can carry the resolved node as its only type. Next trigger: the field arms keep `tr.resolved`, `resolve_field` is either their single route or deleted, and the downstream env re-resolution in `type_reference_provenance_in_env` is removed in the same change.",
],

evidence: [
decl_ref(module_path: "v1.compiler.infer_resolve", decl_name: "resolve_item_types"),
decl_ref(module_path: "v1.compiler.infer_resolve", decl_name: "resolve_field"),
decl_ref(module_path: "v1.compiler.emit_rust", decl_name: "type_reference_provenance_in_env"),
decl_ref(module_path: "v1.std.core", decl_name: "type_reference_identity"),
],
}
4 changes: 4 additions & 0 deletions dag/gunbc/recurring_failure_mode/state_space_conflation.dag
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ data state_space_conflation: RecurringFailureMode = RecurringFailureMode {

"**RECOGNITION RULE FOR THE FORM: when a consumer narrows a closed variant to an `Optional`, the narrowing is where the states are lost, and the arm that gives the collapsed case a permissive default is where the loss becomes a fail-open.** The tell is a refusal reason that is empty on some path: a refusal that cannot say why was never a refusal.",

"**RECEIPT (2026-09-17, CARRIER-KEY-1): THE REFERENCE-SITE FALLBACK ARM IS SPLIT, AND THE SPLIT ITSELF CORRECTED THE CONFLATION'S PROXY.** `v1.std.core` `type_reference_provenance` answered `this node IS the declaration` and `this reference's declaration was not recovered` with one arm keyed on the node's own span. The obvious proxy for telling them apart -- is a Resolved node bound -- is itself a conflation: on the typed tree, `v1.compiler.infer_resolve` resolves a LEAF reference by substituting the declaration (no Resolved node, correct span) and builds an APPLIED reference's Resolved node on the REFERENCE's span (a Resolved node, location key). `v1.std.core` `type_reference_identity` over `std.coercion` `TypeReferenceIdentity` therefore splits on the parser's `ModuleItemTypeDeclaration` mark and the kernel mint, and refuses the rest with a cause. Populations are re-derived by `v1.tests.claim.carrier_realization_census` column `split_identity`; the executing RED is `v1.compiler.compiler_tests_rust` `ct_type_reference_identity_split_test`. Production is unchanged and declared as `gunbc.rung_drop` `type_reference_location_fallback_keys_production_realization`.",

"**RECOGNITION RULE ADDED BY THAT RECEIPT: a presence test on a carrier field is not a state test.** `inferred is Resolved` and `span is non-empty` each looked like the discriminator and each put both states on both sides of it. Ask what STRUCTURE only one state can have.",

],

evidence: [],
Expand Down
2 changes: 2 additions & 0 deletions dag/gunbc/rung_drop/roster.dag
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ import gunbc.rung_drop.accumulator_copy_positive_controls_off_every_lane { accum
import gunbc.rung_drop.seed_whole_corpus_demand_population_blind { seed_whole_corpus_demand_population_blind }
import gunbc.rung_drop.roadmap_live_projection_new_witness_eval_step_cost { roadmap_live_projection_new_witness_eval_step_cost }
import gunbc.rung_drop.seam_monolith_control_unmeasured_derived_root { seam_monolith_control_unmeasured_derived_root }
import gunbc.rung_drop.type_reference_location_fallback_keys_production_realization { type_reference_location_fallback_keys_production_realization }

data rung_drop_roster: List<RungDrop> = [
floor_cut_heal,
Expand Down Expand Up @@ -131,6 +132,7 @@ data rung_drop_roster: List<RungDrop> = [
seed_whole_corpus_demand_population_blind,
roadmap_live_projection_new_witness_eval_step_cost,
seam_monolith_control_unmeasured_derived_root,
type_reference_location_fallback_keys_production_realization,
]

// THE DERIVATION THE PROJECTION USES, so "standing today" has one authority and not two. The
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
module gunbc.rung_drop.type_reference_location_fallback_keys_production_realization

import std.types { NonEmptyStr }
import gunbc.rung_drop { RungDrop, Standing, TypedDeclaration, ReplacementStaged }
import gunbc.guarantee_rung { MechanicallyPreventable, OutsideTheLadder }

// THE DECLARED DROP FOR THE REFERENCE-SITE IDENTITY KEY THAT REALIZATION IS DECIDED ON (DESIGN 4b(3)).
//
// WHAT IS DROPPED. v1.compiler.emit_rust checkpoint_table_bypasses_identity_note reports
// declaration-keyed realization as MECHANICALLY PREVENTABLE. That rung assumes the key names the
// DECLARING module. It does not: v1.std.core type_reference_provenance falls back to the node's own
// span whenever no Resolved node is bound, so a reference whose declaration was not recovered is
// keyed on the file the REFERENCE sits in. v1.compiler.coercion type_realization_decision then
// answers that location with total confidence. That is silent wrongness, which is outside the
// ladder, and the reported rung was never held on this path.
//
// WHY IT IS DECLARED RATHER THAN REPAIRED IN THE SAME CHANGE. std.coercion TypeReferenceIdentity and
// v1.std.core type_reference_identity split the collapsed arm and refuse where the key is a
// location. Pointing production at them is not a key edit. Mapping the refusal onto the existing
// DeclarationIdentityAbsent does not refuse: type_realization_decision answers that arm from the
// bare-name table. It also flips provenance_realizes_natively, which changes literal elaboration in
// v1.compiler.infer and String gating in v1.compiler.emit_rust. That is the renderer reroute, and
// docs/plans/carrier-realization-arbiter-repair-design.md forbids taking it before it is measured.
// So the query lands as an instrument and production keeps its answer. This row stops that answer
// being silent.
//
// THE POPULATION IS NAMED BY ITS INSTRUMENT, NOT TRANSCRIBED. It is every occurrence
// v1.tests.claim.carrier_realization_census reports with legacy key FALLBACK or resolved and a
// split identity of ReferenceIdentityUnavailable, re-derived by running that census's binary over
// a closure. Two causes carry it: record and coproduct FIELD type expressions, which
// v1.compiler.infer_resolve resolve_item_types resolves and then discards, and the Resolved node of an
// APPLIED reference, which resolve builds on the reference's own span.
//
// THE TRIGGER NAMES A CAPABILITY. Every production reader of a type reference's declaration asks
// type_reference_identity (or an identity authority keyed on the declaration node or env binding)
// and gives the refusal arm a typed, located behaviour rather than a location key. Deleting the
// fallback arm of type_reference_provenance is the observable retirement. Routing only the six
// text-carrier renderers does not discharge this row: v1.compiler.infer and the numeric realization
// gate read the same key.
data type_reference_location_fallback_keys_production_realization: RungDrop = RungDrop {
identity: "type_reference_location_fallback_keys_production_realization" as NonEmptyStr,

subject: "the declaration identity key production realization decides on at a type reference (v1.std.core type_reference_provenance feeding v1.compiler.coercion type_realization_decision): a location stands in where no declaration was recovered",

declared: "2026-09-17",

standing: Standing,

declaration: TypedDeclaration {
previous: MechanicallyPreventable,
temporary: OutsideTheLadder,
reason: ReplacementStaged { replacement: "v1.std.core type_reference_identity over std.coercion TypeReferenceIdentity, which refuses where the key would be a location; consumed today by v1.tests.claim.carrier_realization_census and v1.compiler.compiler_tests_rust ct_type_reference_identity_split_test only" },
population: [
"type-reference occurrences for which v1.tests.claim.carrier_realization_census reports split identity ReferenceIdentityUnavailable while production still answers a CorpusDeclared key: record and coproduct field type expressions (v1.compiler.infer_resolve resolve_item_types discards the resolved type)",
"applied type references whose Resolved node v1.compiler.infer_resolve builds on the reference's own span (split cause ResolvedNodeIsNotADeclaration)",
],
restoration_trigger: "every production reader of a type reference's declaration identity -- v1.compiler.coercion type_reference_realization, the v1.compiler.infer native-numeric sites and the v1.compiler.emit_rust readers of type_reference_provenance -- asks type_reference_identity or a declaration-node or env-binding keyed authority and gives its refusal arm typed behaviour, so the own-span fallback arm of type_reference_provenance is deleted",
}
}
51 changes: 51 additions & 0 deletions dag/gunbc/type_reference_decl_file_occurrence_census.dag
Original file line number Diff line number Diff line change
Expand Up @@ -524,3 +524,54 @@ data type_reference_decl_file_census_discharge: List<DeclarationRef> = [
decl_ref(module_path: "v1.compiler.coercion", decl_name: "type_reference_realization"),
decl_ref(module_path: "v1.compiler.coercion", decl_name: "declaration_realization"),
]

// THE FALLBACK ARM, SPLIT (CARRIER-KEY-1, 2026-09-17). The roster above counts CALL occurrences of the
// reference-site read. This record states how that read's own collapsed arm is now told apart, so
// the fallback population it produces can be scored per occurrence rather than read as one mass.
// It carries no count on purpose. The populations are occurrence facts about a closure, and the
// producer that re-derives them is named here instead of transcribed (DESIGN section 6).
//
// THE SPLIT IS BY STRUCTURE, AND THE RESOLVED ARM IS SPLIT TOO. Running the instrument on the typed
// tree showed the brief's premise was half right. A missing Resolved node does NOT mean inference
// was unavailable, because v1.compiler.infer_resolve resolves a leaf reference by SUBSTITUTING the
// declaration, span included. And a present Resolved node does NOT mean a declaration, because
// resolve builds an applied reference's Resolved node on the reference's own span. So neither
// "Resolved or not" nor "span present or not" separates the states. The parser's
// ModuleItemTypeDeclaration mark and the kernel mint do.
//
// WHAT THE SPLIT IS NOT, measured on its first run and stated so a refusal is not read as a wrong key.
// (1) IT OVER-REFUSES. A leaf reference substituted through an alias keeps the declaration's span
// but carries the alias target's item kind, so a reference whose old key DID name its declaration
// can land in Unavailable:NoResolutionBoundAtReference. Refusal means "not provable from the node",
// never "production was wrong here". Score a refusal right-or-wrong only by joining the census's
// environment column. (2) IT DOES NOT REFUSE THE KERNEL-MINTED ALIAS BOUNDARY. A substituted alias
// right-hand side minted on the kernel pseudo-file (e.g. std.algebra.FreeMonoid) answers
// ResolvedToDeclaration:KernelMinted while the environment names the corpus declaration. That
// inherits v1.std.core declaration_provenance_of's kernel recognizer and is state_space_conflation's
// third form, not a new defect. It shows up in the census as a ResolvedToDeclaration row whose
// identity column is DISAGREE.
//
// PRODUCTION IS NOT CHANGED BY THIS, and the record says so rather than implying a wall:
// gunbc.rung_drop type_reference_location_fallback_keys_production_realization declares the key
// production still decides on.
type FallbackArmSplit {
collapsed_read: DeclarationRef
split_query: DeclarationRef
outcome_type: DeclarationRef
refusal_causes: DeclarationRef
population_instrument: DeclarationRef
population_column: String
executing_witness: DeclarationRef
declared_drop: String
}

data type_reference_decl_file_fallback_split: FallbackArmSplit = FallbackArmSplit {
collapsed_read: decl_ref(module_path: "v1.std.core", decl_name: "type_reference_provenance"),
split_query: decl_ref(module_path: "v1.std.core", decl_name: "type_reference_identity"),
outcome_type: decl_ref(module_path: "std.coercion", decl_name: "TypeReferenceIdentity"),
refusal_causes: decl_ref(module_path: "std.coercion", decl_name: "ReferenceIdentityUnavailableCause"),
population_instrument: decl_ref(module_path: "v1.tests.claim.carrier_realization_census", decl_name: "typed_census_from_sources"),
population_column: "split_identity, beside legacy_key: a FALLBACK or resolved legacy arm joined to IsTheDeclaration (legitimately keyed), ResolvedToDeclaration, or Unavailable:<cause> (production keyed a location), per occurrence",
executing_witness: decl_ref(module_path: "v1.compiler.compiler_tests_rust", decl_name: "ct_type_reference_identity_split_test"),
declared_drop: "gunbc.rung_drop type_reference_location_fallback_keys_production_realization",
}
36 changes: 36 additions & 0 deletions dag/std/coercion.dag
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,42 @@ type TypeDeclarationProvenance
| KernelMinted { minted_name: String }
| DeclarationIdentityAbsent

// WHICH STATE A TYPE REFERENCE IS IN WHEN ITS DECLARATION IS ASKED FOR -- the split of the one arm
// the reference-site read used to answer for two states. v1.std.core type_reference_provenance
// falls back to the reference node's OWN span whenever no Resolved node is bound, so `this node IS
// a declaration` and `this reference's declaration was not recovered here` both answer
// CorpusDeclared on the file the node sits in. The second case is a location standing where an
// identity was owed: DESIGN section 5's absorbing fallback, and gunbc.recurring_failure_mode
// state_space_conflation's form for this carrier.
//
// Each arm is decided from STRUCTURE, never from span presence. A declaration node is one the parser
// marked ModuleItemTypeDeclaration, or the kernel mint for its own name. A Resolved node that is
// neither is NOT a declaration: the resolver builds the Resolved node of an applied reference on
// the REFERENCE's span, so reading its span is the same location key one hop later. Those arms
// refuse, and the cause says which of the two shapes refused.
//
// A TYPE-VARIABLE BINDER IS ITS OWN ARM. A generic parameter such as T is bound by the enclosing
// declaration and has no declaring module to key on. Filing it as a declaration would let the kernel
// span its binding is minted on pass for a KernelMinted type. Filing it as a refusal would count a
// correctly bound name as a missing identity. It is recognized only when the node itself carries
// the binding (inferred TypeVariable). An unresolved T sitting in a field still has no binding on the
// node, and refuses like any other unresolved reference.
//
// THIS IS NOT YET A PRODUCTION WALL. The production read is unchanged and still mis-keys, which is
// declared as gunbc.rung_drop type_reference_location_fallback_keys_production_realization. The
// consumer today is the census and the witness; the restoration trigger is the renderer reroute
// onto this query.
type TypeReferenceIdentity
= ReferenceResolvedToDeclaration { provenance: TypeDeclarationProvenance }
| ReferenceIsTheDeclaration { provenance: TypeDeclarationProvenance }
| ReferenceIsTypeVariableBinder { binder_name: String }
| ReferenceIdentityUnavailable { cause: ReferenceIdentityUnavailableCause }

type ReferenceIdentityUnavailableCause
= NoResolutionBoundAtReference
| ResolvedNodeIsNotADeclaration
| DeclarationNodeCarriesNoSpan

type RealizationRefusalCause
= DeclarationIdentityUnavailable
| ExactSourceIdentityAbsent { detail: String }
Expand Down
Loading
Loading