011 registry scope composition

✓ Passing This code compiles and runs correctly.

Code

// DESIGN: Registry Scope - Composition and Globs
//
// Advanced registry features:
// - Glob patterns: module:* includes all events from a module
// - Scope composition: scope(other) includes another scope
// - Compiler flags: [debug]event only included with --debug

~import "$std/runtime"
~import "$std/io"

const std = @import("std");

// User management events
~pub event users.get { id: u64 }
| found { name: []const u8 }
| not_found {}

~pub event users.list {}
| listed { count: usize }

~pub event users.create { name: []const u8 }
| created { id: u64 }

// Admin events (restricted)
~pub event admin.delete_user { id: u64 }
| deleted {}

~pub event admin.reset_db {}
| reset {}

// Debug events (only in debug builds)
~pub event debug.dump_state {}
| dumped { json: []const u8 }

~pub event debug.trace { message: []const u8 }
| traced {}

// =============================================================================
// REGISTRY SCOPES
// =============================================================================

// Internal scope - basic operations
~[registry:scope(internal)]std.runtime:register {
    std.io:println
}

// User scope - all user events via glob
~[registry:scope(user)]std.runtime:register {
    scope(internal)     // Compose: include internal scope
    users:*             // Glob: all events under users.*
}

// Admin scope - includes user scope + admin events
~[registry:scope(admin)]std.runtime:register {
    scope(user)         // Compose: include user scope
    admin:*             // Glob: all admin events
    [debug]debug:*      // Conditional: only with --debug flag
}

// =============================================================================
// TEST: Scope hierarchy
// =============================================================================

// User code - should work with "user" scope
const USER_CODE =
    \\~users.get(id: 42)
    \\| found |> std.io:println(text: "Found")
    \\| not_found |> std.io:println(text: "Not found")
;

// Admin code - should work with "admin" scope, fail with "user" scope
const ADMIN_CODE =
    \\~admin.delete_user(id: 42)
    \\| deleted |> std.io:println(text: "User deleted")
;

// Debug code - should only work with "admin" scope AND --debug flag
const DEBUG_CODE =
    \\~debug.dump_state()
    \\| dumped |> std.io:println(text: "State")
;

// Test user scope
~std.runtime:parse.source(source: USER_CODE, file_name: "user.kz", allocator: std.heap.page_allocator)
| parsed p |> std.runtime:eval(ast: p.ast, scope: "user")
    | result _ |> std.io:print.ln("User code OK")
    | event_denied e |> std.io:print.ln("User denied: {{e.name}}")
    | exhausted _ |> std.io:print.ln("User exhausted")
    | validation_error _ |> std.io:print.ln("User validation error")
    | dispatch_error _ |> std.io:print.ln("User dispatch error")
    | scope_not_found _ |> std.io:print.ln("User scope missing")
| parse_error e |> std.io:print.ln("Parse error: {{e.message}}")

// Test debug scope in non-debug builds (should be denied)
~std.runtime:parse.source(source: DEBUG_CODE, file_name: "debug.kz", allocator: std.heap.page_allocator)
| parsed p |> std.runtime:eval(ast: p.ast, scope: "admin")
    | result _ |> std.io:print.ln("UNEXPECTED: Debug code ran without --debug")
    | event_denied e |> std.io:print.ln("Debug denied: {{e.name}}")
    | exhausted _ |> std.io:print.ln("Debug exhausted")
    | validation_error _ |> std.io:print.ln("Debug validation error")
    | dispatch_error _ |> std.io:print.ln("Debug dispatch error")
    | scope_not_found _ |> std.io:print.ln("Debug scope missing")
| parse_error e |> std.io:print.ln("Parse error: {{e.message}}")

// Test admin scope with user code (should work - admin includes user)
~std.runtime:parse.source(source: USER_CODE, file_name: "user2.kz", allocator: std.heap.page_allocator)
| parsed p |> std.runtime:eval(ast: p.ast, scope: "admin")
    | result _ |> std.io:print.ln("User code with admin scope OK")
    | event_denied e |> std.io:print.ln("Unexpected denial: {{e.name}}")
    | exhausted _ |> std.io:print.ln("Admin exhausted")
    | validation_error _ |> std.io:print.ln("Admin validation error")
    | dispatch_error _ |> std.io:print.ln("Admin dispatch error")
    | scope_not_found _ |> std.io:print.ln("Admin scope missing")
| parse_error e |> std.io:print.ln("Parse error: {{e.message}}")

// Test admin code with user scope (should fail)
~std.runtime:parse.source(source: ADMIN_CODE, file_name: "admin.kz", allocator: std.heap.page_allocator)
| parsed p |> std.runtime:eval(ast: p.ast, scope: "user")
    | result _ |> std.io:print.ln("UNEXPECTED: Admin code ran with user scope!")
    | event_denied e |> std.io:print.ln("Correctly denied admin event: {{e.name}}")
    | exhausted _ |> std.io:print.ln("Admin code exhausted")
    | validation_error _ |> std.io:print.ln("Admin code validation error")
    | dispatch_error _ |> std.io:print.ln("Admin code dispatch error")
    | scope_not_found _ |> std.io:print.ln("Admin code scope missing")
| parse_error e |> std.io:print.ln("Parse error: {{e.message}}")
input.kz