This library is in flux. APIs may change without notice. Generated from source with koruc 0.1.7 on 8/19/2026.
Bridge
~import std/bridgeResource Bridge Standard Library
bridge.kz · 7 tors · ~[comptime]· ~[runtime]
Resource Bridge Standard Library · 15 more lines
Resource Bridge Standard Library
Persistent handle storage for long-running interactive sessions (Hollywood OS mode)
A Bridge owns a HandlePool that outlives any single interpreter run, so a
resource opened on one turn is still held on the next — the human or the agent
can act on it three turns later and the obligation is still outstanding.
The session is itself an obligation: `create` mints `<session!>` and only
`close` discharges it, so a bridge cannot be brought into being and forgotten.
You cannot forget to hang up.
A bridge is bound to a SCOPE at birth. The scope is the vocabulary: the set of
events that may act on what the bridge holds, and — through each obligation's
recorded discharge event — the knowledge of how to release it. That is what
makes hanging up able to actually release rather than merely forget.
Phantom lifecycles
Derived from the phantom labels in the declarations below — state! issues an
obligation the compiler will chase, !state discharges it, a bare state holds it without moving it. Nothing here is hand-drawn.
Bridge 1 state session!// CREATE - Open a bridge session against a registered scope
~pub tor create { id: string, scope: string } -> *Bridge<session!>get-handles
koru_std/bridge.kz:138// GET_HANDLES - Query handles currently on the bridge
~pub tor get-handles { br: *Bridge } -> u32// RUN - Execute a turn against the session's resources
//
// The verb the bridge existed without: `std/runtime:run` takes a `handle_pool`
// and a `scope`, and a bridge is exactly a pairing of those two that outlives a
// single turn. Without this, every caller reached into Zig for `&br.pool` — the
// mechanism was real and the Koru surface over it did not exist.
//
// The branch set MIRRORS `std/runtime:run` rather than trimming it: forwarding a
// vocabulary that already exists invents nothing, and a turn can fail every way
// a run can fail.
//
// Two of that tor's parameters are deliberately not forwarded:
//
// - `budget` — metering is PARKED. It earns its keep on a public-facing API, not
// on an internal bridge, and exposing the knob here would quietly un-park it.
// - `auto_discharge` — always false, and it must be. A bridge-managed pool
// outlives the run BY DESIGN; releasing at end-of-turn is precisely the
// retention this whole subsystem exists to provide. `close` is what releases.
~pub tor run { br: *Bridge, source: string }
| result {
value: @import("root").koru_std.koru_interpreter.Value,
used: u64,
handles: u32
}
| defined string
| exhausted { used: u64, last_event: string, handles: u32 }
| parse-error { message: string, line: u32, column: u32 }
| validation-error string
| shape-error { branch: string, field: ?[]const u8, message: string }
| event-denied string
| dispatch-error { event_name: string, message: string }
| scope-not-found stringdefine
koru_std/bridge.kz:253// DEFINE - install a subflow declaration as a session verb (the REPL define)
//
// The vocabulary grows at runtime: `tor name { args }` + `name = <body>`
// becomes a verb callable on subsequent runs, held in the session's durable
// defined-flows table. The body's calls run through the same possession
// machinery as any dispatch, so a defined flow cannot reach beyond what the
// session holds. The agent hears "defined name" — or the parse error — fed
// back into the transcript (the honest-diagnostics rule applies here most of
// all: a wrong declaration needs a truthful error).
~pub tor define { br: *Bridge, source: string }
| defined string
| parse-error { message: string, line: u32, column: u32 }vocabulary
koru_std/bridge.kz:288// VOCABULARY - the derived prompt, session-shaped
//
// `std/runtime:scope-vocabulary` renders a scope's COMPILED events — the
// base vocabulary the program was built with. This tor grows that with the
// session's DEFINED flows, so the prompt walks the whole environment a REPL
// accumulates: compiled scopes plus the verbs the agent invented on earlier
// turns. That visibility is the second half of the R1 claim — an invention
// the agent never sees in its own prompt is an invention it will not use.
//
// The same arena discipline as scope-vocabulary: the returned string is
// page-backed and intentionally never freed, because it must outlive this
// call and land in the caller's prompt buffer.
~pub tor vocabulary { br: *Bridge }
| ok string
| not-found stringgrammar
koru_std/bridge.kz:338// GRAMMAR - the derived prompt, complete: the wire's rules + the session's
// whole vocabulary
//
// `std/runtime:scope-grammar` renders the wire's shape rules above the
// scope's COMPILED verbs. The prompt an agent actually lives under needs one
// more thing: the session's DEFINED flows, the verbs it invented on earlier
// turns. This render is that whole surface — rules, compiled base, and
// inventions, one string — so the agent's prompt is the register block plus
// its own growth, and nothing hand-typed. A turn judged by the wire gate
// (parse.wire, in `run` above) and a prompt built from this render are the
// same declaration read twice.
~pub tor grammar { br: *Bridge }
| ok string
| not-found string// CLOSE - Hang up: release everything the session still holds
//
// VOID, and that is load-bearing rather than minimal. Auto-discharge can only
// insert a disposer with nothing to bind — `auto_discharge_inserter.zig:2742`
// refuses any event carrying a branch or a bare return, because the inserter
// appends a bare call and cannot invent a binding for its output. A `close`
// that returned the still-held count disqualified itself, which meant every
// failure arm of every conversation had to spell the hang-up by hand.
//
// Failing to release is not a value a caller may drop; it panics. `get-handles`
// is there for anyone who wants the count on either side of the call.
~pub tor close { br: *Bridge<!session> }