✓
Passing This code compiles and runs correctly.
Code
// RULING GUARD (2026-09-11): a BRANCHED `: bind`-head chain continues in
// every arm.
//
// `make(): h` head-binds a handle; `t1(h)` consumes and re-mints it; `split(h)`
// consumes the re-minted handle and branches. Each arm's `close(h)` means that
// arm's re-minted handle. This is the seam between the continuation pass and
// the chain-pun thread: the pun thread's walk is linear, so it claims the
// pre-branch consume (`t1`) but cannot reach the in-arm references; the
// continuation pass must therefore run FIRST and own every consume-continuation.
// Without that layering this is KORU030 on the stale `h` in each arm.
//
// See concepts/frag-a-consumed-handle-should-continue-its-binding.
import app/held
import std/io
app/held:make(): h |> app/held:t1(h) |> app/held:split(h)
| yes _ |> app/held:close(h) |> std/io:print.ln("yes arm continued")
| no _ |> app/held:close(h) |> std/io:print.ln("no arm continued")
Supporting Files
// The branched `: bind`-head fixture: a bare-return producer, a consume-and-
// reissue step, and a branching consume. Exercises the seam between the
// continuation pass and the chain-pun thread.
const std = @import("std");
pub const Handle = struct { _token: u8 };
~pub tor make {} -> *Handle<open!>
~proc make|zig {
const h = std.heap.page_allocator.create(Handle) catch unreachable;
h.* = Handle{ ._token = 0 };
return h;
}
~pub tor t1 { h: *Handle<!open|!active> } -> *Handle<active!>
~proc t1|zig { return h; }
~pub tor split { h: *Handle<!active> }
| yes *Handle<active!>
| no *Handle<active!>
~proc split|zig { return .{ .yes = h }; }
~pub tor close { h: *Handle<!active> }
~proc close|zig { std.heap.page_allocator.destroy(h); }
Actual
yes arm continued
Expected output
yes arm continued
Flows
flow ~make click a branch to expand · @labels scroll to their anchor
make
Test Configuration
MUST_RUN