Skip to content

Derived-node identity step 2, repair (a): peel_nominal_alias_identity keeps a type parameter's mark (census 37 -> 0; plan specimens unmoved) - #13329

Merged
gunbai-bot[bot] merged 15 commits into
mainfrom
session/jolly-pike-330-peel-keeps-declaration
Oct 5, 2026
Merged

gunbai-bot[bot] merged 15 commits into
mainfrom
session/jolly-pike-330-peel-keeps-declaration

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Derived-node identity step 2, repair (a) only: v1.compiler.infer_resolve peel_nominal_alias_identity keeps a type parameter's mark. Plan: docs/plans/derived-node-identity-design.md §6 step 2.

What it fixes

peel_nominal_alias_identity looked a type-parameter reference up by name and returned whatever the environment bound to that spelling. Where a module binds the same spelling (a record Box<Q> beside fn f<Q>), it replaced the parameter leaf and dropped its own mark. The repair reads the mark instead: a node carrying a TypeParameter declaration is returned as given (std.decl_ref declaration_ref_is_type_parameter).

  • Measured: the generic-identity census (gunbc test //gunbc/instruments:generic-identity-census, Derived-node identity step 2: the generic-identity census (gunbc test //gunbc/instruments:generic-identity-census) #13290) goes from 37 rows of this shape to 0, and no other row moves.
  • Gating RED: control conformance_keeps_the_parameter_mark over fixtures/generic_identity_census/a.dag (same_spelling_as_a_record_parameter). It fails before the repair and holds after.
  • The branch also carries the step-2 bet readings (bet 2: substitute_generics_apply keeps the child declaration; the plan-field reading). They are readings in the census label, not gates, run over nodes the real compiler emitted.

Evidence at 69d839c (gunbc / claim_executor built from this tree)

  • Next generation: claim_executor --regen-round-cost gives convergence_stages=0, rebuild_packages=0, and leaves the mirrors unchanged.
  • src/v2/compiler/00_compile.dag resolves (NoSuchFunction). The four fold_list rows an earlier attempt newly refused do not refuse.
  • Census label: STANDING held, all 7 controls held.

The plan's specimens: both UNMOVED, and not claimed

Both are shapes of gunbc.recurring_failure_mode generic_identity_decided_by_spelling, and both stay with the rest of step 2 (carry origins, switch the three sites to identity). The receipts below come from gunbc built at main ed68b5573b and at this head:

specimen main ed68b55 this head 69d839c
srv3 test.claim.srv3_websocat_sequence_witness the_readback_never_runs_after_a_failed_step (shape 1, valid code refused) refused: function 'join' not found in scope (122:34) refused, identically
take_s(s: head_of(xs: [1], d: 2)), take_s(s: String) (shape 2, wrong code accepted) Accepted, returns Int 1 Accepted, returns 1
control: the same call with String arguments returns a returns a

Shape 2 is silent wrongness, and it is the next priority in step 2. This PR does not touch it.

🤖 Generated with Claude Code

gunbc-ci-auto-heal and others added 15 commits October 4, 2026 13:58
…ment (output grain)

v1.tests.claim.generic_identity_census reads the typed graph and records, per
stored type node, which generic-identity marks it carries. Its blind spot is a
typed UNOBSERVED population in every receipt.

Not ready to push: the mirror and lib.rs line were emitted by a local compiler
that is not main's emitter and must be regenerated; the gunbc test label and the
callee-argument column are not written yet.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
claim_executor --regen-round-cost in a standalone clone, looped to
rebuild_packages=0. The census mirror and lib.rs line were already a fixed point.

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

gi_supplied_node_readings calls substitute_generics_apply and unify_generics
over nodes the real producer emitted for the fixture. Not ready: the mirror
here may be stale against the .dag (a rebuild is in flight) and has not been
regenerated with --regen-round-cost. Stacks on #13290.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1. gi_foreign_reading is three-valued. "No marked occurrence in the owner's
   value arguments" no longer reads as "no occurrence": a leaf spelled as the
   parameter and carrying no mark is ForeignParameterValueArgumentUndecided.
2. The bound-call control and the collision reading rest on
   ResultCarrierObservation, which says whether the carrier was seen at all.
3. gi_sig_rows reads every signature, not only those declaring a type parameter.

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

owner_argument_arms_discriminate asks about one marked parameter under three
supplied owners built from head_of's real signature and requires three
different answers. missing_carriers_are_unobserved requires Unobserved for a
name with no item and for an item with no body.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…D conformance_keeps_the_parameter_mark (mirrors pending regen round)
…rebuild_packages=0)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…pt the branch's superset)

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.

LAND. This is the correct repair-(a) cut. peel_nominal_alias_identity is an alias operation, so a node already carrying a DeclField::TypeParameter identity is not eligible for name-based nominal lookup; returning that node unchanged preserves the existing declaration authority and copy law rather than adding another inference rule. The predicate lives beside DeclarationRef, and the old path remains unchanged for every non-parameter reference.

The fixture is discriminating at the affected carrier: a function parameter Q shares a spelling with the record parameter Box<Q>, and formal_declaration_bound_conformance must retain the function parameter's exact (owner, TypeParameter) mark. The reported 37 -> 0 movement confined to that carrier, fixed-point regeneration, and successful 00_compile resolution support the claimed blast radius.

The PR also states the ceiling honestly: neither the srv3 join refusal nor the accepted head_of<Int> into String specimen moves, and this review credits neither as repaired. The supplied-node bet readings are observations, not gates or production behavior.

GitHub's live status currently still shows the exact-head witnesses run in progress despite the request saying green; treat this approval as the code/modeling verdict and queue only after the exact-head required run completes successfully.

@gunbai-bot
gunbai-bot Bot added this pull request to the merge queue Oct 5, 2026
Merged via the queue into main with commit 8710fb1 Oct 5, 2026
4 checks passed
@gunbai-bot
gunbai-bot Bot deleted the session/jolly-pike-330-peel-keeps-declaration branch October 5, 2026 04:37
gunbai-bot Bot pushed a commit that referenced this pull request Oct 5, 2026
… mirrors bootstrapped by 3-way merge, regenerated next
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