Skip to content

XL-2 resolve: a wildcard '_' match arm binds nothing and names nothing - #12297

Merged
gunbai-bot[bot] merged 1 commit into
mainfrom
session/zesty-ant-189
Sep 25, 2026
Merged

gunbai-bot[bot] merged 1 commit into
mainfrom
session/zesty-ant-189

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

What

v2.compiler.resolve resolve_pattern_node_walk recognized _ only as a constructor field target (resolve_pattern_field_target_walk). A bare _ arm pattern hit the construct_tag_optional = Absent arm and went to resolve_node_walk, which looked it up as a reference to a symbol spelled _. That was the earliest wrong link: lowering hands resolve the same _ atom in both positions, and resolve already treated it as a wildcard in one of them. The fix is one recognizer (resolve_pattern_is_wildcard) at the top of the pattern walk, so every depth goes through it. The field-only helper is removed. body_lowering_fold.dag is not touched.

Witness: v2.test.claim.namespace_xl0.wildcard_arm_resolve

Native census route (native_test_context_from_ingest → native_census_module_resolution), four inline modules. The claims were run locally with gunbc run against main 69e0bb7566e and against this head:

claim main head
a_match_exhaustive_through_a_wildcard_arm_resolves (specimen) false true
an_undeclared_name_in_a_wildcard_arm_body_is_the_sole_refusal_at_its_atom false true
a_wildcard_in_a_constructor_field_resolves (control) true true
a_named_binder_arm_still_binds (control: exhaustive through named arms, WcB { r: r } => r) true true

wc_outcomes is enrolled WARM in v2.workflow.floor_pure_producer_share, the same as its sibling *_outcomes rows.

Measurement (2): census-resolve behavior before and after

I used a scratch probe that printed each module's census outcome, meaning its chain atoms and ObservationCompleteness. The probe was deleted afterwards.

  • main: wc_arm: REFUSED first=_ obs=complete · wc_body: REFUSED first=_ +wc_undeclared_body obs=complete
  • head: wc_arm: RESOLVED · wc_body: REFUSED first=wc_undeclared_body obs=complete

So on main the wildcard refusal never marked the match or the module incomplete. Observation stayed ObservationComplete. What it did was refuse the whole module as an extra, spurious chain that came first, ahead of the real body refusal. The real refusal was still reported, as a second chain. On head that spurious chain is gone and the body refusal is the only one.

RFM

a_wildcard_match_arm_resolves_as_an_unbound_name is not retired. Its trigger names a capability: the lowered pattern carries the wildcard as its own form. That capability is not delivered here. The wildcard is still an atom spelled _ that resolve recognizes through pattern_wildcard_name, and the construction lives in body_lowering_fold (another worker's). I appended a receipt that records the repair, the measurement and why the row stays open.

Carrier wording (for compiler_frontend_program_status, not edited here)

Carrier arm Wildcard: the spurious unbound rows are removed on the native census route. A _ arm pattern at any depth resolves, and a refusal in a _ arm's body is reported at its own atom as the only chain. Proposed status: resolve-side DONE (witness v2.test.claim.namespace_xl0.wildcard_arm_resolve). The lowered-form climb stays tracked by the RFM.

🤖 Generated with Claude Code

resolve_pattern_node_walk recognized `_` only as a constructor field's target;
a bare `_` arm pattern fell to resolve_node_walk and was looked up as a symbol.
It now recognizes the wildcard at every pattern depth.

Witness v2.test.claim.namespace_xl0.wildcard_arm_resolve (warm-shared).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVE on exact head 5d563b9 for MERGE-QUEUE landing only.

The fix is appropriately narrow at the resolver boundary: resolve_pattern_node_walk recognizes the exact _ pattern as binding no name, without changing named-binder handling or suppressing references in the arm body. The three controls discriminate those boundaries: the top-level wildcard is red on main and green here; a named arm binder still binds; and an undeclared name used inside the wildcard arm body still refuses at that atom.

The census consequence is material for XL-2: before this repair, the spurious wildcard failure was emitted as a real residual chain while observation remained complete. This head removes that false row rather than hiding it through incompleteness.

Keeping a_wildcard_match_arm_resolves_as_an_unbound_name OPEN is correct. This PR delivers only the resolve-grain property that _ does not become an unbound reference; it does not deliver the row's terminal requirement of a distinct lowered wildcard form.

Carrier follow-up boundary: mark Wildcard delivered at resolve grain with that qualification, and admit QualifiedFieldTypeVisibility as OUTSTANDING in the same carrier update so the prerequisite universe does not falsely appear closed.

All five exact-head checks are green and GitHub reports CLEAN. Enqueue this exact head; do not direct-merge it, and require the merge_group candidate to revalidate against then-current main.

@gunbai-bot
gunbai-bot Bot added this pull request to the merge queue Sep 25, 2026
Merged via the queue into main with commit 0579afa Sep 25, 2026
5 checks passed
@gunbai-bot
gunbai-bot Bot deleted the session/zesty-ant-189 branch September 25, 2026 18:41
@briansrls
briansrls restored the session/zesty-ant-189 branch September 25, 2026 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant