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,23 @@
module gunbc.recurring_failure_mode.roster_membership_by_structural_equality

import std.types { NonEmptyStr }
import std.decl_ref { DeclarationRef, WholeDeclaration }
import gunbc.recurring_failure_mode { RecurringFailureMode }

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

receipts: [
"**a node becomes a declared-inhabitant roster member because it is STRUCTURALLY EQUAL to some node inside a roster value, not because it denotes that roster entry.** (INVALID STATE: a bare synthetic childless Conj, which is parse residue or an empty product anywhere, is a TypeDenotationKind member of the dag roster. So `v2.compiler.infer` derives it a grounding by lookup, an ungrounded algebra ref, instead of GroundingNotDerived.) Consumers that demand grounding refuse at the wrong link (coercion at `infer_algebra_ref_ungrounded`, not `infer_grounding_demanded_not_derived`), and any frontier claim over such a node reads derived. `std.kind` `roster_kind_index` keys `Map<Node, Kind>` by the node value and entered every node reachable from the roster.",
"RECEIPT. gunbc#12625 (Program P, one Arrow encoding) rebuilt `v2.extdeps.languages.dag` `dag_fixture_emitted_add_fn` through `v2.std.arrow_signature` `anonymous_signature_arrow`. That added the declared-order edge, whose label list is a FreeMonoid ending in a synthetic childless Conj. Bisected on BuildBuddy (339be73493..c29acd041e, `product_introduction_leaves_childless_conj_on_the_frontier_holds`); first bad commit feadae7841. Five claims went silently red outside the required gate (gunbc#12860): infer_self_grounding_wall, translate_underived_refusal, type_param_binder_frame tpb_undeclared_t, infer_product_introduction childless_conj, and ingest_bridge refuses_source_absent. The cause was decided by execution, not by a facts-key collision: each claim's tree is one node, so infer's facts map holds one entry. A direct `infer_node_declared_in_language_inhabitants` probe answered Present for a bare childless Conj.",
"REPAIRED AT THE EARLIEST UNJUSTIFIED LINK: the roster index walked label metadata as if it were payload. `std.kind` `roster_member_nodes` skips an edge that `v2.std.node` `arrow_signature_order_edge` classifies as an Arrow's declared order. That is the same predicate infer's gather fold and product evidence ask, so there is one classification and no second label list. RESIDUAL, COUNTED: membership is STILL decided by structural equality with a node in the roster value, so any value-position node equal to a payload node of a roster member is still read as that member. RUNG: mechanically preventable, held by the claims below. CEILING: structurally guaranteed. NEXT-RUNG TRIGGER, NAMING THE CAPABILITY: roster membership is keyed by the DECLARED IDENTITY a node resolves to, not by its value. This is the namespace migration's end-state that `v2.compiler.infer` names, where the roster lookup is deleted in favour of consuming resolution output.",
],

evidence: [
DeclarationRef { module_path: "v2.test.execution.infer_product_introduction", decl_name: "a_bare_childless_conj_is_not_a_roster_member_holds", field: WholeDeclaration },
DeclarationRef { module_path: "v2.test.execution.infer_product_introduction", decl_name: "the_declared_order_label_list_is_not_a_roster_member_holds", field: WholeDeclaration },
DeclarationRef { module_path: "v2.test.execution.infer_product_introduction", decl_name: "the_roster_add_fn_is_still_a_roster_member_holds", field: WholeDeclaration },
DeclarationRef { module_path: "v2.test.execution.infer_product_introduction", decl_name: "the_add_fn_domain_through_a_payload_edge_is_a_roster_member_holds", field: WholeDeclaration },
DeclarationRef { module_path: "v2.test.execution.infer_product_introduction", decl_name: "product_introduction_leaves_childless_conj_on_the_frontier_holds", field: WholeDeclaration },
],
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ data v2_test_family_reds_measured_outside_the_gate: RungDropAmendment = RungDrop

later_event: "the srv1 probe of the withdrawn v2.test. family (neat-boar-16, scratch commit eff2d73b14 = main c95f906 plus the family, artifacts on branch artifact/v2-gate-probe) measured what this row's population holds for that family: 841 v2.test.* modules declaring 5,030 test fns at c29acd041e1 have no required route; with the family restored, 4,265 were planned, 4,192 passed, 17 reached no verdict (route gaps already rostered by v2.workflow.floor_route_gap), and 44 were red on main with no lane observing them. Preparation dominated, about 3,569 modules resolved and 3,096 s wall against about 101 s of claim evaluation, the shape of this row's 2026-09-19 nominal-roster cut, so the family stays out until the trigger below. One module, v2.test.claim.cargo_build_run_argv_witness, did not typecheck on main and refused the whole floor in strict preparation when the family was restored; gunbc#12860 repaired it" as NonEmptyStr,

bearing: "of the 44 measured red identities, those still red are named here with their owners, and each leaves this amendment's list when its fix lands, so restoring the family does not inherit them as silent reds. Owner gentle-koi-724 (MQ lane), fixed green by sharp-tern-39: v2.test.execution.data_decl_lowering_grounding.childless_conj_in_codomain_stays_on_the_frontier_holds (returned false). Owner deep-ferret-305 (floor lane), fixed by work item adhoc-e6c8990b-ccf: v2.test.claim.declaring_identity_spelling.production_ingest.matched_imported_kernel_type_position_is_absent_from_the_census_today (returned false); v2.test.claim.infer_self_grounding_wall.wall_conj_grounding_no_longer_returns_source_as_its_own_type (returned false); v2.test.claim.reference_derived_residency_reading.a_type_declaration_does_not_resolve_from_a_live_module_root_pending_11574 (returned false); v2.test.claim.translate_underived_refusal.translate_refuses_underived_conj_holds (returned false); v2.test.claim.type_param_binder_frame.tpb_undeclared_t_is_not_a_type_variable (returned false); v2.test.emit.rust_variant_construct_emit.rust_variant_construct_emit_holds_accepts (returned false); v2.test.emit.rust_variant_construct_emit.rust_variant_construct_emit_wrong_value_discriminates (returned false); v2.test.execution.infer_product_introduction.product_introduction_leaves_childless_conj_on_the_frontier_holds (returned false); v2.test.manual.ingest_bridge.ingest_identity_coercion_refuses_source_absent_from_authored_roster (returned false); v2.test.manual.program_assembly_multi_file.program_assembly_cross_file_import_assembles_holds (returned false); v2.test.manual.structured_body_dispatch.structured_body_produce_subsumes_add_table (returned false); v2.test.name_resolve.test_code_reference_wall.supplied_root_is_what_normalize_emits_holds (returned false); v2.test.parse.d5_expression_grammar_parse.cause_p_keyword_field_init_red_tokens_remain_holds (returned false); v2.test.parse.type_decl_modifier_g0_parse_probe.generic_param_publishes_the_generic_ident_class_holds (returned false). None is an expected-red row: that roster asserts the identity executes, and these do not while the family is outside the gate" as NonEmptyStr,
bearing: "of the 44 measured red identities, those still red are named here with their owners, and each leaves this amendment's list when its fix lands, so restoring the family does not inherit them as silent reds. Owner deep-ferret-305 (floor lane), fixed by work item adhoc-e6c8990b-ccf: v2.test.claim.declaring_identity_spelling.production_ingest.matched_imported_kernel_type_position_is_absent_from_the_census_today (returned false); v2.test.claim.reference_derived_residency_reading.a_type_declaration_does_not_resolve_from_a_live_module_root_pending_11574 (returned false); v2.test.emit.rust_variant_construct_emit.rust_variant_construct_emit_holds_accepts (returned false); v2.test.emit.rust_variant_construct_emit.rust_variant_construct_emit_wrong_value_discriminates (returned false); v2.test.manual.program_assembly_multi_file.program_assembly_cross_file_import_assembles_holds (returned false); v2.test.manual.structured_body_dispatch.structured_body_produce_subsumes_add_table (returned false); v2.test.name_resolve.test_code_reference_wall.supplied_root_is_what_normalize_emits_holds (returned false); v2.test.parse.d5_expression_grammar_parse.cause_p_keyword_field_init_red_tokens_remain_holds (returned false); v2.test.parse.type_decl_modifier_g0_parse_probe.generic_param_publishes_the_generic_ident_class_holds (returned false). Owner calm-hawk-793 (typing/identity lane), measured red on main on 2026-10-01 while fixing the rows above and missing from the srv1 list: v2.test.manual.ingest_bridge.ingest_identity_coercion_accepts_source_present_in_authored_roster (returned false); v2.test.execution.infer_product_introduction.product_introduction_derives_fully_evidenced_products_holds (returned false). None is an expected-red row: that roster asserts the identity executes, and these do not while the family is outside the gate" as NonEmptyStr,
}
26 changes: 23 additions & 3 deletions dag/std/kind.dag
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import std.occurrence_identity { OccurrenceSynthetic }
import v2.std.algebra { filter, fold_list, list_flat_map }
import v2.std.collection { List, empty_map, map_insert, map_lookup }
import std.types { Map }
import v2.std.node { Atom, Node, Symbol, TypeNode, node_subtree_nodes }
import v2.std.node { Atom, Node, Symbol, TypeNode, arrow_signature_order_edge }
import v2.std.node_query { NamedChildAmbiguous, NamedChildFound, NamedChildMissing, named_child_lookup }
import v2.std.optional { Optional }

Expand Down Expand Up @@ -72,11 +72,31 @@ type RosterKindIndex {
kinds: Map<Node, Kind>
}

// A ROSTER'S MEMBERS ARE ITS VALUES, NOT ITS LABEL METADATA. An Arrow member built through
// v2.std.arrow_signature carries a declared-order edge whose subtree is the domain's binder labels
// (a FreeMonoid ending in a childless Conj), not a value the Arrow is built from; infer already
// carries that edge as metadata and derives nothing from it. Walking it entered those label nodes
// as TypeDenotationKind members, so every structurally equal node anywhere -- a bare childless
// Conj -- derived a kind by lookup (gunbc#12625 rebuilt dag_fixture_emitted_add_fn with the edge).
// The edge is classified by v2.std.node arrow_signature_order_edge, the one predicate infer asks.
// Membership is still decided by STRUCTURAL equality with a node in the roster value; keying it by
// declared identity is the namespace migration's end-state named in v2.compiler.infer
// (gunbc.recurring_failure_mode roster_membership_by_structural_equality).
fn roster_member_nodes(root: Node) -> List<Node> {
fold(root.children, init: [root], f: fn(acc, edge) {
if arrow_signature_order_edge(parent: root, edge: edge) {
acc
} else {
concat(acc, roster_member_nodes(root: edge.target))
}
})
}

fn kind_record_fact_nodes(record: Node, subject_field: Symbol) -> List<Node> {
match named_child_lookup(root: record, name: subject_field) {
NamedChildFound { target: subject } =>
filter(
xs: node_subtree_nodes(root: record),
xs: roster_member_nodes(root: record),
predicate: fn(member) { !(member == record) && !(member == subject) }
)
NamedChildMissing => []
Expand All @@ -97,7 +117,7 @@ fn roster_kind_enter_one(kinds: Map<Node, Kind>, n: Node, kind: Kind) -> Map<Nod
}

fn roster_kind_index(roster: Node, subject_field: Symbol) -> RosterKindIndex {
let members = node_subtree_nodes(root: roster)
let members = roster_member_nodes(root: roster)
let denotations = roster_kind_enter(kinds: empty_map(), nodes: members, kind: TypeDenotationKind)
RosterKindIndex {
kinds: roster_kind_enter(
Expand Down
Loading