Skip to content

dt64/r2il: stamp MethodRef with its issuing store and binding digest; make Prepared private - #1979

Merged
AdaWorldAPI merged 2 commits into
mainfrom
ccr-8062bcc7-l7lkz9-l5c
Nov 7, 2026
Merged

AdaWorldAPI merged 2 commits into
mainfrom
ccr-8062bcc7-l7lkz9-l5c

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

Problem

A MethodRef was plain data: class, method id, signature revision and guard. Two problems followed.

  • Cross-store admission. A reference taken from one BindStore was admitted by another store that had bound a method with the same number but different effects. The lab probe measured a cross-store method with reversed effects being admitted.
  • Mutable plans. Prepared exposed pub steps, and run executed them after checking only permit.methods.contains(&plan.method). A caller could therefore swap in different steps after preparation (r2il binding.rs, prior lines 153-161 and 340-363).

The ruling is Linear EXO-199 (D1/D2):

  • The classid stays the class identity, with no class versioning.
  • The binding is attested by the issuing store plus a digest.
  • A cloned store gets a new issuer.

Change

dt64

  • MethodRef gains one pub opaque stamp: Stamp. It carries the issuer (Weak<()>) and a 128-bit binding digest, has private fields, and no public constructor.

  • The stamp comes from the store: BindStore::method_ref and MethodRef::of.

  • BindStore implements Clone by hand, and each clone mints a fresh identity (D2). derive(Clone) would have shared the identity.

  • admit checks, in order:

    1. the existing refusals;
    2. the stored binding digest, refusing with BindingMismatch;
    3. the stamp's issuer, refusing with ForeignStore.

    Only in this order can both refusals fire.

r2il

  • Prepared's fields are private, with getters (method, steps, lens, route, guards, plan_id).
  • run, prepare_native and run_native check the stamp's issuer against the store. A plan prepared against another store, or a clone of it, is refused.
  • plan_id hashes the binding digest.

Constraints

  • Generic R2IL Programs stay reusable. The binding is checked at admit, prepare and run, never stored in the Program.
  • The 5 struct-update forgeries still compile and keep their exact refusals.
  • No unsafe code.

Non-test diff: dt64 lib.rs +211/−19, r2il binding.rs +67/−15, binding_native.rs +11/−4. The plan doc d-dt64-6-routing-bindstore-behavior-v1.md gains contract section A.6.

Call sites updated

Crate Sites
dt64 tests 7
r2il tests 4 literals, 3 of calls, 6 Prepared field reads (now getters)
report 2
dir-sim 3
math-polyfill-probe 1
xlog-relcomp-probe 1
dt64-admission-probe 2
grammar-constraints-probe 5

In grammar-constraints-probe, a stamped() helper keeps the old refusals for refs built from descriptions. dr-math-binding-probe has its own local MethodRef and is unaffected.

Tests

  • Positive: a same-store twin admits.
  • Negative (each can fire):
    • a_reference_to_reversed_effects_is_refused_as_another_binding
    • a_stamp_moved_to_another_method_is_refused
    • a_same_binding_from_another_store_is_refused_as_foreign
    • a_cloned_store_refuses_the_originals_reference
    • r2il a_plan_prepared_or_run_against_another_store_is_refused
    • r2il native a_native_plan_prepared_or_run_against_another_store_is_refused
    • compile_fail doctests: Prepared::steps cannot be mutated, and a Stamp cannot be built.

Disable runs

All five ran after the commit. Each patch was asserted to apply once, then restored with git checkout.

Disabled Tests that went red
(a) digest compare reversed-effects, stamp-moved
(b) issuer compare clone, foreign, r2il foreign-store
(c) derive(Clone) instead of the manual impl clone, and both r2il foreign-store tests
(d) the stamp check in run / run_native / prepare_native, each alone the matching foreign-store test
(e) Prepared::steps made pub its compile_fail doctest

Validation

All runs used CARGO_PROFILE_DEV_DEBUG=0 CARGO_PROFILE_TEST_DEBUG=0 CARGO_INCREMENTAL=0.

  • cargo test: dt64 95 passed, r2il 87, report 55, all with 0 failures. The dt64 and r2il counts were re-run independently.
  • Tests pass for dir-sim, grammar-constraints-probe, dt64-admission-probe and xlog-relcomp-probe.
  • clippy --all-targets -D warnings is clean for dt64, r2il and math-polyfill-probe. cargo fmt --check is clean.

Open

  • plan_id does not include the lane kind. Prepared holds no lanes (they are bound per run), and adding them would make plans source-specific. This is recorded in the plan.
  • run checks the issuer before guards and route, so a clone with identical routes reports ForeignStore.
  • The in-repo search found no exhaustive match on Refusal. External code is unknown, so the two new variants may break it.
  • This PR is independent of dt64: bind the frame store to the lane source, not the caller #1978 (source issuer). Both touch the dir-sim test file, so they should merge one after the other.

Generated by Claude Code

…d private

A store admitted another store's MethodRef for reversed effects (P1-5), and
Prepared's public fields let a caller edit `steps` after prepare checked them.

dt64:
- BindStore gets a private Arc<()> identity; Clone is manual and mints a
  fresh one (D2), so a clone is another store.
- Each method's binding digest (FNV-1a 128, tag dt64.binding.v1: classid,
  basis witness, id, sig_rev, ON/reads, ordered effects with lens rev and
  arity, population/truth/demand; not name, not guard) is stored at insert.
- MethodRef gains `stamp: Stamp` (private issuer + digest, no public
  constructor). MethodRef::of is removed; BindStore::method_ref issues refs.
- admit: existing checks, then stored digest (BindingMismatch), then issuer
  (ForeignStore). New Refusal variants BindingMismatch, ForeignStore.

r2il:
- run, prepare_native and run_native refuse a plan whose reference another
  store issued (ExecRefusal::Binding(ForeignStore)).
- Prepared fields are pub(crate) with read-only getters; compile_fail doctest.
- plan_id hashes the binding digest. Lane kind is not hashed: lanes are bound
  per run, never on Prepared (C5).

Call sites moved to method_ref in dt64, r2il, report, dir-sim,
math-polyfill-probe, grammar-constraints-probe, dt64-admission-probe and
xlog-relcomp-probe tests/examples. Ruling: EXO-199.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XAqKMMWgnUU9g7Ldyn6sbk
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 7, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-07T21:45:07.285137Z 674018e PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 16016bbc-e4c8-4d9a-af1f-d97ea2b9b1ff
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@AdaWorldAPI
AdaWorldAPI merged commit 6c99d4e into main Nov 7, 2026
20 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