Repository navigation
v2: one binder reader -- every binder type read goes through node_query declared_field_from_edge (XL-2 PR2b-1) - #12899
Merged
Conversation
added 3 commits
October 1, 2026 05:02
…rget_model through the reader
…13-pr2b1 # Conflicts: # src/v2/compiler/04_infer.dag
briansrls
approved these changes
Oct 1, 2026
briansrls
left a comment
Contributor
There was a problem hiding this comment.
APPROVE-MERGE at exact head 7a97b3ffa5a810bd0095951e66bcaf1957e5826f.
No findings.
This is a representation- and behavior-neutral PR2b-1 cut:
- The existing
v2.std.node_query.declared_field_from_edgeis the one binder reader. On today's shape, every named binder still yieldsDeclaredField { name: edge.label, type_node: edge.target, cardinality: ... }, so each migrated read is extensionally identical. member_edge_type_nodeis only the mixed-member projection: named members delegate to that reader; positional members retaine.target. It introduces no second binder model.- Infer, resolve, translation, declaration emission, target rendering, concept indexing, and the named lenses now consume the shared projection instead of independently assuming
edge.targetis the type. - No binder builder, node shape, conformance rule, generic subtree walk, coproduct-arm representation, or type-parameter representation changes in this PR. The single representation therefore remains unchanged until the planned atomic reader/builder switch.
- The final commit is the authored refactor merged with current main; the resolved
04_infer.dagconflict retains both main's changes and the shared-reader conversion.
Exact-head floor, generated, emit-build, and witnesses pass. GitHub reports the PR clean and mergeable.
Merge-queue landing only: the actual merge_group candidate must pass against then-current main; no direct merge or check bypass.
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Oct 1, 2026
…om_edge) at every conflicted site; lens member arms read Authored Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
XL-2 PR2b-1. A refactor only: no representation change and no behaviour change.
Why
The 2026-10-01 side-chat ruling puts a default on the BINDER, not on its type. It requires ONE binder representation (a required type, an optional default, one reader and one builder), shared by fn parameters, service io fields and record fields. Changing today's
name -> typebinder shape is a replacement migration (DESIGN §3), which may never leave two shapes coexisting.A census found the builders already centralized (
body_lower_typed_param_edge_of). The readers were scattered: about 15 production functions read a binder edge's.targetdirectly as its type. If the shape changed now, every one of them would misread a binder node. So the migration is staged in three PRs, and the shape is single at every point:Change
v2.std.node_querydeclared_field_from_edge, which returnsDeclaredField { name, type_node, cardinality }. Reusing it avoids minting a second name. Beside it ismember_edge_type_node, for sites that also see positional members: a binder's type through the reader, and a positional member's target, which is its type.v2.compiler.infer:infer_conj_edge_named_type_for_bindingandinfer_formals_from_domain(the latter also covers record formals).v2.compiler.resolve:resolve_record_field_type_optional.v2.std.compilers.semantic_decl_emission:target_semantic_decl_field_surface_from_edge.v2.std.compilers.target_model:produced_decl_param_segment_tokensandproduced_decl_function_type_param_tokens.v2.compiler.translate: the record-field slot arm oftranslate_algebra.v2.std.node_query:conj_payload_type_name_go.v2.std.concept_index:field_refs_from_conj_node.lifecycle_carrier,unit_modeling,reference_derived_residency_reading(three sites) andcost.copied_port_derivation.symbol_index_fillcontainment. They only matter when the shape changes, so they move in 2b-3.Evidence
true:flat_scalar_unit_leaf_flagged_holds,modeled_unit_field_passes_holds,raw_dissolve_on_string_field_is_rejected.dpo_infer_formals_follow_declared_order(infer formals) was OOM-killed on a default-size remote runner before it reported, so this PR's CI floor is its evidence.type_nodeISe.target), so the floor's existing witnesses are the regression check.🤖 Generated with Claude Code