Skip to content

R2IL gains a fold reading: one arity table, two classids, twelve new bytes - #306

Merged
AdaWorldAPI merged 1 commit into
mainfrom
claude/fold-distillation-pr-wave-s57uj7
Sep 22, 2026
Merged

AdaWorldAPI merged 1 commit into
mainfrom
claude/fold-distillation-pr-wave-s57uj7

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Sep 22, 2026

Copy link
Copy Markdown
Owner

Why

The capstone ruling: we already built the instruction set; stop re-implementing programs as Rust enum variants. mask_risc::{Pred, Terminal}, quack::{Filter, Agg} and lgj's LgjOpDesc are three mirror enums of one meaning. The carrier that removes the mirroring is a loco body under a vocabulary — and the vocabulary already existed here.

Evidence it works: lance-graph #1258 carried a join-count as loco bytes through the existing Interpreter into the fused executor, 2 facade passes against quack::lower's 3, allocation identical at 1,000 and 65,536 rows. That probe used a local vocabulary. This PR gives it a real one.

One table, two readings

R2ILVocabulary now answers for the machine reading and a folded reading of the same VocabularyTable. VocabularyRegistry::plug refuses only a taken concept id and copies *v.table(), so one CheckedVocabulary plugs under both ids with no code change, and compose samples the hooks once — arity, pushes and body_refs are identical under both by construction. Only the dialect differs.

That is what closes the ambiguity: the classid binds the dialect, so a stored body is never semantically undecidable.

The 0xE2..=0xED band — twelve rows, eighteen slots left free

VIA · RANGE · SUM · MIN · MAX · GROUP_SUM · KEY_RUNS · ANY · ALL · KEEP · SCATTER_OR · BLEND

Each is backed by a mask-risc Pred/Terminal that already earned its existence in a prior wave with its own parity case. A byte names what passed — that is the line between this and enum explosion. Unminted for want of a falsifier: FIRST (the witness; earns 0xEE when a receive-shaped probe fails without it), MATCH (no P-Code spelling, no frontend emits it), SCATTER_COUNT (the mask-risc terminal is HELD).

Three selection findings that removed rows nobody has to mint

finding consequence
Load is ordinal 1, arity 1, pushes true — exactly P-Code's shape No new byte. The lane index is the single stack operand; the lane KIND rides the immediate as the address SPACE (0=u32, 1=i32, 2=u64 — LaneRef's three variants). No inference, no schema dep.
P-Code's signed/unsigned split maps onto mask-risc's I32/U32 split IntSLess plus operand ORDER gives LtI32 and GtI32. Four compare bytes cover all six mask-risc compares. P-Code has no Greater, as no ISA does. Unsigned IntLess becomes a named refusal, not a silent signed substitution.
GROUP_SUM reads its key operand's kind Addr::Lane selects GroupSumI32, Addr::Via selects GroupSumViaI32. One byte, both terminal shapes, by selection not by variant.

The constraint that shaped the implementation

The drift test asserts MNEMONICS.len() == R2IL_OPS against r2sleigh's own enum, so a row added to MNEMONICS/ARITY/PUSHES would break the pin that keeps R2IL honest. The band therefore lives in separate arrays. Verified: all three protected arrays are byte-identical to origin/main, and both guard tests (the_table_matches_r2il_s_own_enum, every_opcode_sits_above_the_domain_floor_and_below_the_next_domain) are byte-identical too.

Additive side-fix: domain_name was never wired

VocabularyTable::name() returned None for all 82 R2IL opcodes even though MNEMONICS existed — the same shape of gap domain_pushes_result closed earlier. Wired for both bands. Nothing outside this crate depends on ogar-r2il (the one hit in ogar-loco/Cargo.toml is a comment line), so the fix is observable and carries no cross-crate risk.

Concept ids are PROVISIONAL

CONCEPT_R2IL_MACHINE = 0xC400, CONCEPT_R2IL_FOLD = 0xC401, in ConceptDomain::BinaryLifting — the domain whose own doc names architecture-agnostic lift/IR and sends platform facts like $D021 to 0xC6XX instead. No persisted GUID may use them until minted in ogar-vocab; minting stays an operator decision. Both doc comments say so.

The 2026-08-26 ruling needs no storno

It rules out the ruff_r2il R2IL→SPO pre-pass, and that stands unchanged. This crate gains no executor and remains an arity table plus addressing glue. What was narrowed, in place: "the runtime path is r2sleigh's interpreter""the machine reading's runtime path", since the folded reading's dialect lives in a consumer. Both readings execute R2IL; neither pre-converts it.

Gates (run scoped, -p ogar-r2il, never --all)

cargo test -p ogar-r2il      25 passed / 0 failed  (was 15; +10 new)
                              5 passed / 0 failed  (zipper_hop_parity, untouched)
cargo clippy -p ogar-r2il --all-targets -- -D warnings   0 findings
cargo fmt -p ogar-r2il --check                           clean

Five disable arms red-then-green (full table in the commit); two re-verified independently after the doc edits landed: FOLD_BASE off by one → 2 red; the two-classid plug falsifier collapsed to one id → 1 red. Every patch anchor was assertion-checked before applying, because cargo fmt has already silently moved an anchor once in this arc.

Measured gap, named not hidden

Dialect::truthy returns a bare bool through &self, so a fold dialect cannot refuse a branch on a population — whatever it answers, loco proceeds. Detectable via a poison flag, never abortable. Making it a true refusal needs truthy -> Result<bool, Self::Error> in ogar-loco: its own PR, its own blast radius.

Not in this PR

No R2ILOp/r2sleigh change. No machine dialect (the 6510 / MemoryBus / r2conc-oracle arm is its own wave). No fold dialect — that lands next in lance-graph's excluded-tier probe, where the OGAR path deps already resolve, so no lance-graph workspace crate gains an OGAR dependency and no restructure is needed.

Ledger: docs/DISCOVERY-MAP.md D-R2IL-FOLD-BAND (appended, per the map's append-only discipline).

🤖 Generated with Claude Code

https://claude.ai/code/session_01GXUahz73MZxtxWcfpHp9dG


Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Added support for a fold-reading runtime alongside the existing machine-reading runtime.
    • Added fold operations for aggregation, selection, grouping, range processing, and value blending.
    • Expanded vocabulary and naming support across both runtime modes while preserving existing R2IL execution behavior.
  • Documentation

    • Documented the shared operation set, runtime interpretations, opcode mappings, and provisional concept identifiers.
    • Clarified that fold-runtime execution is handled by consuming components.

…bytes

The capstone ruling was that we already have the instruction set and keep
re-implementing programs as Rust enum variants. mask-risc's Pred/Terminal,
quack's Filter/Agg and lgj's LgjOpDesc are three mirrors of one meaning.
The carrier that removes the mirroring is a loco body under a vocabulary,
and the vocabulary already existed here.

So R2ILVocabulary now answers for TWO readings of the SAME table. The
registry's plug() refuses only a taken concept id and copies the table, so
one CheckedVocabulary plugs under CONCEPT_R2IL_MACHINE and
CONCEPT_R2IL_FOLD with no code change, and compose() samples the hooks
once -- arity, pushes and body_refs are identical under both by
construction. Only the dialect differs.

The 0xE2..=0xED band adds the twelve population ops P-Code cannot spell:
VIA, RANGE, SUM, MIN, MAX, GROUP_SUM, KEY_RUNS, ANY, ALL, KEEP,
SCATTER_OR, BLEND. Each is backed by a mask-risc terminal that already
earned its existence with its own parity case, so a byte names what
passed. FIRST, MATCH and SCATTER_COUNT stay unminted for want of a
falsifier. 18 slots stay free.

Three selection findings removed rows nobody has to mint. Load (arity 1,
pushes true) needs no new byte: P-Code's shape already fits, with the lane
index as the single stack operand and the lane kind riding the immediate
as the address space. P-Code's signed/unsigned split maps onto mask-risc's,
so four compare bytes plus operand order cover all six compares. GROUP_SUM
selects between the local and via terminals off its key operand's kind.

The band lives in separate arrays because the drift test asserts
MNEMONICS.len() == R2IL_OPS against r2sleigh's enum; all three protected
arrays are byte-identical to origin/main and both guard tests are
unchanged. domain_name was never wired, so name() was None for all 82
opcodes despite MNEMONICS existing -- wired here as an additive fix with
nothing outside this crate depending on it.

Concept ids are provisional in ConceptDomain::BinaryLifting, whose own doc
names architecture-agnostic lift/IR and sends platform facts to 0xC6XX.
No persisted GUID may use them until minted.

This crate gains no executor and stays proxy glue, so the 2026-08-26
ruling needs no storno -- only a narrowing of "the runtime path" to "the
machine reading's runtime path", applied in place.

10 tests, 5 disable arms red-then-green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXUahz73MZxtxWcfpHp9dG
@coderabbitai

coderabbitai Bot commented Sep 22, 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: 06ce9aad-a7a8-429c-ac69-6141c0e2cbc7

📥 Commits

Reviewing files that changed from the base of the PR and between a5b852e and 7a13a9e.

📒 Files selected for processing (2)
  • crates/ogar-r2il/src/lib.rs
  • docs/DISCOVERY-MAP.md

Included review availability: 1 review is currently available. Your included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour.


📝 Walkthrough

Walkthrough

The change adds a 12-opcode fold band to R2IL, registers machine and fold concept IDs, extends vocabulary lookups, preserves existing R2IL behavior, and documents the fold runtime boundary.

Changes

R2IL Fold Vocabulary

Layer / File(s) Summary
Fold band contract
crates/ogar-r2il/src/lib.rs, docs/DISCOVERY-MAP.md
The crate defines fold opcodes from 0xE2 through 0xED, their names, arities, result metadata, function indices, and provisional concept IDs. Documentation records shared table semantics and consumer-owned execution.
Vocabulary integration and validation
crates/ogar-r2il/src/lib.rs
R2ILVocabulary resolves both opcode bands for arity, result, body-reference, and name queries. Tests validate layout, metadata alignment, registrations, names, fold semantics, and unchanged R2IL answers.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~35 minutes

Change: Feature

Suggested reviewers: claude

Merge Risk: ⚪ Minimal · up to 7a13a

This change adds fold vocabulary metadata while preserving existing R2IL behavior; the reported validation passes, so it is ready to merge with normal checks.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: a fold reading, shared arity table, two concept IDs, and twelve new opcodes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 1 files. (1 skipped: 1…
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.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR

A rabbit checks the fold-band sign,
Twelve bright opcodes fall in line.
The old machine path stays clear,
Names and arities now appear.
Two concepts share one table’s thread,
While tests hop lightly overhead.

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

@cursor

cursor Bot commented Sep 22, 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: serverGenReqId_d8aedd34-7348-4c8c-b806-a779533eb06c)

@AdaWorldAPI
AdaWorldAPI marked this pull request as ready for review September 22, 2026 06:20
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@AdaWorldAPI
AdaWorldAPI merged commit 7c6ddba into main Sep 22, 2026
5 checks passed
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