feat(L10): phase 3 rung 3a — named echo residues within a body#42
Merged
Conversation
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
marked this pull request as ready for review
June 15, 2026 17:47
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.
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:
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 thatreversetransitions toSpent— the static mirror ofResidueCell(Holding/Spent) inEchoResidueLinear.idr. Same affine capability, linear consumption rule as phase 2:reverse undo(cell alreadySpent) is the reverse-without-residue error.reversible as undo { … }never followed byreverse undois not an error.reverse undocannot reach areversible as undoin another body. That's the soundness guard and the seam where rung 3b takes over.Implementation (additive, compiler-guided)
grammar.pest+spec/grammar.ebnf): optionalas <ident>onreversible; newreverse_named = "reverse" ident. Harvard-safe (control rules reference the sharedidenttoken; the Harvard invariant guard passes).ReversibleAs { binding, body }/ReverseNamed { target }— existingReversible/Irreversible/Reverseuntouched, so every exhaustiveControlStmtmatch was enumerated by the compiler and mirrored (codegen ×3, dual_ast, eval, formatter, metainterpreter, CFG, typechecker, oracle).named_residues: HashMap<String, NamedResidueState>(Holding(Type)/Spent),bind_named_residue/take_named_residue, the twocheck_stmtarms, per-function + per-handler isolation.Verified locally
cargo test -p oo7-core→ 890 lib tests (2 new parser + 5 new typechecker), 0 failcargo test→ 0 failurescargo fmt -- --check→ cleancargo clippy -- -D warnings(CI-equivalent) → exit 06a2/→ 0 errorsTests
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
reversibleinon receivereplayed by areverseinon error). That step is irreducibly partly runtime — no static analysis knows whether the earlier handler fired, so the IdristakeForReversereturnsMaybe. It adds a residue cell in agent state + evaluator runtimeHolding/Spent+ the bridge lemma. The static name-resolution and affine discipline here carry straight over.No new Idris was needed —
reverseLinear/ResidueCellalready model this rung. Spec: TYPE-SYSTEM-SPEC §11b.5; docsdocs/echo-residue-integration.adoc.https://claude.ai/code/session_018CaSgNjNURC7ocsyjYh9We
Generated by Claude Code