○
Planned This feature is planned but not yet implemented.
Parked: the emitted Zig for this shape-contract program does not compile
Error Details
install
Failure Output
Showing last 10 of 27 lines
error: the following command failed with 1 compilation errors:
/opt/homebrew/Cellar/zig/0.15.2_1/bin/zig build-exe -ODebug --dep koru_parser --dep koru_ast=ast --dep koru_errors=errors --dep ast --dep flow_parser --dep liquid -Mroot=/Users/larsde/src/koru/tests/regression/400_RUNTIME_FEATURES/410_BUDGETED_INTERPRETER/410_010_shape_contract/output_emitted.zig -ODebug --dep struct_literal --dep ast --dep ast_mangle --dep lexer --dep errors --dep type_registry --dep expression_parser --dep comptime_eval --dep annotation_parser --dep union_collector --dep module_resolver --dep file_types -Mkoru_parser=/usr/local/lib/koru/src/parser.zig -ODebug --dep errors -Mast=/usr/local/lib/koru/src/ast.zig -ODebug -Merrors=/usr/local/lib/koru/src/errors.zig -ODebug --dep ast --dep lexer --dep errors --dep expression_parser -Mflow_parser=/usr/local/lib/koru/src/flow_parser.zig -ODebug -Mliquid=/usr/local/lib/koru/src/liquid.zig -ODebug --dep liquid -Mstruct_literal=/usr/local/lib/koru/src/struct_literal.zig -ODebug --dep ast -Mast_mangle=/usr/local/lib/koru/src/ast_mangle.zig -ODebug -Mlexer=/usr/local/lib/koru/src/lexer.zig -ODebug --dep ast --dep log -Mtype_registry=/usr/local/lib/koru/src/type_registry.zig -ODebug --dep lexer --dep ast -Mexpression_parser=/usr/local/lib/koru/src/expression_parser.zig -ODebug --dep ast --dep expression_parser -Mcomptime_eval=/usr/local/lib/koru/src/comptime_eval.zig -ODebug -Mannotation_parser=/usr/local/lib/koru/src/annotation_parser.zig -ODebug --dep ast -Munion_collector=/usr/local/lib/koru/src/union_collector.zig -ODebug --dep config --dep log --dep file_types -Mmodule_resolver=/usr/local/lib/koru/src/module_resolver.zig -ODebug -Mfile_types=/usr/local/lib/koru/src/file_types.zig -ODebug -Mlog=/usr/local/lib/koru/src/log.zig -ODebug --dep log -Mconfig=/usr/local/lib/koru/src/config.zig -lc --cache-dir .zig-cache --global-cache-dir /Users/larsde/.cache/zig --name output --zig-lib-dir /opt/homebrew/Cellar/zig/0.15.2_1/lib/zig/ --listen=-
Build Summary: 0/3 steps succeeded; 1 failed
install transitive failure
+- install output transitive failure
+- compile exe output Debug native 1 errors
error: the following build command failed with exit code 1:
.zig-cache/o/fe6ba252fde73c4f0b3939aa1e4d43b5/build /opt/homebrew/Cellar/zig/0.15.2_1/bin/zig /opt/homebrew/Cellar/zig/0.15.2_1/lib/zig /Users/larsde/src/koru/tests/regression/400_RUNTIME_FEATURES/410_BUDGETED_INTERPRETER/410_010_shape_contract .zig-cache /Users/larsde/.cache/zig --seed 0xf8670ef9 -Z234078fde4c0b247 Code
// Test: Shape contract validation for interpreted code
// Interpreted code can optionally be validated against an event signature
// This ensures responses conform to a known shape
~import std/runtime
~import std/io
const std = @import("std");
// =============================================================================
// The Handler Contract
// =============================================================================
// This defines what shape interpreted "handlers" must return.
// Think of it as a response schema for code sent over the wire.
~pub tor handler { req: string }
| ok { status: i32, body: string }
| error string
// =============================================================================
// Backend events the handler can call
// =============================================================================
~pub tor db.user.get { id: i32 } -> string
~proc db.user.get|zig {
if (id == 1) {
return "Alice";
}
}
// Register events with costs
~std/runtime:register(scope: "api") {
handler(0) // handler itself has no cost (it's the shape)
db.user.get(5) // database lookup costs 5 tokens
}
// =============================================================================
// TEST 1: Valid handler - should pass shape validation
// =============================================================================
const VALID_HANDLER =
\\db.user.get(id: 1)
\\| found u |> ok { status: 200, body: u.name }
\\| unknown |> not-found {}
;
~std/runtime:run(source: VALID_HANDLER, scope: "api", budget: 100, shape: "handler")
| result _ |> std/io:print.ln("TEST 1 PASS: valid handler accepted")
| shape-error e |> std/io:print.ln("TEST 1 FAIL: unexpected shape error: {{ e.branch:s }}")
| exhausted _ |> std/io:print.ln("TEST 1 FAIL: exhausted")
| parse-error _ |> std/io:print.ln("TEST 1 FAIL: parse error")
| validation-error _ |> std/io:print.ln("TEST 1 FAIL: validation error")
| event-denied _ |> std/io:print.ln("TEST 1 FAIL: event denied")
| dispatch-error _ |> std/io:print.ln("TEST 1 FAIL: dispatch error")
| scope-not-found _ |> std/io:print.ln("TEST 1 FAIL: scope not found")
// =============================================================================
// TEST 2: Invalid branch name - should fail shape validation
// =============================================================================
const TYPO_HANDLER =
\\db.user.get(id: 999)
\\| found u |> ok { status: 200, body: u.name }
\\| unknown |> not_foundy {}
;
// Note: "not_foundy" is a typo - should be "not_found"
// Using id: 999 which returns 'unknown' so the typo branch is executed
~std/runtime:run(source: TYPO_HANDLER, scope: "api", budget: 100, shape: "handler")
| result _ |> std/io:print.ln("TEST 2 FAIL: should have caught typo")
| shape-error e |> std/io:print.ln("TEST 2 PASS: caught invalid branch '{{ e.branch:s }}'")
| exhausted _ |> std/io:print.ln("TEST 2 FAIL: exhausted")
| parse-error _ |> std/io:print.ln("TEST 2 FAIL: parse error")
| validation-error _ |> std/io:print.ln("TEST 2 FAIL: validation error")
| event-denied _ |> std/io:print.ln("TEST 2 FAIL: event denied")
| dispatch-error _ |> std/io:print.ln("TEST 2 FAIL: dispatch error")
| scope-not-found _ |> std/io:print.ln("TEST 2 FAIL: scope not found")
// =============================================================================
// TEST 3: Missing required field - should fail shape validation
// =============================================================================
const MISSING_FIELD_HANDLER =
\\db.user.get(id: 1)
\\| found u |> ok { status: 200 }
\\| unknown |> not-found {}
;
// Note: ok branch is missing required 'body' field
~std/runtime:run(source: MISSING_FIELD_HANDLER, scope: "api", budget: 100, shape: "handler")
| result _ |> std/io:print.ln("TEST 3 FAIL: should have caught missing field")
| shape-error e |> std/io:print.ln("TEST 3 PASS: caught missing field in '{{ e.branch:s }}'")
| exhausted _ |> std/io:print.ln("TEST 3 FAIL: exhausted")
| parse-error _ |> std/io:print.ln("TEST 3 FAIL: parse error")
| validation-error _ |> std/io:print.ln("TEST 3 FAIL: validation error")
| event-denied _ |> std/io:print.ln("TEST 3 FAIL: event denied")
| dispatch-error _ |> std/io:print.ln("TEST 3 FAIL: dispatch error")
| scope-not-found _ |> std/io:print.ln("TEST 3 FAIL: scope not found")
// =============================================================================
// TEST 4: Free-running mode (no shape) - typo allowed
// =============================================================================
~std/runtime:run(source: TYPO_HANDLER, scope: "api", budget: 100)
| result r |> std/io:print.ln("TEST 4 PASS: free-running mode allows any shape, got branch '{{ r.value.branch:s }}'")
| exhausted _ |> std/io:print.ln("TEST 4 FAIL: exhausted")
| parse-error _ |> std/io:print.ln("TEST 4 FAIL: parse error")
| validation-error _ |> std/io:print.ln("TEST 4 FAIL: validation error")
| shape-error _ |> std/io:print.ln("TEST 4 FAIL: shape error")
| event-denied _ |> std/io:print.ln("TEST 4 FAIL: event denied")
| dispatch-error _ |> std/io:print.ln("TEST 4 FAIL: dispatch error")
| scope-not-found _ |> std/io:print.ln("TEST 4 FAIL: scope not found")
Expected output
TEST 1 PASS: valid handler accepted
TEST 2 PASS: caught invalid branch 'not_foundy'
TEST 3 PASS: caught missing field in 'ok'
TEST 4 PASS: free-running mode allows any shape, got branch 'not_foundy'
Flows
flow ~register click a branch to expand · @labels scroll to their anchor
register (scope: "api", source: handler(0) // handler itself has no cost (it's the shape)
db.user.get(5) // database lookup costs 5 tokens)
flow ~run click a branch to expand · @labels scroll to their anchor
run (source: VALID_HANDLER, scope: "api", budget: 100, shape: "handler")
flow ~run click a branch to expand · @labels scroll to their anchor
run (source: TYPO_HANDLER, scope: "api", budget: 100, shape: "handler")
flow ~run click a branch to expand · @labels scroll to their anchor
run (source: MISSING_FIELD_HANDLER, scope: "api", budget: 100, shape: "handler")
flow ~run click a branch to expand · @labels scroll to their anchor
run (source: TYPO_HANDLER, scope: "api", budget: 100)
Test Configuration
MUST_RUN