# Event Continuations

**Note: Event Continuations are a BEIST/OS feature built on top of RINGS IPC primitives. This document describes the high-level orchestration concepts that live in the BEIST/OS repository, not the RINGS core library.**

## Overview

Event Continuations extend RINGS' self-routing events into composable, self-describing workflows. **Event types define their continuation methods at compile time**, while s-expressions describe the routing between these pre-defined continuation points, enabling arbitrary branching and interactive command chains.

## Core Concept

Traditional shell pipes create linear workflows:
```bash
cat file.txt | grep "error" | wc -l
```

Event continuations enable the same with s-expression style routing definitions:
```zig
// Event types define continuation methods at compile time
const FileReadEvent = struct {
    pub fn success(self: FileReadEvent, data: []const u8) void { ... }
    pub fn file_not_found(self: FileReadEvent, path: []const u8) void { ... }
    pub fn permission_denied(self: FileReadEvent, user: []const u8) void { ... }
};

// S-expressions describe routing between these compile-time defined continuations
const workflow = parseSexpr("
    (file:read
        (success file:process (ok file:save) (error file:log))
        (file_not_found file:create (ok file:read))
        (permission_denied security:alert)
    )");

// Execute with event
const result = file.read("input.txt").withRouting(workflow);
```

When `file:read` calls `event.success(data)`, it routes to `file:process`; when `file:process` calls `event.ok(result)`, it routes to `file:save`, etc.

## Continuation Code Language

Event continuations use a HTTP-inspired status code system for runtime composability:

### Standard Continuation Codes (0-127)

**Success Codes:**
- `0` - OK: Operation completed successfully
- `1` - Created: Resource created successfully
- `2` - Accepted: Operation accepted for processing
- `3` - No Content: Success with no response data

**Error Codes (10-63):**
- `10` - Bad Request: Invalid request parameters
- `11` - Unauthorized: Authentication required
- `13` - Forbidden: Authorization failed
- `14` - Not Found: Resource not found
- `15` - Timeout: Operation timed out
- `50` - Internal Error: Server-side error

**Control Flow (64-127):**
- `64` - Retry: Operation should be retried
- `65` - Cancelled: Operation was cancelled
- `66` - Redirect: Operation redirected to different handler

### Event-Specific Codes (128-255)

Available for custom continuations defined by specific event types.

### S-Expression Usage

S-expressions can use both numeric codes and text labels for standard codes:

```zig
// Using numeric codes
const workflow1 = parseSexpr("(file:read (0 file:edit) (14 file:create))");

// Using text labels (mapped to standard codes)
const workflow2 = parseSexpr("(file:read (ok file:edit) (not_found file:create))");
```

## Architecture

### Compile-Time Continuation Methods

Event types define their continuation methods at compile time. These methods are statically known and type-safe:

```zig
const FileReadEvent = struct {
    // ... standard event fields ...

    // Compile-time defined continuation methods
    pub fn success(self: FileReadEvent, data: []const u8) void {
        self.continueWith(.success, data);
    }

    pub fn file_not_found(self: FileReadEvent, path: []const u8) void {
        self.continueWith(.file_not_found, path);
    }

    pub fn permission_denied(self: FileReadEvent, user: []const u8) void {
        self.continueWith(.permission_denied, user);
    }
};
```

### Continuation Tree (Routing Only)

Events carry a continuation tree in their payload that describes routing between pre-defined continuation points. The continuation tree and cursor state are managed by BEIST/OS user-space libraries:

```zig
const ContinuationNode = struct {
    branch_code: u8,             // Continuation code (0=ok, 10=bad_request, etc.)
    routing_bloom: u64,          // Routing bloom for next destination
    next: ?*ContinuationNode,    // Next node in chain
    subtree: ?*ContinuationNode, // Branch subtree
};

// BEIST/OS library checks for continuation metadata in payload
if (event.hasContinuationMetadata()) {
    // Event has routing information for continuation workflows
}
```

### S-Expression Parser

Parse runtime routing definitions between compile-time defined continuation methods:

```zig
// Parse routing: (file:read (success file:process (ok file:save)) (file_not_found file:create))
pub fn parseSexpr(expr: []const u8) !*ContinuationNode {
    // Parse s-expression into routing tree structure
    // Maps continuation method names to routing blooms
    // Continuation methods themselves are defined at compile time on event types
    return try parseRoutingExpression(expr);
}
```

### Tree Packing Strategies

**Full Tree**: Serialize entire routing tree into event payload for complex branching.

**Cursor Only**: Store tree in shared buffer, pass cursor index for efficiency.

```zig
// BEIST/OS user-space function
pub fn attachRouting(event: *Event, tree: *ContinuationNode) void {
    if (tree.size() < 4096) {
        // Pack full routing tree into payload
        event.setContinuationMetadata(tree, 0); // cursor = 0
    } else {
        // Use cursor approach with shared tree
        const shared_tree = shareContinuationTree(tree);
        event.setContinuationMetadata(shared_tree, 0);
    }
}
```

### Routing Control Flow

S-expressions define routing control flow between compile-time defined continuation methods:

- **Sequential Flow**: Route from one continuation method to another
- **Branching**: Route different continuation methods to different destinations
- **Loops**: Route continuations back to earlier points in the workflow
- **Complex Workflows**: Arbitrary routing graphs between continuation points

```zig
// Example: routing with loops
const workflow = parseSexpr(`
    (file:read
        (success file:process
            (ok file:save)
            (validation_error file:read))  // Loop back on validation error
        (file_not_found file:create
            (ok file:read))  // Loop back to retry
        (permission_denied security:alert))
`);

// Processor calls compile-time defined continuation methods
pub fn handleFileRead(event: FileReadEvent) void {
    if (try readFile(event.path)) |data| {
        event.success(data);  // Routes to file:process
    } else |err| switch (err) {
        .not_found => event.file_not_found(event.path),     // Routes to file:create
        .permission => event.permission_denied(event.user), // Routes to security:alert
    }
}

pub fn handleFileProcess(event: FileProcessEvent) void {
    if (try validateAndProcess(event.data)) |result| {
        event.ok(result);  // Routes to file:save
    } else {
        event.validation_error(event.data);  // Routes back to file:read (loop)
    }
}
```

The s-expression defines the routing graph, but continuation methods are statically defined on event types for compile-time safety.

## Usage Example

### Simple Chain

```zig
// Define event types with compile-time continuation methods
const FileReadEvent = struct {
    pub fn success(self: FileReadEvent, data: []const u8) void { ... }
    pub fn error(self: FileReadEvent, code: u8, msg: []const u8) void { ... }
};

const FileEditEvent = struct {
    pub fn ok(self: FileEditEvent, edited: []const u8) void { ... }
};

const FileWriteEvent = struct {
    pub fn ok(self: FileWriteEvent) void { ... }
};

// Define routing between continuation methods
const workflow = parseSexpr("(file:read (success file:edit) (error system:log))");

// Execute with event
const event = file.read("input.txt").withRouting(workflow);

// When file:read succeeds:
// - Processor calls event.success(data)
// - Routing looks up "success" -> routes to file:edit
// - file:edit processor calls event.ok(edited_content)
// - Routing looks up "ok" -> routes to file:write
```

### Complex Branching

```zig
// Event types define their continuation methods
const ProcessDataEvent = struct {
    pub fn ok(self: ProcessDataEvent, result: []const u8) void { ... }
    pub fn error(self: ProcessDataEvent, code: u8, msg: []const u8) void { ... }
    pub fn retry(self: ProcessDataEvent) void { ... }
};

// Routing defines workflow between these methods
const workflow = parseSexpr(`
    (process:data
        (ok analyze:stats
            (ok output:json)
            (error output:text))
        (error log:error
            (ok retry:process)    // Route back to process:data
            (error alert:admin))
        (retry process:data))     // Explicit retry routing
`);

// Execute
const result = process.data(input).withRouting(workflow);
```

### Interactive Shell

```zig
// User defines routing at runtime between compile-time defined methods
const user_workflow = shell.parse("(grep 'ERROR' (found wc -l) (not_found echo 'No errors'))");
const result = shell.execute("cat log.txt").withRouting(user_workflow);
```

## Implementation Details

### S-Expression Parser

Parse runtime routing definitions between continuation codes. This lives in BEIST/OS user-space libraries:

```zig
pub fn parseSexpr(expr: []const u8) !*ContinuationNode {
    var parser = SexpParser.init(expr);
    const root = try parser.parseRoutingNode();

    // Map text labels to standard codes (ok -> 0, not_found -> 14, etc.)
    try mapLabelsToCodes(root);

    // Generate routing blooms at runtime
    try generateRoutingBlooms(root);

    return root;
}
```

#### S-Expr Syntax

S-expressions define routing trees where each node specifies a continuation code and its routing destinations:

```zig
// Basic routing using codes: (event_type code destination_event_type)
(file:read (0 file:edit) (14 file:create))

// Using text labels (mapped to codes): (event_type label destination_event_type)
(file:edit
    (ok file:write)
    (not_found file:create)  // Maps to code 14
    (internal_error system:alert))  // Maps to code 50

// Complex workflow with loops
(process:data
    (ok analyze:stats
        (ok output:json)
        (error output:text))
    (error log:error
        (ok process:data))  // Retry loop
    (retry process:data))
```

The parser maps text labels to standard continuation codes for runtime composability.

### Tree Packing and Cursor Management

**Full Tree Packing**:
```zig
pub fn serializeRoutingTree(tree: *ContinuationNode) []u8 {
    // Serialize routing tree structure into bytes
    // Include bloom values and continuation method names
    return try serialize(tree);
}
```

**Cursor Approach**:
```zig
pub fn continueWith(event: *Event, continuation_name: []const u8, new_payload: []const u8) void {
    // Update payload
    @memcpy(event.data[0..new_payload.len], new_payload);

    // Look up continuation routing in tree
    const next_route = event.routing_tree.lookup(continuation_name);

    // Update routing bloom for next destination
    event.frame.routing_bloom = next_route.bloom;

    // Re-enqueue with updated routing
    ring.tryEnqueue(event.frame);
}
```

### Event Propagation

When a continuation method is called, the BEIST/OS user-space library:

1. Overwrites payload with new data
2. Looks up continuation code in routing tree
3. Updates routing_bloom for next destination
4. Creates new event with updated cursor
5. Re-enqueues event for routing

```zig
// Continuation methods defined at compile time on event types
pub fn success(self: FileReadEvent, data: []const u8) void {
    // BEIST/OS library handles continuation logic
    continuations.continueWith(self, .ok, data);
}

pub fn error(self: FileReadEvent, code: u8, message: []const u8) void {
    const payload = try std.fmt.allocPrint(self.allocator, "Error {}: {s}", .{code, message});
    defer self.allocator.free(payload);
    continuations.continueWith(self, .internal_error, payload);
}
```

### Processor Integration

Processors call compile-time defined continuation methods on events. The BEIST/OS continuation library handles the routing logic:

```zig
// Processor for file read events
pub fn handleFileRead(event: FileReadEvent) void {
    // Process file
    if (try processFile(event.path)) |data| {
        event.success(data);  // BEIST/OS library routes to next step
    } else |err| switch (err) {
        .not_found => event.file_not_found(event.path),
        .permission => event.permission_denied(event.user),
    }
}

// Processor for file processing events
pub fn handleFileProcess(event: FileProcessEvent) void {
    if (try validateAndProcess(event.data)) |result| {
        event.ok(result);
    } else {
        event.validation_error(event.data);
    }
}
```

Continuation methods are defined at compile time for type safety, while routing logic lives in BEIST/OS user-space libraries.

### Consumer Requirements

Event consumers work with events that have routing information attached:

```zig
pub fn handleFileRead(event: FileReadEvent) void {
    // Process file
    if (try processFile(event.path)) |data| {
        event.success(data);  // Route to next step via attached routing
    } else |err| switch (err) {
        .not_found => event.file_not_found(event.path),
        .permission => event.permission_denied(event.user),
    }
}
```

## Benefits

### vs Traditional Pipes

1. **Compile-Time Safety**: Continuation methods are statically defined and type-checked
2. **Runtime Flexibility**: User-defined routing between compile-time continuations
3. **Performance**: Bloom routing with zero string parsing at runtime
4. **Arbitrary Branching**: Routing trees support complex workflows
5. **Turing-Complete Routing**: Loops and arbitrary control flow in routing graphs
6. **Composability**: Interactive command chains with automatic routing

### vs Event Streams

1. **Directed Flow**: Explicit routing paths vs broadcast
2. **State Preservation**: Payload updates maintain context through routing
3. **Error Propagation**: Structured error handling with routing navigation
4. **Interactivity**: Runtime-defined routing for shell-like usage
5. **Type Safety**: Compile-time defined continuation methods prevent runtime errors

## Performance Characteristics

- **Continuation Decision**: <50ns (bloom check + cursor advance)
- **Memory Overhead**: 32-4096+ bytes per tree (cursor vs full tree)
- **Chain Latency**: O(depth) where depth = tree depth
- **Throughput**: 100M+ continuations/sec
- **Parsing Overhead**: O(tree size) for s-expr parsing
- **Zero Allocations**: Pre-allocated trees and shared buffers

## Design Philosophy

### Imperative Core for Performance

RINGS maintains a fully imperative design at the library level, prioritizing performance over theoretical purity:

- **No Monadic Enforcement**: Event methods mutate payloads in-place for zero-copy operations
- **Processor Isolation**: Message-passing architecture naturally isolates state; shared state requires explicit coding
- **Performance First**: Avoids overhead of referential transparency checks in a 177M msgs/sec system
- **Layered Abstractions**: Higher-level systems (BEIST shell, AI layers) can add monadic behavior on top

### Why Not Monadic?

- **Overhead**: Pure functions create unnecessary copies in performance-critical paths
- **Complexity**: Enforcing purity adds runtime checks without clear benefits at this level
- **Flexibility**: Processors can choose functional or imperative styles based on needs
- **Reality**: In isolated, message-passing systems, "impurity" requires active effort to achieve

This design keeps RINGS lean and fast, delegating purity concerns to application layers where they add value.

## Integration with RINGS

Event continuations build directly on RINGS' core:

- **Bloom Routing**: Runtime-generated continuation blooms use same mechanism
- **Ring Topology**: Tree branches route through specialized rings
- **Security**: Continuation permissions via emission blooms
- **Memory Management**: Zero-copy payload with tree packing strategies
- **Shared Memory**: Continuation trees stored in shared buffers for cross-process chains

## Implementation Roadmap (BEIST/OS)

Since continuations are implemented as BEIST/OS user-space libraries on top of RINGS IPC primitives, the implementation roadmap focuses on the orchestration layer:

### Phase 1: Continuation Library Foundation
- [ ] Define ContinuationNode structure for routing trees
- [ ] Implement basic tree packing (cursor vs full tree) in payload
- [ ] Create continuation metadata format for event payloads
- [ ] Define standard continuation codes (0-255)

### Phase 2: S-Expression Parser
- [ ] Build SexpParser for routing expression parsing
- [ ] Implement text label to code mapping (ok → 0, not_found → 14)
- [ ] Runtime bloom generation for routing patterns
- [ ] Support for nested routing trees and branches

### Phase 3: Continuation Runtime
- [ ] Implement routing tree lookup and cursor advancement
- [ ] Add tree serialization/deserialization for payloads
- [ ] Create continueWith() helper functions
- [ ] Memory management for routing trees in shared buffers

### Phase 4: Event Type Integration
- [ ] Define continuation methods on event types at compile time
- [ ] Implement event type wrappers with continuation support
- [ ] Add type-safe payload handling in routing
- [ ] Error handling and recovery mechanisms

### Phase 5: Advanced Features
- [ ] Tree optimization (compression, deduplication)
- [ ] Conditional continuation evaluation
- [ ] Tree composition and merging utilities
- [ ] Cross-process continuation support

### Phase 6: Testing and Examples
- [ ] Unit tests for parser, tree operations, and routing
- [ ] Integration tests with RINGS event system
- [ ] Example implementations (file processing, loops, error handling)
- [ ] Performance benchmarks and optimization

### Phase 7: Ecosystem Integration
- [ ] Type-level event definitions with continuation contracts
- [ ] Shell syntax compiler to s-expr
- [ ] Visual debugging tools
- [ ] Documentation and tutorials

## Future Extensions

### Tree Optimization

Compress continuation trees for memory efficiency.

### Interactive Debugging

Visual tools to inspect and modify continuation trees at runtime.

### Tree Composition

Merge continuation trees from different domains.

### Distributed Trees

Cross-process continuation trees via shared memory rings.

### Caching

Cache parsed s-expressions for frequently used chains.

## Examples

See `examples/continuations/` for complete working examples including:

- S-expression parsing for routing definitions
- Event types with compile-time defined continuation methods
- File processing with routing loops
- Error recovery with routing branches
- Interactive shell command chains
- Cross-process distributed routing
- Control flow patterns in routing graphs

---

*Event Continuations: BEIST/OS orchestration layer for composable workflows on RINGS IPC primitives.*