✗
Failing This test is currently failing.
Failed: frontend
Failure Output
Showing last 10 of 12 lines
|
33 | ~app.fs:open(path: "data.txt")
| ^
hint: lift this into a top-level subflow (e.g. `~my_event = call(args) | branch x |> done {}`) or invoke the event from outside the proc body
error[KORU035]: '.' is not a namespace separator in 'app.fs' — use '/' (e.g. 'std/io:...', not 'std.io:...'). '.' is member access after ':'.
--> tests/regression/300_ADVANCED_FEATURES/335_OBLIGATION_STRESS/335_041_subflow_opens_and_forgets/input.kz:34:1
|
34 | | opened f |> done {}
| ^ Code
// PIN (design gap): A subflow that OPENS a resource internally and then
// returns to `done {}` (a void branch constructor) without closing the
// resource or propagating the opened! obligation. The obligation is created
// inside the subflow Koru proc body and vanishes at the body boundary.
//
// This mirrors 518_obligation_lost_at_boundary/bad_subflow.kz — that test
// uses a multi-file setup with a separate fs.kz; this is a single-file
// self-contained pin that opens using the same fs.kz companion.
//
// The phantom checker SHOULD see that `f` carrying `<opened!>` was live at
// the end of the `| opened` branch inside the proc body and no event consumed
// <!opened>. The obligation leaks.
//
// PREDICTION: RED PIN — same failure mode as 518: the frontend accepts the
// proc body, and the backend emits either invalid Zig (as in 518) or runs
// without catching the leak. The expected error below is what SHOULD fire
// when the obligation-at-proc-boundary path is enforced.
//
// Grounding:
// ~import syntax — 330_007/input.kz line 1
// ~pub event void (no branches) — 330_020/input.kz line 2
// ~proc |zig with Koru body — 518/bad_subflow.kz lines 6-12
// | opened f |> done {} call — 518/bad_subflow.kz line 8
// *File<opened!> and app.fs:open — 330_007/fs.kz lines 4-12
~import app/fs
// BAD: opens file inside the proc, forwards to `done {}` (void branch
// constructor), never calling close(). Obligation on `f` is lost.
~pub event work {}
~proc work|zig {
~app.fs:open(path: "data.txt")
| opened f |> done {}
// ERROR: f has <opened!> obligation — done {} does not discharge <!opened>
}
~work()
Must fail at runtime with:
CONTAINS obligationError Verification
Expected Error Pattern
Obligation created inside subflow proc body but not discharged: work() opens
*File<opened!> internally via app.fs:open, then branches to done {} (a void
branch constructor) without calling close(). The opened! obligation is live
at the done {} call — no event in scope accepts <!opened> to discharge it.
Same gap as 518_obligation_lost_at_boundary, single-file form.Actual Compiler Output
error[KORU003]: inline flows are not supported inside `~proc` bodies: ~app.fs:open(path: "data.txt")
--> tests/regression/300_ADVANCED_FEATURES/335_OBLIGATION_STRESS/335_041_subflow_opens_and_forgets/input.kz:33:5
|
33 | ~app.fs:open(path: "data.txt")
| ^
hint: lift this into a top-level subflow (e.g. `~my_event = call(args) | branch x |> done {}`) or invoke the event from outside the proc body
error[KORU035]: '.' is not a namespace separator in 'app.fs' — use '/' (e.g. 'std/io:...', not 'std.io:...'). '.' is member access after ':'.
--> tests/regression/300_ADVANCED_FEATURES/335_OBLIGATION_STRESS/335_041_subflow_opens_and_forgets/input.kz:34:1
|
34 | | opened f |> done {}
| ^Imported Files
// File-resource module reused verbatim from:
// tests/regression/300_ADVANCED_FEATURES/330_PHANTOM_TYPES/330_007_use_after_disposal/fs.kz
const std = @import("std");
const File = struct { handle: i32 };
~pub event open { path: []const u8 }
| opened *File<opened!>
~proc open|zig {
std.debug.print("Opening file: {s}\n", .{path});
const allocator = std.heap.page_allocator;
const f = allocator.create(File) catch unreachable;
f.* = File{ .handle = 42 };
return .{ .opened = f };
}
~pub event close { file: *File<!opened> }
~proc close|zig {
std.debug.print("Closing file\n", .{});
}
Test Configuration
MUST_FAIL