Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
22f252b
The eval driver's verb surface becomes a plan, the way the CLI driver…
briansrls Sep 21, 2026
b562cd8
The rendered eval-driver main calls the plan fold; its literal verb d…
Sep 21, 2026
1ee57f8
Regenerate the stage0 emitter mirror for the plan-fold main
Sep 21, 2026
a02ad67
Name facts_path as a known-wrong shape with its capability trigger
Sep 21, 2026
18f5ff4
Delete the dangling facts-path accessor; pin misuse status by its aut…
Sep 21, 2026
0523f39
Merge remote-tracking branch 'origin/main' into feat/native-driver-pl…
Sep 21, 2026
4b4f29c
Restore the emitted main's closing brace
Sep 21, 2026
1c64418
Regenerate the stage0 emitter mirror for the restored brace
Sep 21, 2026
b6e4f80
Merge remote-tracking branch 'origin/main' into feat/native-driver-pl…
Sep 21, 2026
d83559a
Merge remote-tracking branch 'origin/main' into feat/native-driver-pl…
Sep 21, 2026
9503030
Regenerate the stage0 emitter mirror over merged main
Sep 21, 2026
2d1f917
Merge remote-tracking branch 'origin/main' into feat/native-driver-pl…
Sep 21, 2026
1497db9
adjudicate takes a target-pattern operand and derives the selected un…
Sep 21, 2026
1d8095b
Regenerate the stage0 emitter mirror for the adjudicate pattern opera…
Sep 21, 2026
b52c7b5
Merge remote-tracking branch 'origin/main' into feat/native-driver-pl…
Sep 21, 2026
81dd67a
wip: leading-pipe coproduct and positional variant payload grammar rows
Sep 21, 2026
318a377
Witness the leading-pipe coproduct and positional payload rows on the…
Sep 21, 2026
cb1fe17
Leading separator lowers away in sugar; positional binders refuse; on…
Sep 21, 2026
dbaf88c
Positional refusal fires only on a payload that names something; A(_)…
Sep 21, 2026
f49dd9e
Consume body_lower_is_identity_projection_edge instead of re-declarin…
Sep 21, 2026
0b6e27d
Witness specimens carry only their subject: elimination controls drop…
Sep 21, 2026
03f449a
chore: regenerate drifted generated artifacts (ci auto-heal)
gunbai-bot[bot] Sep 21, 2026
1ff83c3
Declare and defer the binder loss (ruling after review 69815): positi…
Sep 22, 2026
c5aecdc
Merge CI auto-heal regen; the projection is re-derived from the amend…
Sep 22, 2026
5871307
Merge branch 'integ/pkg9-native-test-argv' of https://github.com/gunb…
Sep 22, 2026
62666cc
Merge remote-tracking branch 'origin/session/gentle-tern-521' into se…
Sep 22, 2026
fd3475c
Pkg11b batch 2 (continued from gentle-tern-521): generic int arg, mod…
Sep 22, 2026
9d3dcd1
Parse-tree projection edges are a closed roster owned by the parser; …
Sep 22, 2026
cc56c58
Merge origin/main; bind Symbol at its use site, and take main's proje…
Sep 22, 2026
6792e92
Finish the projection-roster migration at its root: delete the graft …
Sep 22, 2026
789aa87
chore: regenerate drifted generated artifacts (ci auto-heal)
gunbai-bot[bot] Sep 22, 2026
7b3a0c7
Merge remote-tracking branch 'origin/main' into pkg11b-fix
Sep 22, 2026
6668aaf
Rebuild the rung-drop projection as the union: take main's render, ke…
Sep 22, 2026
5ff32e2
Merge remote-tracking branch 'origin/main' into pkg11b-fix
Sep 22, 2026
44a910c
Merge origin/main into #12050 after #12033/#12108/#12116; keep only P…
Sep 23, 2026
02ea6fd
Repair the #12050 merge: split the fused CauseOwnership row; batch tw…
Sep 23, 2026
d56ed9f
chore: regenerate drifted generated artifacts (ci auto-heal)
gunbai-bot[bot] Sep 23, 2026
a887f5b
Merge remote-tracking branch 'origin/main' into adopt-12050
Sep 23, 2026
4a4d922
Batch two: one prepared input per specimen, warmed outside the fold
Sep 23, 2026
4312fa0
chore: regenerate drifted generated artifacts (ci auto-heal)
gunbai-bot[bot] Sep 23, 2026
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,35 @@
module gunbc.rung_drop.admit_callers_discarded_on_the_native_route

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

// DECLARED 2026-09-22 (Pkg11b batch 2, ruling via neat-boar-16). `admit_callers: [decl_ref(..)]`
// on a fn names the only declarations allowed to call it; the seed parses it as a property of the
// fn node (v1.compiler.parse parse_optional_admit_callers). The native front end now parses the
// clause (v2.extdeps.languages.dag dag_grammar_admit_callers_clause_expr) and DISCARDS it when the
// fn lowers to an Arrow, so caller admission is not enforced on the native route. It is not carried
// on the Arrow because nothing would read it: v2.std.node arrow_signature_edges_conform admits only
// arrow_body_edge, and widening a load-bearing substrate type for an edge with no consumer would be
// a dangling declaration. The stage that checks caller admission adds that carrier with its consumer.
// The empty-list refusal (`admit_callers: []`) is kept.

data admit_callers_discarded_on_the_native_route_population: List<String> = [
"the native lane (std.compiler_entry SourceRootEvalDriver) -- every fn declaring admit_callers, the clause parsed and discarded at fn lowering",
]

data admit_callers_discarded_on_the_native_route: RungDrop = RungDrop {
identity: "admit_callers_discarded_on_the_native_route" as NonEmptyStr,
subject: "native route enforces admit_callers: a call from a declaration outside a fn's admitted caller list refuses",
declared: "2026-09-22",
standing: Standing,
declaration: TypedDeclaration {
previous: MechanicallyPreventable,
temporary: Mitigatable,
reason: ReplacementStaged {
replacement: "a v2 stage checks caller admission; that stage adds the Arrow carrier with its consumer"
},
population: admit_callers_discarded_on_the_native_route_population,
restoration_trigger: "a v2 stage checks caller admission on the native route from the fn's declared admit_callers list, refusing a call from a declaration outside it; that stage adds the Arrow carrier together with its consumer. Parsing the clause, or carrying the list with nothing reading it, does not retire this row."
}
}
2 changes: 2 additions & 0 deletions dag/gunbc/rung_drop/roster.dag
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ import gunbc.rung_drop.persisted_resolved_graph_disk_probe_unqualified_format {
import gunbc.rung_drop.self_host_emit_derisk_claim_unobserved { self_host_emit_derisk_claim_unobserved }
import gunbc.rung_drop.g0_type_decl_modifier_parse_without_sealing_property { g0_type_decl_modifier_parse_without_sealing_property }
import gunbc.rung_drop.variant_fields_unlowered_on_the_native_route { variant_fields_unlowered_on_the_native_route }
import gunbc.rung_drop.admit_callers_discarded_on_the_native_route { admit_callers_discarded_on_the_native_route }
import gunbc.rung_drop.postfix_suffix_step_declined_to_the_pre_existing_arms { postfix_suffix_step_declined_to_the_pre_existing_arms }
import gunbc.rung_drop.fabric_storage_append_principal_unrefused { fabric_storage_append_principal_unrefused }
import gunbc.rung_drop.namespace_wave_admission_wall_removed { namespace_wave_admission_wall_removed }
Expand Down Expand Up @@ -176,6 +177,7 @@ data rung_drop_roster: List<RungDrop> = [
self_host_emit_derisk_claim_unobserved,
g0_type_decl_modifier_parse_without_sealing_property,
variant_fields_unlowered_on_the_native_route,
admit_callers_discarded_on_the_native_route,
postfix_suffix_step_declined_to_the_pre_existing_arms,
approval_store_single_writer_by_agreement,
fabric_storage_append_principal_unrefused,
Expand Down
4 changes: 4 additions & 0 deletions docs/design-rung-drops.md
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,10 @@ native G0 path records sole_constructor as a type-item property, the way v1 pars

native route lowers variant fields, named and positional, into declared field identities and binds pattern binders from them, the way the seed does: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: a v2 stage lowers variant fields into declared field identities (named and positional "0")). Population: the emitted (native-route) compiler: variant-field lowering and match-arm binder binding are executed by the interpreted v2 stages but not yet observed on the native route (the emitted compiler builds since gunbc#12089; the native run over the specimen is deferred until gunbc#12100 fixes the compile.emit cost); specimen: the binder `node` of the `Present { value: node }` arms of v2.std.symbol_index symbol_index_candidates_at. Restored when: the emitted compiler builds, and on that native route the specimen is observed: the binder `node` in v2.std.symbol_index symbol_index_candidates_at binds its arm and a positional `A(x)` construction and match round-trip field "0". A declaration-kind classifier alone (gunbc#12082) does NOT satisfy this: it changes how the interpreted stages decide, not whether the native route is observed.

### native route enforces admit_callers: a call from a declaration outside a fn's admitted caller list refuses — declared 2026-09-22

native route enforces admit_callers: a call from a declaration outside a fn's admitted caller list refuses: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: a v2 stage checks caller admission; that stage adds the Arrow carrier with its consumer). Population: the native lane (std.compiler_entry SourceRootEvalDriver) -- every fn declaring admit_callers, the clause parsed and discarded at fn lowering. Restored when: a v2 stage checks caller admission on the native route from the fn's declared admit_callers list, refusing a call from a declaration outside it; that stage adds the Arrow carrier together with its consumer. Parsing the clause, or carrying the list with nothing reading it, does not retire this row.

### native-route body lowering either lowers a postfix chain step whose suffix is a brace record-literal or an `as` suffix, or refuses it located — declared 2026-09-23

native-route body lowering either lowers a postfix chain step whose suffix is a brace record-literal or an `as` suffix, or refuses it located: RUNG DROP, mechanically preventable -> mitigatable (replacement staged: a construct tag that carries a qualified name, so the one-walk postfix chain door lowers `a.b.C { f: v }` as a construction and an `as` step as its conversion). Population: every module over dag + src/v2 for which v2.compiler.body_lowering_fold emits body_lowering_reason_postfix_suffix_carried: a postfix chain step whose suffix is a brace record-literal (`a.b.C { f: v }`) or an `as` suffix. the population is re-derived, not transcribed: the workload adjudicate over dag + src/v2 (claim_executor --v2-native-route) counts the advisory per module. Restored when: native-route body lowering LOWERS every brace-suffix and `as`-suffix postfix step in dag + src/v2, so that body_lowering_reason_postfix_suffix_carried is emitted for zero modules in the workload adjudicate. Alternatively the door REFUSES those steps located, with no module that accepts on base refusing for any other reason. Changing the construct tag alone does not satisfy this: the trigger is that the population is lowered or refused, not that the carrier exists.
Expand Down
18 changes: 18 additions & 0 deletions src/v2/compiler/02_parse.dag
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,24 @@ fn parse_stamp_derived_repeat(
}
}

// THE PARSE TREE'S PROJECTION EDGES, AS A CLOSED ROSTER OWNED BY THEIR PRODUCER. A parse tree
// carries exactly four Named edges that are parse-projection structure rather than authored
// program data: the production identity and captured pair stamped by parse_wrap_production_captured,
// and the sequence left/right pair stamped by the sequence and list spines. Every later stage that
// must see through projection structure (namespace_graft, name_resolve, symbol_index_fill) asks
// THIS predicate. It was a lexeme-suffix test on "_node_projection" before, and a suffix is a
// heuristic (DESIGN section 4): an authored fn or data declaration whose name ends in
// `_node_projection` (v2.std.runtime runtime_value_node_projection and its siblings) matched it and
// was dissolved at the module body -- one such declaration vanished SILENTLY, two collided into an
// ill-formed Conj. The roster is what the grammar_named_edge sites below actually mint; a projection
// edge added there is added here, and a name outside it is program data by construction.
fn parse_tree_projection_edge(name: Symbol) -> Bool {
(name == ^grammar_production_identity_node_projection)
|| (name == ^grammar_production_captured_node_projection)
|| (name == ^grammar_sequence_left_node_projection)
|| (name == ^grammar_sequence_right_node_projection)
}

fn parse_wrap_production_captured(
production: GrammarProduction,
captured: Node,
Expand Down
4 changes: 2 additions & 2 deletions src/v2/compiler/03_name_resolve.dag
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ import v2.extdeps.languages.dag {
qualified_name_from_module_node
}
import v2.compiler.namespace_graft {
namespace_graft_parse_projection_edge,
namespace_graft_strip_provenance_marker
}
import v2.compiler.parse { parse_tree_projection_edge }
import std.algebra { Cons, Empty, FreeMonoid }
import v2.std.algebra { fold_list }
import v2.std.collection { Absent, Map, Present, List, PointwisePower, empty_map, map_get, map_lookup, map_insert, optional_absent, optional_present }
Expand Down Expand Up @@ -372,7 +372,7 @@ fn try_admitted_export_binding(e: Edge) -> DeclaredBinding? {
Present { value: b } =>
if dag_surface_module_header_metadata_edge(name: b.name) {
optional_absent()
} else if namespace_graft_parse_projection_edge(name: b.name) {
} else if parse_tree_projection_edge(name: b.name) {
optional_absent()
} else {
optional_present(value: b)
Expand Down
118 changes: 73 additions & 45 deletions src/v2/compiler/body_lowering_fold.dag
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@ fn body_lower_is_structure_preserved_emitted(emitted: Symbol) -> Bool {
|| (emitted == ^dag_surface_type_alias_rhs_lead)
|| (emitted == ^dag_surface_field_decl_block)
|| (emitted == ^dag_surface_positional_variant_payload)
|| (emitted == ^dag_surface_admit_callers_clause)
|| (emitted == ^dag_surface_fn_type)
|| (emitted == ^dag_surface_field_init)
|| (emitted == ^dag_surface_where_refinement_clause)
Expand Down Expand Up @@ -2541,51 +2542,64 @@ fn body_lower_test_fn_decl_to_member(shell: Node) -> Outcome<Node> {
}
}

// THE WALL SITS AT THE FN, NOT ONLY AT THE STATEMENT. A fn body is lowered DEFERRED, from the raw
// parse subtree by this function's own navigation, so its statements never pass through
// body_lower_after_children one by one; body_lower_body_subtree_lower_from_primary would instead
// find the first primary expression inside an else-less `if` -- its condition -- and return THAT as
// the body, silently discarding the guard and every statement after it. So the fn refuses the whole
// declaration when its subtree holds one, with the same typed cause the statement arm raises.
fn body_lower_fn_decl_to_arrow(shell: Node) -> Outcome<Node> {
match body_lower_unwrap_captured(shell: shell) {
Absent => body_lower_wrapper_retained_shell(shell: shell)
Present { value: captured } =>
match body_lower_find_captured(root: captured, emitted: ^dag_surface_param_list) {
ParseSubtreeAbsent => body_lower_wrapper_retained_shell(shell: shell)
ParseSubtreeFound { captured: param_list } =>
match body_lower_domain_from_param_list(param_list: param_list) {
Absent => body_lower_wrapper_retained_shell(shell: shell)
Present { value: domain } =>
match body_lower_body_from_fn_captured(captured: captured) {
Rejected { diagnostics: r } => Rejected { diagnostics: r }
Accepted { value: body_opt, diagnostics: bd0 } =>
match body_opt {
Absent => body_lower_wrapper_retained_shell(shell: shell)
Present { value: body } =>
match body_lower_reify_arrow_body(body: body) {
Rejected { diagnostics: r } => Rejected { diagnostics: r }
Accepted { value: reified_body, diagnostics: bd } =>
match body_lower_return_type_from_fn_captured(captured: captured) {
match body_lower_find_captured(root: captured, emitted: ^dag_surface_else_less_if_stmt) {
ParseSubtreeFound { captured: guard } => body_lower_else_less_if_reject(shell: guard)
ParseSubtreeAbsent => body_lower_fn_decl_to_arrow_admitted(shell: shell, captured: captured)
}
}
}

fn body_lower_fn_decl_to_arrow_admitted(shell: Node, captured: Node) -> Outcome<Node> {
match body_lower_find_captured(root: captured, emitted: ^dag_surface_param_list) {
ParseSubtreeAbsent => body_lower_wrapper_retained_shell(shell: shell)
ParseSubtreeFound { captured: param_list } =>
match body_lower_domain_from_param_list(param_list: param_list) {
Absent => body_lower_wrapper_retained_shell(shell: shell)
Present { value: domain } =>
match body_lower_body_from_fn_captured(captured: captured) {
Rejected { diagnostics: r } => Rejected { diagnostics: r }
Accepted { value: body_opt, diagnostics: bd0 } =>
match body_opt {
Absent => body_lower_wrapper_retained_shell(shell: shell)
Present { value: body } =>
match body_lower_reify_arrow_body(body: body) {
Rejected { diagnostics: r } => Rejected { diagnostics: r }
Accepted { value: reified_body, diagnostics: bd } =>
match body_lower_return_type_from_fn_captured(captured: captured) {
Absent => body_lower_wrapper_retained_shell(shell: shell)
Present { value: return_type } =>
match dag_surface_kw_then_ident_from_captured(captured: captured) {
Absent => body_lower_wrapper_retained_shell(shell: shell)
Present { value: return_type } =>
match dag_surface_kw_then_ident_from_captured(captured: captured) {
Absent => body_lower_wrapper_retained_shell(shell: shell)
Present { value: fn_name } =>
let arrow = node_synthetic(
kind: TypeNode { connective: Arrow },
children: [
Edge { label: Positional, target: domain },
Edge { label: Positional, target: return_type },
Edge { label: Positional, target: return_type },
Edge {
label: Named { name: ^arrow_body_edge },
target: reified_body
}
]
)
outcome_with_diagnostics(
value: body_lower_fn_decl_named_member_wrap(
arrow: arrow,
fn_name: fn_name
),
diagnostics: diagnostics_merge(outer: bd0, inner: bd)
)
}
Present { value: fn_name } =>
let arrow = node_synthetic(
kind: TypeNode { connective: Arrow },
children: [
Edge { label: Positional, target: domain },
Edge { label: Positional, target: return_type },
Edge { label: Positional, target: return_type },
Edge {
label: Named { name: ^arrow_body_edge },
target: reified_body
}
]
)
outcome_with_diagnostics(
value: body_lower_fn_decl_named_member_wrap(
arrow: arrow,
fn_name: fn_name
),
diagnostics: diagnostics_merge(outer: bd0, inner: bd)
)
}
}
}
Expand Down Expand Up @@ -6340,6 +6354,16 @@ fn body_lower_production_emitted(shell: Node, emitted: Symbol, fn_body_pass_thro
}
}

// AN ELSE-LESS `if` IS REFUSED, NEVER DROPPED OR REWRITTEN. It is an early exit
// (v2.extdeps.languages.dag dag_grammar_else_less_if_stmt_expr), and the v2 core has no lowering for
// early exit yet; lowering it to Branch(cond, then, rest-of-block) is a separate control-flow model.
// Until that lands the statement is a typed, located, counted refusal.
fn body_lower_else_less_if_reject(shell: Node) -> Outcome<Node> {
outcome_rejected(
d: body_lower_diagnostic(reason: ^body_lowering_reason_else_less_if_unlowered, n: shell)
)
}

fn body_lower_after_children(folded: Node, fn_body_pass_through: Bool) -> Outcome<Node> {
if body_lower_is_core_substrate(node: folded) {
outcome_accepted(value: folded)
Expand All @@ -6349,11 +6373,15 @@ fn body_lower_after_children(folded: Node, fn_body_pass_through: Bool) -> Outcom
match parse_production_emitted_identity_optional(node: folded) {
Absent => outcome_accepted(value: folded)
Present { value: emitted } =>
body_lower_production_emitted(
shell: folded,
emitted: emitted,
fn_body_pass_through: fn_body_pass_through
)
if emitted == ^dag_surface_else_less_if_stmt {
body_lower_else_less_if_reject(shell: folded)
} else {
body_lower_production_emitted(
shell: folded,
emitted: emitted,
fn_body_pass_through: fn_body_pass_through
)
}
}
}
}
Expand Down
14 changes: 4 additions & 10 deletions src/v2/compiler/namespace_graft.dag
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import v2.std.node {
TypeNode,
}
import v2.std.qualified_name { QualifiedName }
import v2.std.compilers.lexing { symbol_lexeme }
import v2.compiler.parse { parse_tree_projection_edge }
import v2.std.grammar {
GrammarExpr,
GrammarExprFold,
Expand Down Expand Up @@ -99,12 +99,6 @@ fn namespace_graft_is_module_shell(root: Node) -> Bool {
}
}

fn namespace_graft_parse_projection_edge(name: Symbol) -> Bool {
(name == ^grammar_production_identity_node_projection)
|| (name == ^grammar_production_captured_node_projection)
|| ends_with(s: symbol_lexeme(sym: name), suffix: "_node_projection")
}

fn namespace_graft_is_transparent_sequence_spine(node: Node) -> Bool {
match node.kind {
TypeNode { connective: Conj } =>
Expand All @@ -116,7 +110,7 @@ fn namespace_graft_is_transparent_sequence_spine(node: Node) -> Bool {
false
} else {
match e.label {
Named { name: sym } => namespace_graft_parse_projection_edge(name: sym)
Named { name: sym } => parse_tree_projection_edge(name: sym)
Positional => true
}
}
Expand All @@ -138,7 +132,7 @@ fn namespace_graft_collect_body_edge(
Named { name: sym } =>
if namespace_graft_is_metadata_edge(name: sym) {
acc
} else if namespace_graft_parse_projection_edge(name: sym) {
} else if parse_tree_projection_edge(name: sym) {
concat(acc, namespace_graft_collect_body_edges_from_node(node: edge.target, unit_ids: unit_ids))
} else if dag_resolve_preserve_module_metadata_subtree(node: edge.target) {
acc
Expand Down Expand Up @@ -472,7 +466,7 @@ fn namespace_graft_partition_decl_units(units: List<Node>) -> NamespaceGraftDecl
fn namespace_graft_keep_flattened_member_edge(edge: Edge) -> Bool {
match edge.label {
Named { name: sym } =>
if namespace_graft_parse_projection_edge(name: sym) {
if parse_tree_projection_edge(name: sym) {
false
} else if namespace_graft_is_metadata_edge(name: sym) {
false
Expand Down
Loading