This library is in flux. APIs may change without notice. Generated from source with koruc 0.1.7 on 11/4/2026.

Bridge

import std/bridge

Resource Bridge Standard Library — persistent handle storage for long-running interactive sessions (Hollywood OS mode)

bridge.kz · 10 tors · ~[comptime]· ~[runtime]

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 tors that may act on what the bridge holds, and — through each obligation's recorded discharge tor — 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!

string carries the label <*> with no obligation attached — a dimension, not a lifecycle.

get-handles

<session> koru_std/bridge.kz:131

close

<!session> koru_std/bridge.kz:148

~part world koru_std/bridge.world.kz

Koru Standard Library: the `world` part of bridge.kz — the vocabulary persists. Joined via `~part world` in bridge.kz; merged into the bridge module at load. KOPIUM_RUNTIME.md's permanence rung: `create(world: <dir>)` mounts a directory of flow files as the session's STARTING vocabulary, and every define that lands writes `<dir>/<name>.k`, so session N+1 inherits what session N invented. A world file is verbatim definition source — the same `tor` + `name =` text the agent sent — so the directory reads, diffs, and gardens like a program, and restore runs the SAME install path a fresh define takes: same parser, same checks, same table. Vocabulary persists; possession does not. The pool mints empty and live handles still die with the process — a world carries what the agent may SAY, never what it holds. Failure shape: a world that cannot install panics, it does not degrade. `-> *Bridge` is a bare return and a bare return has no tags, so create cannot spell a refusal arm (210_309/210_310 pin that collision's wall); a session whose genome is corrupt panics at mount, naming the file, rather than running on a silently smaller vocabulary — the same severity dischargeAll gives a session that cannot release what it holds.

create

<session!> koru_std/bridge.world.kz:24

~part custody koru_std/bridge.custody.kz

Koru Standard Library: the `custody` part of bridge.kz — the resource record. Joined via `~part custody` in bridge.kz; merged into the bridge module at load. The world persists vocabulary (`world`); this part persists CUSTODY — the sibling organ SCENE.md names. A world-mounted bridge appends one line per custody event to `<world>/holds.log`, written at the event so the record survives the process. Reading the log back: session-open / session-closed the span a session's holds live in mint verb + subject + the handle it bound release the discharge that retired it A mint inside a closed session's span with no release was released at hang-up; a mint with NO session-closed after it is a hold that died with the process — still-legible to a successor, never silently owned. Consume-and-reissue verbs (append mints a fresh `<open!>` each call) record one mint/release pair per obligation churn — the log is faithful to custody, not to logical fds. A worldless bridge installs nothing and writes no log.

~part run koru_std/bridge.run.kz

Koru Standard Library: the `run` part of bridge.kz. Joined via `~part run` in bridge.kz; merged into the bridge module at load. 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 that pairing outliving a single turn. The branch set MIRRORS `std/runtime:run` plus TWO bridge-only branches. `?partial` is where the mirror ends: sequencing is the agent channel's demand (frag-partial-programs), not `runtime:run`'s contract, which stays single (orisha's endpoint depends on it). A multi-item turn reports here, always, even fully green — one shape for "a turn ran steps". `residue` is the other: a turn whose items were all prose binds every refused text as a session value and hands the turn back to the agent — the callback the harness owes a reply that carried no invocation. Two of that tor's parameters are deliberately not forwarded: - `budget` — metering is PARKED. It earns its keep on a public-facing API. - `auto_discharge` — always false, and it must be. A bridge-managed pool outlives the run BY DESIGN; `close` is what releases. Two required arms: `| result` when the turn completes, `| error` when it fails — the RunError union carries every failure class, `kind` naming the variant (`error-decode` routes it back to the typed arms). The findings stay armable as optionals — the refusal surface is charged once, not nine ritual times.

run

<session><*> koru_std/bridge.run.kz:32

~part error koru_std/bridge.error.kz

Koru Standard Library: the `error` part of bridge — the two-tier error surface for `run`. Joined via `~part error` in bridge.kz; merged into the bridge module at load. `Runtime` is imported in the `bind` part. One arm for every failure class a turn can end in. `kind` names the variant the fine-grained outcome list would have fired; the rest is the lossless union of every variant's payload — zero/empty when the kind doesn't carry it. `error-decode` routes `kind` back to the typed arms when a caller distinguishes between failure classes.

~part run-exec koru_std/bridge.run-exec.kz

Koru Standard Library: the `run-exec` part of bridge — the `run` verb's Zig impl. Joined via `~part run-exec` in bridge.kz; merged into the bridge module at load. The tor decl rides in the `run` part.

~part steps koru_std/bridge.steps.kz

Koru Standard Library: the `steps` part of bridge.kz — the multi-item turn's per-step loop. Joined via `~part steps` in bridge.kz; merged into the bridge module at load. What a multi-item turn's step run produced: the report + counters.

~part hostverbs koru_std/bridge.hostverbs.kz

Koru Standard Library: the `hostverbs` part of bridge — the session- level verbs the interpreter dispatches when the scope's own dispatcher denies: `vocabulary`, `grammar`, and `bind`, plus the tor surfaces that render the same text to host callers. Joined via `~part hostverbs` in bridge.kz; merged into the bridge module at load. VOCABULARY - the derived prompt, session-shaped `std/runtime:scope-vocabulary` renders a scope's COMPILED tors — 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.

vocabulary

<session> koru_std/bridge.hostverbs.kz:22

~part grants koru_std/bridge.grants.kz

Koru Standard Library: the `grants` part of bridge.kz — the introspection-granted verbs' impls. Joined via `~part grants` in bridge.kz; merged into the bridge module at load. `introspection_verbs` — the render `vocabulary`/`grammar` append and the prompt doc exports — lives in the `wiregate` part beside the host_verbs table it renders at comptime, so prompt, parser, and dispatch share one source. `note` is the observer channel: reasoning kept out of residue and out of the user's ear, bound `rN` like any result. `bind(name: "x", value: <datum>)` — the session's injection verb. The harness hands the real world back through it: a tool result that arrived out-of-band becomes a named Koru value the next turn can dereference. `value:` is the datum rendered — a JSON object exposes its members as fields (`r3.user_id`), a scalar binds as-is. The name it reports back is the name it was given; auto-bound results report `r{N}` instead.

~part session koru_std/bridge.session.kz

Koru Standard Library: the `session` part of bridge — the durable-state text helpers a turn's define lines parse through. Joined via `~part session` in bridge.kz; merged into the bridge module at load. The binder itself — `r{N}` minting, deep-copy into session memory, residue — lives in the `bind` part. The declared name of a `tor NAME ...` line (token after `tor`).

~part bind koru_std/bridge.bind.kz

Koru Standard Library: the `bind` part of bridge — the session binder: how a value gets its durable `rN` name, and the dispatch that carries the binder into every run. Joined via `~part bind` in bridge.kz; merged into the bridge module at load. The session env outlives the per-run arena: every dispatched result auto-binds `r{N}`, and the `bind` host verb writes here for values that arrive out-of-band (a harness handing back what the real tool returned). Names and field bytes are copied into the session allocator — arena slices die at the next prepare(), so anything bound here must own its bytes.

~part residue koru_std/bridge.residue.kz

Koru Standard Library: the `residue` part of bridge.kz — residue teaching text (the observer-channel classifier lives in `note`). Joined via `~part residue` in bridge.kz; merged at load. The report a bound residue hands back — and the offense, quoted: the first bytes of the refused text, so a `tool_call:`/`[Calling` wrapper or a prose head is named, not just refused.

~part affordances koru_std/bridge.affordances.kz

Koru Standard Library: the possession-shaped callable surface on the bridge. Joined via `~part affordances` in bridge.kz; merged into the bridge module at load. AFFORDANCES - the callable surface, possession-shaped (the HATEOAS rooms) `vocabulary` is the static surface: everything the scope declares. This is the live half: what you may call GIVEN the handles you currently hold — the answer to "given note_0, what can I do next?" Each live handle knows the tor that created it (`created_by_event`); the scope's tors declare which resources they consume (`!open`); a call is legal now iff every resource it requires is held. The render leads with the held state, then the callable subset of the vocabulary, then the session's inventions (always callable — their bodies enforce possession at dispatch). Same arena discipline as vocabulary: the returned string is page-backed and intentionally never freed — it outlives this call and lands in the caller's prompt buffer.

affordances

<session> koru_std/bridge.affordances.kz:22

~part turn koru_std/bridge.turn.kz

Koru Standard Library: the `turn` part of bridge.kz — the wire gate and the multi-item turn machinery. Joined via `~part turn` in bridge.kz; merged into the bridge module at load. `wireGate` — the wire grammar check shared by the single-item gate and the per-item gate a sequenced turn runs on every slice — lives in the `wiregate` part: one predicate, two surfaces, the item is the unit of enforcement. (440_021; kopium bridge-mirror 2026-09-12-wire-gate-scope) A turn slice: byte offsets into the turn source.

~part turnscan koru_std/bridge.turnscan.kz

Koru Standard Library: the `turnscan` part of bridge.kz — per-line classification for the turn segmenter. Joined via `~part turnscan` in bridge.kz; merged into the bridge module at load. Update delimiter/string state across one raw line. Strings (with `\` escapes) and backtick spans are opaque: delimiters inside them are data.

~part wiregate koru_std/bridge.wiregate.kz

Koru Standard Library: the `wiregate` part of bridge.kz — the gate's vocabulary tables. Joined via `~part wiregate` in bridge.kz; merged into the bridge module at load. One scanner, two duties, same lookups: `wireGate` admits — an arg value is a quoted string or a bare Koru expression, judged by the language's own expression parser, and `dispatchThroughScope` normalizes the same way, so what the gate admits is exactly what dispatch executes. Field names are still judged against the scope's input_fn (or this file's host table for the introspection verbs); untyped scopes see the flat grammar unchanged. wireGate/dispatchThroughScope moved to the `wirerun` part — the wire's path through the installed scope set.

~part items koru_std/bridge.items.kz

Koru Standard Library: the `items` part of bridge.kz — per-item predicates (the note-tail rescue lives in the `note` part). Joined via `~part items` in bridge.kz; merged into the bridge module at load. `tor ...` items route to define_event, everything else dispatches.

~part define koru_std/bridge.define.kz

Koru Standard Library: the `define` part of bridge.kz — install a subflow declaration as a session verb (the REPL define). Joined via `~part define` in bridge.kz; merged into the bridge module at load. 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).

define

<session><*> koru_std/bridge.define.kz:13

~part deflines koru_std/bridge.deflines.kz

Koru Standard Library: the `deflines` part of bridge.kz — the session's invented verbs as vocabulary lines, shared by the grammar render and the affordances render so "what you may say" and "what you may call now" spell the same contract. Joined via `~part deflines` in bridge.kz; merged into the bridge module at load. One `name(args) | outcomes` line per session-defined flow — the same signature spelling the compiled vocabulary uses, plus the declared outcome contract the flow's `define` captured at install.

~part types koru_std/bridge.types.kz

Koru Standard Library: the `types` part of bridge.kz — the module's imports and the interpreter-type re-exports. Joined via `~part types` in bridge.kz; merged into the bridge module at load.

~part render koru_std/bridge.render.kz

Koru Standard Library: the `render` part of bridge — the session's two rendered surfaces, `vocabulary` and `grammar`, shared by the tor surfaces and the wire verbs. Joined via `~part render` in bridge.kz; merged into the bridge module at load. Both renders compose the same layers: the bound scope's compiled text, every mounted scope spelled by the same emitters, the granted host verbs, and the session's own inventions — one string, so a prompt built from this render and a turn judged by the wire gate are the same declaration read twice. The render both surfaces share — the `vocabulary` tor for host callers and the `vocabulary()` wire verb agree byte-for-byte: compiled scope, the mounted scopes, the granted host verbs (so the session's answer is self-describing), then the session's own inventions, one line each: `name(param: type<!phantom>, ...)`. Mounted scopes render through the same line emitter the compiled scope used — a `.dylib` verb is spelled exactly like a register-block verb.

~part mount koru_std/bridge.mount.kz

Koru Standard Library: the `mount` part of bridge — installing a runtime scope from a native module (`.dylib`) onto a live session. Joined via `~part mount` in bridge.kz; merged into the bridge module at load. The loadable unit is a SCOPE, not a proc: the module exports one symbol, `koru_module_init`, which the host calls with a service table and which returns the scope's `ScopeRuntime` — the same vtable a `register` block emits at comptime. Once mounted, the scope's verbs dispatch against THIS bridge's pool: a mounted tor can borrow a handle the bound scope minted three turns ago, mint obligations the hang-up sweep will discharge through the module's own dispatcher, and appear in `vocabulary()`/`grammar()` beside the compiled verbs. Capability grows; authority doesn't. Mount is a host-held tor — the wire cannot reach it, the session cannot install vocabulary on itself. Mount-for-life: the lib stays open until the bridge closes, because a handle whose discharge path lives inside the module must be callable at hang-up. There is no `unmount` while custody is live; the bridge's `deinit` closes the libs after `dischargeAll` has run.

~part wirerun koru_std/bridge.wirerun.kz

Koru Standard Library: the `wirerun` part of bridge — the wire's path into the installed scope set: the per-item gate, the normalize that canonicalizes what the gate admitted, and the dispatch that runs it. Joined via `~part wirerun` in bridge.kz; merged into the bridge module at load. All three stages judge a verb's fields by the OWNER's declared input vocabulary — bound scope first, then every mounted scope's own table — so a mounted verb is admitted and normalized by its own manifest, not the bound scope's. The session lookup rides threadlocal because parse_wire's `input_fn` is a bare fn pointer with no context slot; set for the duration of each call only.

~part runsteps koru_std/bridge.runsteps.kz

Koru Standard Library: the `runsteps` part of bridge.kz — the multi-item turn's per-step loop. Joined via `~part runsteps` in bridge.kz; merged into the bridge module at load. Run a segmented turn item by item: define items install into the session, gate refusals bind residue or strike as wire failures, dispatched items report value + durable binding (a chain's inner links surface through their trace line). Execution continues past every refusal — a partial program RUNS, and the model learns every step's outcome in one observation instead of discovering failures one turn at a time.

~part note koru_std/bridge.note.kz

Koru Standard Library: the `note` part of bridge.kz — the observer channel's whole machinery, kept in one file because it has been removed once already by a diff that only touched some of its surfaces (ac5d38b82). The lane is five things that move together: the host verb itself, the dispatch entry, the tail-split rescue, the residue classifier, and the per-step refusal reporter. Joined via `~part note` in bridge.kz; merged into the bridge module at load. `note(text: ...)` — the observer channel, granted by introspection like its siblings. Reasoning the agent wants kept goes here instead of into prose (which binds as residue and counts toward the rejection bound). The result is a bare acknowledgment — the text itself is already durable in the turn's wire source; echoing it back as the result would re-feed the model its own prose on every report.