Skip to content

mask-risc: keyed partial-sink merge — MERGE made real (fold-contract Step E) - #1332

Merged
AdaWorldAPI merged 3 commits into
mainfrom
claude/mask-risc-keyed-sink-merge
Oct 5, 2026
Merged

AdaWorldAPI merged 3 commits into
mainfrom
claude/mask-risc-keyed-sink-merge

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Oct 5, 2026 •

Copy link
Copy Markdown
Owner

Step E makes MERGE real. RETAIN identity is the next contract boundary.

raw keyed FoldState A
        +
raw keyed FoldState B
        ↓
same-algebra MERGE
        ↓
raw keyed FoldState
        ↓
finalize once

Two populations are folded separately: no source rows are materialised and the two never run as one pass. Their raw sinks are merged, and the result is finalized once. This is the first substrate implementation of the same-type RENDEZVOUS.

Step E does NOT solve:
    retained-state identity
    multi-terminal traversal sharing
    destination binding / coordinate resolution
    route composition beyond depth 2
    DO

This PR is rebased onto main after #1331 and #1333.

What changed (mask-risc only)

  • Partial extents accepted. GroupSumI32, GroupSumViaI32 and GroupReduce { Count, MinI32, MaxI32, SumSymI32 } now run on a partial extent, with Lane, Via and Pair keys. Each extent gets a fresh, re-seeded Out::I64.
  • Edge clipping fixed. An edge word is now clipped in a register. These three terminal arms did not clip before. That was harmless only because partial extents were refused.
  • New merge API.
    • GroupFold::merge holds the per-slot law. It lives on the IR type that already knows the fold kind.
    • Terminal::merge_group_sink applies that law across a whole sink.
  • Nothing else added: no grouping engine, sink type, address, terminal, wrapper type or query syntax.

What merge_group_sink checks, exactly

It checks two things, and on failure writes nothing:

  • the terminal is a supported keyed i64 terminal (otherwise ExtentUnsupported);
  • the two sinks have equal length (otherwise LenMismatch).

Equal K is not semantic compatibility. The merge does NOT prove:

  • raw vs finalized state;
  • algebra / state identity;
  • coordinate / world / version identity;
  • filter identity;
  • semantic destination-space identity;
  • binding identity;
  • contribution-population identity;
  • disjoint or legal contribution sets;
  • total-row-bound legality.

All of these are explicit, unchecked caller preconditions in the method's docs. They are tracked under TD-KEYED-SINK-MERGE-IDENTITY-1.

Overflow algebra

Each fold keeps exactly its existing semantics.

fold merge exact when
Count wrapping_add always
GroupSumI32 / Via wrapping_add (as the kernel) total rows ≤ 2^32
Min / Max min / max (the seed is the lattice identity) always
SumSymI32 ⊥⊕x = x, x⊕⊥ = x, ⊥⊕⊥ = ⊥, otherwise wrapping_add. Never plain +. total rows across all partials ≤ GROUP_SUM_SYM_MAX_ROWS

Report's FoldState::merge agrees with every row.

Errors

  • Every refusal for these terminals happens in preflight (precheck / validate), before the sink is seeded. None of them can fail during traversal.
  • execute_into's contract is unchanged.
  • A partial sink is per-extent workspace, sized by K, never by the population.

Gates

All green on the rebased tree: the full mask-risc suite, keyed_merge, clippy -D warnings, fmt, the board gates and the entries index (218 rows).

tests/keyed_merge.rs covers:

  • Whole equals merged partitions for 14 terminal × key combinations at two tile widths. Partitions:

    • one partition;
    • cuts inside a word, on a word edge and on the tile edge;
    • empty extents;
    • random uneven splits.

    Each split is merged in four orders plus a balanced tree.

  • Whole equals the row oracle.

  • Anti-vacuity: a group live in two partials, a group live in exactly one, an empty group, an empty extent, and a cut that splits a live word.

  • _sym can-fire cases: ⊥⊕x, x⊕⊥, ⊥⊕⊥, and a real zero ≠ ⊥.

  • Finalize after merge is correct. Merging already-finalized slots is shown to be wrong.

  • Monoid laws on extremes. The _sym row bound is shown to be load-bearing.

  • merge_refuses_unmergeable_terminals_and_mismatched_sink_lengths.

Disable runs were re-run on the rebased tree. Each mutation turned the suite red, and the suite was green again after restoring:

SumSym as plain +            => RED
Min merged as Max            => RED
empty SumSym treated as 0    => RED
GroupReduce edge unclipped   => RED
GroupSumI32 edge unclipped   => RED

Board

  • entries/2026-10-05-fold-contract-and-keyed-sink-merge.md. It records the fold contract, the planning rules, the ISA layering and the DO arm. Everything except Step E is a working model and is not built. Its OPEN section, aligned with merged report: name the real gap (destination binding for Report); record why GroupAddr::Pair is not the pivot model #1331, separates:
    • A. Destination binding / coordinate resolution.
      • This is a frontend / binder concern, and its normal path lowers to the existing Local / Via keyed fold. It is not a missing ndarray / fold primitive.
      • A destination ordinal is not a semantic identity by itself: an ordinal has meaning only inside its destination-space / codebook identity. That identity carrier is not built.
    • B. Functional route composition beyond depth 2. This is a substrate / R2IL question: an address chain vs a precomposed resident lane. Unmeasured.
  • TD-SYM-SUM-MERGE-IS-NOT-ADDITION-1 is resolved. A resolution note marks its old body as historical rationale.
  • New OPEN TD-KEYED-SINK-MERGE-IDENTITY-1. It is to be closed by the retained FoldState identity contract, not by metadata bolted onto this merge.

Note

citation_decay.py exits 1 locally both with and without this PR's latest edits, with identical output, and the CI citation-decay check is green. The earlier no_alloc flake was fixed independently by #1333, which is now in the base.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DCEP2fZdHYdMCtcEVcTpS2

@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: d8bbde05-98fc-446e-b96f-3ca4fd9b2be2
📥 Commits

Reviewing files that changed from the base of the PR and between 540874d and 166ad06.

📒 Files selected for processing (8)
  • .claude/board/TECH_DEBT.md
  • .claude/board/entries/2026-10-05-fold-contract-and-keyed-sink-merge.md
  • .claude/board/entries/README.md
  • crates/lance-graph-mask-risc/src/exec.rs
  • crates/lance-graph-mask-risc/src/ir.rs
  • crates/lance-graph-mask-risc/src/value.rs
  • crates/lance-graph-mask-risc/tests/extent.rs
  • crates/lance-graph-mask-risc/tests/keyed_merge.rs

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour.


📝 Walkthrough

Walkthrough

Grouped sum and reduce terminals now support partial-extent execution. Fresh keyed sinks are merged using fold-specific laws, and edge masks are clipped to each extent. Tests cover merge results, refusal cases, and finalization order. Documentation records merge preconditions and related fold contracts.

Changes

Keyed Partial-Sink Merge

Layer / File(s) Summary
Fold contracts and merge API
.claude/board/entries/2026-10-05-fold-contract-and-keyed-sink-merge.md, crates/lance-graph-mask-risc/src/ir.rs, .claude/board/TECH_DEBT.md, .claude/board/entries/README.md
Documents fold and planning responsibilities, defines raw-state merge laws, and adds GroupFold::merge and Terminal::merge_group_sink. The board records caller preconditions and updates the symmetric-sum debt status.
Partial-extent execution
crates/lance-graph-mask-risc/src/exec.rs, crates/lance-graph-mask-risc/src/value.rs, .claude/board/entries/2026-10-05-fold-contract-and-keyed-sink-merge.md
Allows GroupSumI32, GroupSumViaI32, and GroupReduce on partial extents. Execution clips masks to extent edges and merges fresh sinks through Terminal::merge_group_sink.
Merge validation
crates/lance-graph-mask-risc/tests/keyed_merge.rs, crates/lance-graph-mask-risc/tests/extent.rs, .claude/board/entries/2026-10-05-fold-contract-and-keyed-sink-merge.md
Tests partitioned results, fold laws, empty and present-zero slots, finalization, and merge refusals. The extent test now verifies refusal for BlendI32.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant execute_extent
  participant GroupedTerminal
  participant OutI64Sink
  participant TerminalMergeGroupSink
  execute_extent->>GroupedTerminal: Run over the extent-clipped mask
  GroupedTerminal->>OutI64Sink: Write grouped raw state to a fresh sink
  OutI64Sink->>TerminalMergeGroupSink: Provide partial sink
  TerminalMergeGroupSink->>OutI64Sink: Merge slots using the fold law
Loading

Suggested reviewers: claude

Merge Risk: ⚪ Minimal · up to 166ad

The change is mergeable after normal checks, provided callers honor the documented keyed-sink merge preconditions.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 85.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 20 functions across 5 files. (3 skipped: 3 …
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: keyed partial-sink merging in mask-risc. The Step E reference adds context without obscuring the change.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

A rabbit counts each grouped sum,
Then joins the raw states, one by one.
Clipped masks keep each edge in view,
Fold laws guide the merge through.
Empty slots rest; zero stays true,
The burrow tests each partition too.

Comment @coderabbitai help to get the list of available commands.

@cursor

cursor Bot commented Oct 5, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: 3965ae0c-c499-45e6-aeef-5d145bdb8844)

claude added 3 commits October 5, 2026 10:33
…record

Admit GroupSumI32 / GroupSumViaI32 / GroupReduce {Count, MinI32, MaxI32,
SumSymI32} (Lane / Via / Pair keys) on partial extents. Each extent gets a
fresh, re-seeded Out::I64; edge words are clipped in a register, which the
three arms previously did not do (dormant while partial extents were
refused). Partials combine with Terminal::merge_group_sink, applying
GroupFold::merge -- the merge law lives on the IR type that knows the fold:
Count/Sum wrapping_add, Min/Max lattice, _sym SUM the pinned bottom-absorbing
law (never plain +). Every fold's existing overflow semantics is preserved.
All refusals stay preflight; execute_into's contract is unchanged.

tests/keyed_merge.rs: whole == merge of any partition (one / two / many
uneven / empty extents / word, tile and in-word cuts), four orders plus a
tree grouping, whole == row oracle, _sym can-fire cases, finalize-after-merge
vs merge-of-finalized, monoid laws, refusals. Disable runs red: _sym with +,
min as max, empty _sym as 0, unclipped GroupReduce / GroupSumI32 edges.

Board: fold-contract entry (four corrections, planning rules, ISA layering,
DO arm -- working models), TD-SYM-SUM-MERGE resolved with a resolution note,
new OPEN TD-KEYED-SINK-MERGE-IDENTITY-1 (equal length is not semantic
compatibility; to be closed by retained FoldState identity).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DCEP2fZdHYdMCtcEVcTpS2
…say so

Wording only. The refusal is LenMismatch on different sink lengths; it does
not and cannot detect a different semantic destination universe (same length
!= same universe; TD-KEYED-SINK-MERGE-IDENTITY-1). Doc and test name now say
exactly that: merge_refuses_unmergeable_terminals_and_mismatched_sink_lengths.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DCEP2fZdHYdMCtcEVcTpS2
…te index

Wording only, after rebasing onto main (#1331, #1333):
- entries/README.md regenerated from the rebased tree (218 rows).
- Fold-contract OPEN splits the old "destination resolution" item into
  A. destination binding / coordinate resolution (frontend / binder; lowers
  to the existing Local / Via fold; not a missing ndarray primitive) and
  B. functional route composition beyond depth 2 (substrate / R2IL; chain vs
  precomposed lane unmeasured).
- TD-KEYED-SINK-MERGE-IDENTITY-1 states exactly what merge_group_sink checks
  (supported keyed i64 terminal, equal length) and adds binding identity,
  contribution-population identity, and the working law that an ordinal has
  meaning only inside its destination-space / codebook identity.
- merge_group_sink precondition 5 names the binding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DCEP2fZdHYdMCtcEVcTpS2
@AdaWorldAPI
AdaWorldAPI force-pushed the claude/mask-risc-keyed-sink-merge branch from 166ad06 to 32226e4 Compare October 5, 2026 10:35
@AdaWorldAPI
AdaWorldAPI merged commit 376528c into main Oct 5, 2026
11 checks passed
AdaWorldAPI pushed a commit that referenced this pull request Oct 5, 2026
The rebase resolved each prepend-ledger conflict by keeping both sides,
which duplicated blocks that both sides carried. Rebuilt AGENT_LOG,
INTEGRATION_PLANS, ISSUES, STATUS_BOARD and TECH_DEBT as main plus only
this branch's own insertions, placed below main's newer entries:
- TECH_DEBT: drop the stale "OPEN, dormant" TD-SYM-SUM-MERGE-IS-NOT-ADDITION-1
  copy (main has it RESOLVED by #1332).
- ISSUES: keep main's ISS-CE64-EMIT-INVERSE-BIT2-DISAGREE (harvested from
  #1303) and drop this branch's earlier copy.
- entries/2026-09-30-three-reference-sets-are-not-ordinal-aligned.md:
  main's corrected version (4 aligned ordinals, not 3).
Regenerated the entries index and SUPERSESSION-INDEX.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DCEP2fZdHYdMCtcEVcTpS2
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.

2 participants