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
1 change: 1 addition & 0 deletions dag/extdeps/languages/rust/emit.dag
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ data rt_function_registry: List<RuntimeFunction> = [
{ name: "chars_to_string", bridge_name: "chars_to_string", passes_by_ref: true, wraps_result: false },
{ name: "record_source_chars_index_lookup", bridge_name: "record_source_chars_index_lookup", passes_by_ref: false, wraps_result: false },
{ name: "resolution_silent_pick_is_enabled", bridge_name: "resolution_silent_pick_is_enabled", passes_by_ref: false, wraps_result: false },
{ name: "name_resolution_policy_is_namespace_only", bridge_name: "name_resolution_policy_is_namespace_only", passes_by_ref: false, wraps_result: false },
{ name: "resolution_silent_pick_record_global_bare_lcp_pick", bridge_name: "resolution_silent_pick_record_global_bare_lcp_pick", passes_by_ref: false, wraps_result: false },
{ name: "resolution_silent_pick_record_global_bare_lcp_tie", bridge_name: "resolution_silent_pick_record_global_bare_lcp_tie", passes_by_ref: false, wraps_result: false },
{ name: "resolution_silent_pick_record_fn_parent_first_hit", bridge_name: "resolution_silent_pick_record_fn_parent_first_hit", passes_by_ref: false, wraps_result: false },
Expand Down
1 change: 1 addition & 0 deletions dag/test/retirement/model.dag
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module test.retirement.model
type RetirementDisposition
= DeleteRedundant { covered_by: String }
| DeleteLowValue { reason: String }
| RetainedNonMigratable { reason: String }

type TestModuleRetirement {
module: String
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module test.retirement.namespace_unique_on_chain_policy_retained


data namespace_unique_on_chain_policy_retention: TestModuleRetirement = TestModuleRetirement {
module: "namespace_unique_on_chain_policy_test.rs",
disposition: RetainedNonMigratable {
reason: "The namespace-resolution-design.md section-13 keystone witness toggles the host thread-local NameResolutionPolicy gate (v1_rt.name_resolution_policy_set_namespace_only) between ImportScoped and NamespaceOnlyY, then compiles homonym fixtures and asserts the strict policy refuses with AmbiguousReference where the default resolves. That thread-local process-state toggle is host-Rust-only and is unreachable from a dag witness (a substrate program has no handle to flip the seed interpreter's resolution policy), so this module cannot migrate to an exact-stem test dag floor witness. It is therefore RETAINED as rs, not migration debt and not a delete candidate. This retention dissolves when src/v1 is deleted at v2 self-host, at which point the policy gate and its host toggle cease to exist."
}
}
53 changes: 49 additions & 4 deletions docs/plans/namespace-resolution-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ values `{ import-scoped (§1c, today) , namespace-only-X , namespace-only-Y }`.

1. Land `resolve(name, position)` + the `Ambiguous`/`Unresolved` outcomes beside the current
resolver, gated by the policy row (import-scoped stays the default → zero corpus churn).
**LANDED 2026-07-22** in the executing v1 seed under the §13 unique-on-chain semantics
(which supersede this section's original nearest-wins wording) — see the §13 "STEP 1
LANDED" entry for the mechanism, edit sites, and the discriminating witness.
2. The **precise census is already run** (§5.1, declared `module` paths): the exact
forced-qualification residue and the fork worklist are its outputs — steps 3–4 act on them,
no re-run.
Expand Down Expand Up @@ -629,7 +632,9 @@ from *build a fourth resolver* into *delete a fork*.
ancestor walk; the tree is materialized once by fill (§7.5's fill-once discipline), so §6's
"bare minimum cost" is satisfied by construction rather than by measurement. *This is the
claim most worth falsifying before implementation — it is the difference between a cheap
substitution and a rewrite.*
substitution and a rewrite.* **FALSIFICATION RUN — the claim held (2026-07-22, §12.4
delivery):** lexical_steps_histogram={1: 17175, 2: 1} over 37,521 containment hits — a
substitution, not a rewrite.
- **Migration rides §8 unchanged.** When a subtree flips to `namespace-only-Y`, its runtime
dispatch keys on the same index in the same motion. The two cannot drift because there is only
one thing; a flip that moved resolution without moving dispatch would re-open the fork.
Expand Down Expand Up @@ -691,6 +696,23 @@ and the lane's shape changes. This is the cheapest moment to find out.
**Do not** flip any policy, edit any resolver, or change dispatch as part of this. The census is an
artifact the rest of the lane consumes; §8 step 1 starts after it, informed by it.

**DELIVERED — and §8 step 1 has consumed it (2026-07-22).** The census shipped as
`resolution_divergence_census` (#6936 slice 1, #6967 slice 2); the fresh pre-step-1 run
(whole tree, `dag` + `src/v2`; raw rows in
`docs/probes/resolution_divergence_census_2026-07-22.tsv`): modules_resolved=1309,
sites_checked=40592 — **agree=33422 / diverge=0 / containment_ambiguous=38 /
containment_unresolved=0**, import_unresolved=4099 (walk-vs-infer cross-check
mismatch=0), neither_bound=3033 (builtin_or_intrinsic=1422, local_or_param=1607,
genuinely_unbound=4), agree-global-unique owner_mismatch=0. Cost shape (the §12.3
falsification): containment hits=37521, lexical_steps_histogram={1: 17175, 2: 1},
global_unique=20345 — the walk is O(chain depth) map hits with depth almost always 1,
so the fold is a **substitution, not a rewrite**; the claim held. One genuine §13
fail-open surfaced by the silent-pick join (both whole-tree and closure-scoped scopes,
pre-existing on main): `gunbc.falsifier_workflow` bare `ci_repo_root_shell` first-hits
`gunbc.ci_spec` over the identical duplicate decl in `gunbc.merge_admission_produce`
(fn_parent_first_hit=1) — a real §3 fork needing consolidation or qualification, and
the live specimen of the class §8 step 1's refusal arm makes loud under the flip.

Related: [type environment: single import authority + scope cursor](type-env-single-authority-design.md) — the type-env/SymbolIndex lane design this walk-rule migration rides on · [interface summaries and the declared↔use arity family](interface-summary-declared-use-arity.md) — the `std.interface_summary` carrier consumed by interface-grain resolve.

## 13. Resolution is unique-on-chain, not nearest (operator ruling, ratified 2026-07-21)
Expand Down Expand Up @@ -730,20 +752,43 @@ target is encoded **once** (no dual representation), an unused alias is lintable
surface form is a grammar row (DESIGN.md §4, one grammar read both directions). **Import→alias
transmutation** is the migration mechanism — an `import` becomes an alias node at the importing
position, and the **source of truth is the walk's resolved target**, with the old import list
demoted to a cross-check. Grounded by #6936's buckets: agree=38138 / import_unresolved=1854 /
neither_bound=739 / ambiguous=53.
demoted to a cross-check. Grounded by the census buckets (#6936 first run: agree=38138 /
import_unresolved=1854 / neither_bound=739 / ambiguous=53; refreshed 2026-07-22 pre-step-1:
agree=33422 / import_unresolved=4099 / neither_bound=3033 / ambiguous=38, diverge=0 —
`docs/probes/resolution_divergence_census_2026-07-22.tsv`).

**`global_bare` dies as a mechanism.** The terminal state **deletes**
`symbol_index_global_unique_lookup` / `GlobalBareLookup` as *resolution* mechanisms — they survive
only as a migration oracle (computing the §12.4 divergence census), then are removed. This
supersedes §7's "the wall moves to *is it unique?*": the wall is *is it unique **on your chain?***
The executing seed's two interim gaps are named, not hidden: the fn path (`lookup_resolved_sig`,
`v1_compiler_infer_sigs.rs:111-117` — first-hit over `func_env.parents`, **no refusal arm at all**)
`v1_compiler_infer_sigs.rs` — first-hit over `func_env.parents`, **no refusal arm at all**)
and the type/data LCP nearest-arm (`global_bare_lookup`, `v1_compiler_infer_env.rs` — refuses only
on an exact tie). The §5 interim backstop plus still-hawk-65's slice-2 per-class silent-pick counts
gate any widening (§12.4; do not widen blind — refusing where nothing refuses today reds latent
homonyms at scale, and fn is the larger class since it has *no* refusal today).

**§8 STEP 1 LANDED (2026-07-22) — both gaps now have policy-gated strict arms in the executing
seed.** A thread-local `NameResolutionPolicy` gate (`name_resolution_policy_is_namespace_only`,
`v1_rt`, host-setter only, **default OFF = ImportScoped byte-for-byte**) forks both paths:
the type/value path (`global_bare_lookup` / `global_bare_is_ambiguous`,
`src/v1/04_env.dag`) resolves a homonym to the **unique binder on the ancestor chain**
(exactly-one resolves; zero-or-multiple refuses — zero-on-chain whole-pool homonyms are
`Ambiguous`, census-walk parity, never a fabricated bind), and the fn path is rewritten to the
3-state `FuncSigLookup = FuncSigResolved | FuncSigUnresolved | FuncSigAmbiguous{candidates}`
(`src/v1/04_sigs.dag` / `04_lookup.dag`) so a refusal finally **has somewhere to go** — the
`Absent`-as-"keep-looking" straddle is dead as a class, and `FuncSigAmbiguous` never falls
through to the census fallback. Refusals surface as the typed, located
`AmbiguousReference { name, candidates, span }` diagnostic (`00_core.dag`) at the reference
site with the full candidate fix-menu. Analysis-only consumers (provenance/descent) project
through `func_sig_if_resolved` — conservative no-enrichment, never a fabricated bind; the
semantic bind sites (`04_infer.dag` ExprVar/ExprCall) match the full outcome. Discriminating
witness: `src/v1/tests/src/namespace_unique_on_chain_policy_test.rs` — the same homonym
fixtures compile clean under ImportScoped and refuse (typed, full candidate list) under
NamespaceOnlyY on both paths, with unique-on-chain-still-resolves and
unbound-stays-`UnresolvedType` controls. No subtree is flipped; the flip (step 4) still
gates on import→alias transmutation landing with-or-before it.

**Builtins bind at root.** The root namespace is on **every** chain, so builtins bound at root are
unique-on-chain everywhere — this **structurally dissolves** the prelude-shaped `neither_bound`
class (#6936, 739) rather than special-casing it, pending still-hawk's confirmation of the (c)
Expand Down
54 changes: 54 additions & 0 deletions docs/probes/resolution_divergence_census_2026-07-22.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
[resolution-divergence-census] scope=dag+src/v2 modules_resolved=1309 modules_excluded=0
[resolution-divergence-census] sites_checked=40592
[resolution-divergence-census] agree=33422
[resolution-divergence-census] diverge=0
[resolution-divergence-census] containment_ambiguous=38
[resolution-divergence-census] containment_unresolved=0
[resolution-divergence-census] import_unresolved=4099
[resolution-divergence-census] neither_bound=3033
[resolution-divergence-census] neither_bound_subclass builtin_or_intrinsic=1422 local_or_param=1607 genuinely_unbound=4
[resolution-divergence-census] silent_pick global_bare_lcp=1045 global_bare_lcp_tie=13692 fn_parent_first_hit=1
[resolution-divergence-census] agree_global_unique_owner_rows=16246 owner_mismatch=0
[resolution-divergence-census] import_unresolved_infer_cross_check agree=4099 mismatch=0
[resolution-divergence-census] cost_shape hits=37521 lexical_only=17176 global_unique=20345 lexical_steps_histogram={1: 17175, 2: 1}

CONTAINMENT_AMBIGUOUS module=std.layout caller=render_go callee=repeat_string at=/workspace/dag/std/layout.dag@949 via=n/a import_chain=std.render_repeat_string_bootstrap (std.render_repeat_string_bootstrap.repeat_string)
CONTAINMENT_AMBIGUOUS module=extdeps.formats.dnsmasq caller=serialize_dnsmasq callee=render at=/workspace/dag/extdeps/formats/dnsmasq.dag@1829 via=n/a import_chain=std.layout (std.layout.render)
CONTAINMENT_AMBIGUOUS module=extdeps.git.versioning caller=git_release_version_compare callee=nat_compare at=/workspace/dag/extdeps/git/versioning.dag@1535 via=n/a import_chain=std.nat (std.nat.nat_compare)
CONTAINMENT_AMBIGUOUS module=extdeps.git.versioning caller=git_release_version_compare callee=nat_compare at=/workspace/dag/extdeps/git/versioning.dag@1592 via=n/a import_chain=std.nat (std.nat.nat_compare)
CONTAINMENT_AMBIGUOUS module=extdeps.git.versioning caller=git_release_version_compare callee=nat_compare at=/workspace/dag/extdeps/git/versioning.dag@1645 via=n/a import_chain=std.nat (std.nat.nat_compare)
CONTAINMENT_AMBIGUOUS module=extdeps.languages.yaml.emit caller=serialize_yaml callee=render at=/workspace/dag/extdeps/languages/yaml/emit.dag@6462 via=n/a import_chain=std.layout (std.layout.render)
CONTAINMENT_AMBIGUOUS module=extdeps.version.semver caller=semver_compare_non_negative_int callee=nat_compare at=/workspace/dag/extdeps/version/semver.dag@996 via=n/a import_chain=std.nat (std.nat.nat_compare)
CONTAINMENT_AMBIGUOUS module=test.claim.machine_shape_catalog_integration_witness caller=cpu_catalog_shape callee=shape_from_catalog at=/workspace/dag/test/claim/machine_shape_catalog_integration_witness_test.dag@1032 via=n/a import_chain=extdeps.cpu.machine_shape (extdeps.cpu.machine_shape.shape_from_catalog)
CONTAINMENT_AMBIGUOUS module=extdeps.languages.markdown caller=md_item callee=repeat_string at=/workspace/dag/extdeps/languages/markdown.dag@4946 via=n/a import_chain=std.render_repeat_string_bootstrap (std.render_repeat_string_bootstrap.repeat_string)
CONTAINMENT_AMBIGUOUS module=extdeps.languages.markdown caller=md_item callee=repeat_string at=/workspace/dag/extdeps/languages/markdown.dag@5738 via=n/a import_chain=std.render_repeat_string_bootstrap (std.render_repeat_string_bootstrap.repeat_string)
CONTAINMENT_AMBIGUOUS module=extdeps.languages.markdown caller=md_item callee=repeat_string at=/workspace/dag/extdeps/languages/markdown.dag@5878 via=n/a import_chain=std.render_repeat_string_bootstrap (std.render_repeat_string_bootstrap.repeat_string)
CONTAINMENT_AMBIGUOUS module=extdeps.languages.markdown caller=md_item callee=repeat_string at=/workspace/dag/extdeps/languages/markdown.dag@6010 via=n/a import_chain=std.render_repeat_string_bootstrap (std.render_repeat_string_bootstrap.repeat_string)
CONTAINMENT_AMBIGUOUS module=extdeps.languages.markdown caller=md_item callee=repeat_string at=/workspace/dag/extdeps/languages/markdown.dag@6169 via=n/a import_chain=std.render_repeat_string_bootstrap (std.render_repeat_string_bootstrap.repeat_string)
CONTAINMENT_AMBIGUOUS module=extdeps.languages.markdown caller=md_item callee=repeat_string at=/workspace/dag/extdeps/languages/markdown.dag@6309 via=n/a import_chain=std.render_repeat_string_bootstrap (std.render_repeat_string_bootstrap.repeat_string)
CONTAINMENT_AMBIGUOUS module=extdeps.languages.markdown caller=md_item callee=repeat_string at=/workspace/dag/extdeps/languages/markdown.dag@6433 via=n/a import_chain=std.render_repeat_string_bootstrap (std.render_repeat_string_bootstrap.repeat_string)
CONTAINMENT_AMBIGUOUS module=extdeps.languages.markdown caller=md_block callee=repeat_string at=/workspace/dag/extdeps/languages/markdown.dag@10260 via=n/a import_chain=std.render_repeat_string_bootstrap (std.render_repeat_string_bootstrap.repeat_string)
CONTAINMENT_AMBIGUOUS module=extdeps.render.terminal caller=serialize_line callee=repeat_string at=/workspace/dag/extdeps/render/terminal.dag@3854 via=n/a import_chain=std.render (std.render.repeat_string)
CONTAINMENT_AMBIGUOUS module=test.claim.machine_shape_witness caller=shape_from_rtx5090_catalog callee=shape_from_catalog at=/workspace/dag/test/claim/machine_shape_witness_test.dag@1817 via=n/a import_chain=extdeps.gpu.machine_shape (extdeps.gpu.machine_shape.shape_from_catalog)
CONTAINMENT_AMBIGUOUS module=test.claim.machine_shape_witness caller=shape_from_m5_catalog callee=shape_from_catalog at=/workspace/dag/test/claim/machine_shape_witness_test.dag@3041 via=n/a import_chain=extdeps.gpu.machine_shape (extdeps.gpu.machine_shape.shape_from_catalog)
CONTAINMENT_AMBIGUOUS module=gunbc.gitignore_emit caller=expected_gitignore callee=render at=/workspace/dag/gunbc/gitignore_emit.dag@10701 via=n/a import_chain=std.layout (std.layout.render)
CONTAINMENT_AMBIGUOUS module=v2.lens.cost caller=nat_dominates callee=nat_compare at=/workspace/src/v2/lens/cost.dag@6949 via=n/a import_chain=v2.std.nat (v2.std.nat.nat_compare)
CONTAINMENT_AMBIGUOUS module=gunbc.runner_deploy_emit caller=expected_runner_deploy_manifest callee=render at=/workspace/dag/gunbc/runner_deploy_emit.dag@7785 via=n/a import_chain=std.layout (std.layout.render)
CONTAINMENT_AMBIGUOUS module=gunbc.runner_deploy_emit caller=expected_runner_deploy_manifest_json callee=render at=/workspace/dag/gunbc/runner_deploy_emit.dag@8105 via=n/a import_chain=std.layout (std.layout.render)
CONTAINMENT_AMBIGUOUS module=gunbc.runner_deploy_emit caller=expected_runner_deploy_manifest_json callee=render at=/workspace/dag/gunbc/runner_deploy_emit.dag@8278 via=n/a import_chain=std.layout (std.layout.render)
CONTAINMENT_AMBIGUOUS module=v2.compiler.emit_module caller=emit_module_append_decl callee=emit at=/workspace/src/v2/compiler/emit_module.dag@692 via=n/a import_chain=v2.compiler.emit (v2.compiler.emit.emit)
CONTAINMENT_AMBIGUOUS module=v2.compiler.emit_module caller=emit_family_append_member callee=emit at=/workspace/src/v2/compiler/emit_module.dag@2425 via=n/a import_chain=v2.compiler.emit (v2.compiler.emit.emit)
CONTAINMENT_AMBIGUOUS module=v2.compiler.emit_orchestration caller=orch_emit_from_registry callee=emit at=/workspace/src/v2/compiler/05_emit_orchestration.dag@3842 via=n/a import_chain=v2.compiler.emit (v2.compiler.emit.emit)
CONTAINMENT_AMBIGUOUS module=v2.compiler.emit_orchestration caller=orch_emit_node_spelling callee=emit at=/workspace/src/v2/compiler/05_emit_orchestration.dag@4130 via=n/a import_chain=v2.compiler.emit (v2.compiler.emit.emit)
CONTAINMENT_AMBIGUOUS module=v2.compiler.source_authority caller=semantic_ir_from_ast_with_model callee=resolve at=/workspace/src/v2/compiler/source_authority.dag@17318 via=n/a import_chain=v2.compiler.resolve (v2.compiler.resolve.resolve)
CONTAINMENT_AMBIGUOUS module=v2.compiler.emit_host caller=run_test_claim_emit_vs_eval_for_claim callee=emit at=/workspace/src/v2/compiler/emit_host.dag@18124 via=n/a import_chain=v2.compiler.emit (v2.compiler.emit.emit)
CONTAINMENT_AMBIGUOUS module=tools.emit_host_transport caller=expected_stdout_nul_run callee=repeat_string at=/workspace/dag/tools/emit_host_transport.dag@4201 via=n/a import_chain=std.render_repeat_string_bootstrap (std.render_repeat_string_bootstrap.repeat_string)
CONTAINMENT_AMBIGUOUS module=gunbc.live_deploy.emit caller=apply_systemd_unit_write_step callee=render at=/workspace/dag/gunbc/live_deploy/emit.dag@8368 via=n/a import_chain=std.layout (std.layout.render)
CONTAINMENT_AMBIGUOUS module=gunbc.live_deploy.emit caller=apply_tree_sync_unit_write_step callee=render at=/workspace/dag/gunbc/live_deploy/emit.dag@11075 via=n/a import_chain=std.layout (std.layout.render)
CONTAINMENT_AMBIGUOUS module=gunbc.live_deploy.emit caller=live_deploy_systemd_unit_for callee=render at=/workspace/dag/gunbc/live_deploy/emit.dag@28767 via=n/a import_chain=std.layout (std.layout.render)
CONTAINMENT_AMBIGUOUS module=gunbc.live_deploy.emit caller=live_deploy_tree_sync_unit_for callee=render at=/workspace/dag/gunbc/live_deploy/emit.dag@28916 via=n/a import_chain=std.layout (std.layout.render)
CONTAINMENT_AMBIGUOUS module=gunbc.falsifier_workflow caller=native_cache_cold_control_invoke callee=ci_repo_root_shell at=/workspace/dag/gunbc/falsifier_workflow.dag@5533 via=n/a import_chain=gunbc.ci_spec (gunbc.ci_spec.ci_repo_root_shell)
CONTAINMENT_AMBIGUOUS module=gunbc.fleet_converge_emit caller=fleet_converge_sh_for callee=render at=/workspace/dag/gunbc/fleet_converge_emit.dag@8529 via=n/a import_chain=std.layout (std.layout.render)
CONTAINMENT_AMBIGUOUS module=gunbc.host_runner_memory_cap_plan_emit caller=expected_runner_memory_cap_apply_sheet callee=render at=/workspace/dag/gunbc/host_runner_memory_cap_plan_emit.dag@4119 via=n/a import_chain=std.layout (std.layout.render)

SILENT_PICK_FN_PARENT_FIRST_HIT module=gunbc.falsifier_workflow name=ci_repo_root_shell parent_matches=2 chosen_parent=gunbc.ci_spec
Loading
Loading