Skip to content

feat(L10): phase 3 rung 3a — named echo residues within a body#42

Merged
hyperpolymath merged 1 commit into
mainfrom
claude/echo-residue-phase3-named
Jun 15, 2026
Merged

feat(L10): phase 3 rung 3a — named echo residues within a body#42
hyperpolymath merged 1 commit into
mainfrom
claude/echo-residue-phase3-named

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

What

L10 phase 3, rung 3a (the slice you chose: static core first). New surface syntax binds a reversal residue to a name and replays it by name, within a single body:

reversible as undo { … }   // bind this block's residue to `undo`
reverse undo               // replay it — consumes the residue exactly once

The anonymous reversible {…} / reverse {…} forms are unchanged. This is fully static — no runtime semantics, which is what makes it the dependable first slice.

Discipline (the affine cell the proof pins)

The named residue is tracked per body as a Holding(Linear<Echo<T>>) cell that reverse transitions to Spent — the static mirror of ResidueCell (Holding/Spent) in EchoResidueLinear.idr. Same affine capability, linear consumption rule as phase 2:

  • Linear — a second reverse undo (cell already Spent) is the reverse-without-residue error.
  • Affine — a reversible as undo { … } never followed by reverse undo is not an error.
  • No leak — named residues are scoped per body (isolated at function + handler boundaries), so a reverse undo cannot reach a reversible as undo in another body. That's the soundness guard and the seam where rung 3b takes over.

Implementation (additive, compiler-guided)

  • Grammar (grammar.pest + spec/grammar.ebnf): optional as <ident> on reversible; new reverse_named = "reverse" ident. Harvard-safe (control rules reference the shared ident token; the Harvard invariant guard passes).
  • AST: additive variants ReversibleAs { binding, body } / ReverseNamed { target } — existing Reversible/Irreversible/Reverse untouched, so every exhaustive ControlStmt match was enumerated by the compiler and mirrored (codegen ×3, dual_ast, eval, formatter, metainterpreter, CFG, typechecker, oracle).
  • Typechecker: per-body named_residues: HashMap<String, NamedResidueState> (Holding(Type)/Spent), bind_named_residue / take_named_residue, the two check_stmt arms, per-function + per-handler isolation.
  • Parser: builders for the named forms.

Verified locally

  • cargo test -p oo7-core890 lib tests (2 new parser + 5 new typechecker), 0 fail
  • full-workspace cargo test → 0 failures
  • cargo fmt -- --check → clean
  • cargo clippy -- -D warnings (CI-equivalent) → exit 0
  • Harvard invariant guard → OK; A2ML validator on 6a2/ → 0 errors

Tests

reversible_as_binds_named_residue, reverse_named_parses (parser); and (typechecker) named-reverse-ok, reverse-unknown-errs, double-reverse-errs, un-reversed-ok (affine), no-cross-function-leak.

Not in scope — rung 3b (next)

Cross-handler residues through agent state (a reversible in on receive replayed by a reverse in on error). That step is irreducibly partly runtime — no static analysis knows whether the earlier handler fired, so the Idris takeForReverse returns Maybe. It adds a residue cell in agent state + evaluator runtime Holding/Spent + the bridge lemma. The static name-resolution and affine discipline here carry straight over.

No new Idris was needed — reverseLinear / ResidueCell already model this rung. Spec: TYPE-SYSTEM-SPEC §11b.5; docs docs/echo-residue-integration.adoc.

CI may still be gated by the GitHub Actions billing/spending-limit rejection (account-owner action); all gates above were verified locally.

https://claude.ai/code/session_018CaSgNjNURC7ocsyjYh9We


Generated by Claude Code

New surface syntax binds a reversal residue to a name and replays it by
name, within a single body:

    reversible as undo { … }   // bind this block's residue to `undo`
    reverse undo               // replay it — consumes the residue once

The anonymous `reversible {…}` / `reverse {…}` forms are unchanged. The
named residue is tracked per body as a `Holding(Linear<Echo<T>>)` cell
that `reverse` transitions to `Spent` — the static mirror of `ResidueCell`
(Holding/Spent) in proofs/idris2/EchoResidueLinear.idr. Same affine /
linear discipline as phase 2: a second `reverse undo` (cell already Spent)
is the reverse-without-residue error; a never-replayed `reversible as undo`
is NOT an error (affine drop); and named residues are scoped per body, so a
`reverse undo` cannot reach a `reversible as undo` in another body — the
soundness guard for this rung.

Implementation (additive, compiler-guided):
- grammar.pest + spec/grammar.ebnf: optional `as <ident>` on reversible;
  new `reverse_named = "reverse" ident`. Harvard-safe (control rules ref
  the shared `ident` token; Harvard guard passes).
- ast.rs: additive variants ReversibleAs { binding, body } and
  ReverseNamed { target } — existing Reversible/Irreversible/Reverse
  untouched, so every exhaustive ControlStmt match was enumerated by the
  compiler and mirrored (codegen x3, dual_ast, eval, formatter,
  metainterpreter, CFG, typechecker, oracle).
- typechecker.rs: per-body named_residues map (NamedResidueState
  Holding/Spent), bind_named_residue / take_named_residue, the two
  check_stmt arms, and per-function + per-handler isolation.
- parser.rs: builders for the named forms.

Tests: 2 parser + 5 typechecker (bind+reverse ok; reverse-unknown errs;
double-reverse errs; un-reversed ok; no cross-function leak). 890 oo7-core
lib tests pass; full workspace `cargo test` 0 failures; `cargo fmt --check`
clean; `cargo clippy -- -D warnings` exit 0.

No new Idris is required — reverseLinear / ResidueCell already model this
rung. Remaining rung 3b: cross-handler residues through agent state, which
is irreducibly partly runtime (the Idris `takeForReverse` returns `Maybe`).

Spec: TYPE-SYSTEM-SPEC §11b.5; docs/echo-residue-integration.adoc; 6a2 STATE.

https://claude.ai/code/session_018CaSgNjNURC7ocsyjYh9We
@hyperpolymath
hyperpolymath marked this pull request as ready for review June 15, 2026 17:47
@hyperpolymath
hyperpolymath merged commit 13cecc2 into main Jun 15, 2026
1 of 24 checks passed
@hyperpolymath
hyperpolymath deleted the claude/echo-residue-phase3-named branch June 15, 2026 17:47
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