✗
Failing This test is currently failing.
Failed: output
Failure Output
[REGISTRY] Creating dispatcher for scope 'api'
[REGISTRY] Found 2 events
[REGISTRY] Generated 18923 bytes
🎯 Compiler coordination: Passes: 20 (flow-based: elaborate, analysis, emission) Code
// ═══ RULED 2026-08-07 (Lars). This test is now red against a DECIDED target. ═══
//
// "Why don't we make something like `unhandled-branch`? We add leniency as a
// mode, and add a branch like that which sends out the references too, living
// on the resource bridge?"
//
// THE RULING:
// 1. `run` gains a branch — `| unhandled-branch { branch, payload, handles }`.
// An interpreted fragment that does not handle an outcome hands it back
// rather than erroring. Distinct from `| result`, because "finished with
// this value" and "stopped, nobody handled this" are different events and
// a host wants to tell them apart.
// 2. Leniency is a MODE on `run`, not the interpreter's nature. `run` already
// takes fail_fast / shape / budget / auto_discharge; totality is one more.
// Policy (which API key gets which mode) is resolved by the CALLER — the
// interpreter never sees a key.
// 3. Strict mode REFUSES PRE-FLIGHT, shape-checking the incoming source for
// full handling before anything executes. Today's failure is worse than
// either option: NoBranchMatch fires after the event already ran.
// 4. The payload carries NAMED handles, not the count `run` returns today, so
// the next line of a shell can address what the last one parked on the
// bridge.
//
// WHY THIS IS PRINCIPLED AND NOT MERELY LENIENT: the host MUST handle
// `| unhandled-branch` — KORU022 makes it. Totality is not abandoned, it is
// RELOCATED to the boundary where a compiler still exists. The fragment may be
// partial; the program receiving partiality may not be.
//
// WHO THE OUTER HANDLER IS, which is what the mode selects:
// a human at a prompt — the shell prints it; that IS the handling
// a model over a bridge — it is fed back as a message and teaches the model
// a test harness — an unhandled branch is a test FAILURE (Lars, on 395_002)
// nobody (compiled) — strict; refuse pre-flight
//
// C (the empty branch name when an arm fires) needed no ruling and is a plain
// defect: a terminal void event overwrites the flow's real branch with "".
//
// STILL RED, and correctly: `| unhandled-branch` does not exist yet. expected.txt
// asserts today's measured A/B/C so the file documents the gap honestly; it is
// rewritten to the ruled shape by whoever implements it.
// What does the interpreter do when interpreted source handles only SOME of an
// event's branches, and the unhandled one is taken?
//
// In compiled Koru that is KORU022 at compile time. Interpreted source arrives
// after every compile step is over, so the same rule has nowhere to fire.
~import std/runtime
~import std/io
const std = @import("std");
// Two branches, and which one fires is a runtime decision.
~pub tor pick { n: i64 }
| ok i64
| bad string
~proc pick|zig {
if (n > 0) return .{ .ok = n };
return .{ .bad = "n was not positive" };
}
~pub tor note { text: string }
~proc note|zig {
std.debug.print(" note: {s}\n", .{text});
}
~std/runtime:register(scope: "api") {
pick(1)
note(1)
}
// A: no continuations at all. The event's outcome has nowhere to go.
const A = "pick(n: -1)";
// B: only `| ok` is handled, and `| bad` is the branch that fires. THE QUESTION.
const B = "pick(n: -1)\n| ok v |> note(text: \"took ok\")";
// C: control — same source, and the handled branch is the one that fires.
const C = "pick(n: 5)\n| ok v |> note(text: \"took ok\")";
~std/io:print.ln("--- A: no arms, unhandled outcome")
~std/runtime:run(source: A, scope: "api")
| result r |> std/io:print.ln(" result branch=[{{ r.value.branch:s }}]")
| exhausted _ |> std/io:print.ln(" EXHAUSTED")
| parse-error e |> std/io:print.ln(" PARSE ERROR: {{ e.message:s }}")
| validation-error v |> std/io:print.ln(" VALIDATION ERROR: {{ v:s }}")
| shape-error s |> std/io:print.ln(" SHAPE ERROR: {{ s.message:s }}")
| event-denied ev |> std/io:print.ln(" EVENT DENIED: {{ ev:s }}")
| dispatch-error d |> std/io:print.ln(" DISPATCH ERROR: {{ d.message:s }}")
| scope-not-found _ |> std/io:print.ln(" SCOPE NOT FOUND")
~std/io:print.ln("--- B: only | ok handled, | bad fires")
~std/runtime:run(source: B, scope: "api")
| result r |> std/io:print.ln(" result branch=[{{ r.value.branch:s }}]")
| exhausted _ |> std/io:print.ln(" EXHAUSTED")
| parse-error e |> std/io:print.ln(" PARSE ERROR: {{ e.message:s }}")
| validation-error v |> std/io:print.ln(" VALIDATION ERROR: {{ v:s }}")
| shape-error s |> std/io:print.ln(" SHAPE ERROR: {{ s.message:s }}")
| event-denied ev |> std/io:print.ln(" EVENT DENIED: {{ ev:s }}")
| dispatch-error d |> std/io:print.ln(" DISPATCH ERROR: {{ d.message:s }}")
| scope-not-found _ |> std/io:print.ln(" SCOPE NOT FOUND")
~std/io:print.ln("--- C: control, | ok handled and | ok fires")
~std/runtime:run(source: C, scope: "api")
| result r |> std/io:print.ln(" result branch=[{{ r.value.branch:s }}]")
| exhausted _ |> std/io:print.ln(" EXHAUSTED")
| parse-error e |> std/io:print.ln(" PARSE ERROR: {{ e.message:s }}")
| validation-error v |> std/io:print.ln(" VALIDATION ERROR: {{ v:s }}")
| shape-error s |> std/io:print.ln(" SHAPE ERROR: {{ s.message:s }}")
| event-denied ev |> std/io:print.ln(" EVENT DENIED: {{ ev:s }}")
| dispatch-error d |> std/io:print.ln(" DISPATCH ERROR: {{ d.message:s }}")
| scope-not-found _ |> std/io:print.ln(" SCOPE NOT FOUND")
Actual
--- A: no arms, unhandled outcome
result branch=[bad]
--- B: only | ok handled, | bad fires
DISPATCH ERROR: NoBranchMatch
--- C: control, | ok handled and | ok fires
note: took ok
result branch=[]
Expected output
--- A: no arms, unhandled outcome
result branch=[bad]
--- B: only | ok handled, | bad fires
result branch=[bad]
--- C: control, | ok handled and | ok fires
note: took ok
result branch=[ok]
Flows
flow ~register click a branch to expand · @labels scroll to their anchor
register (scope: "api", source: pick(1)
note(1))
flow ~print.ln click a branch to expand · @labels scroll to their anchor
print.ln (expr: "--- A: no arms, unhandled outcome")
flow ~run click a branch to expand · @labels scroll to their anchor
run (source: A, scope: "api")
flow ~print.ln click a branch to expand · @labels scroll to their anchor
print.ln (expr: "--- B: only | ok handled, | bad fires")
flow ~run click a branch to expand · @labels scroll to their anchor
run (source: B, scope: "api")
flow ~print.ln click a branch to expand · @labels scroll to their anchor
print.ln (expr: "--- C: control, | ok handled and | ok fires")
flow ~run click a branch to expand · @labels scroll to their anchor
run (source: C, scope: "api")
Test Configuration
MUST_RUN