# poc-crank-v2 Design Patterns Analysis for Dobby

**Branch analyzed:** `fix/static-device-execution` @ `https://github.com/dcx/poc-crank-v2`
**Date:** 2026-03-23
**Purpose:** Identify design patterns, principles, and code that can be learned or imported from poc-crank-v2 (the "Agentic" framework) to improve Dobby's architecture.

---

## Table of Contents

1. [Executive Summary](#1-executive-summary)
2. [Architecture Overview: poc-crank-v2](#2-architecture-overview-poc-crank-v2)
3. [Architecture Overview: Dobby](#3-architecture-overview-dobby)
4. [Pattern Comparison](#4-pattern-comparison)
5. [What fix/static-device-execution Does](#5-what-fixstatic-device-execution-does)
6. [Patterns to Adopt](#6-patterns-to-adopt)
7. [Patterns to Skip](#7-patterns-to-skip)
8. [Integration Proposals](#8-integration-proposals)
9. [Appendix: Key Code References](#9-appendix-key-code-references)

---

## 1. Executive Summary

poc-crank-v2 ("Agentic") is a **task-level agent execution framework** focused on effect-sourced state management, declarative task composition, and multi-backend device abstraction. Dobby is a **meta-agent orchestrator** focused on dispatching Claude Code agents, managing queues/priorities, and collecting results.

They operate at different levels of the stack:

```
                      poc-crank-v2 (Agentic)
                      ┌─────────────────────────────────┐
                      │ Task composition & combinators   │
                      │ Effect-sourced state management  │
                      │ Lifecycle pipeline (9 phases)    │  ← Inside the agent
                      │ Device abstraction (containers)  │
                      │ Provider abstraction (LLM SDKs)  │
                      └─────────────────────────────────┘
                                    │
                                    │ Agents execute tasks
                                    │
                      ┌─────────────────────────────────┐
                      │ Dobby                            │
                      │ Task queuing & scheduling        │
                      │ Agent dispatch & monitoring       │  ← Around the agents
                      │ Result collection & parsing      │
                      │ Git worktree isolation           │
                      │ Spoke (remote) execution         │
                      └─────────────────────────────────┘
```

**Key takeaways:**
- **6 patterns worth adopting** from poc-crank-v2 into Dobby
- **3 patterns to skip** (wrong abstraction level for Dobby)
- **3 concrete integration proposals** with estimated complexity

---

## 2. Architecture Overview: poc-crank-v2

### Three-Layer Model

```
Layer 1 — Scope (Resource Container)
├── Bindings (execution contexts: workspace, session, etc.)
├── Providers (LLM SDK adapters)
├── Effect Stream (append-only log of all changes)
└── Fork/merge/discard (speculative execution)

Layer 2 — ExecutionLifecycle (Task Orchestrator)
├── 9-phase pipeline: configure → prepare → cache-check → execute →
│                      artifact → extract → apply → cache-store → cleanup
├── Phase protocol: execute() + rollback()
├── PhaseContext carries state through pipeline
└── Dual-path: LLM tasks vs programmatic tasks

Layer 3 — Provider / Device (Execution Backend)
├── Provider: LLM SDK adapter (Claude, OpenAI, LiteLLM)
├── Device: Execution environment (container, e2b, modal, k8s, prime)
└── Sandbox: Isolated filesystem with overlay extraction
```

### Key Abstractions

| Abstraction | Purpose | Key Pattern |
|---|---|---|
| **Scope** | Resource container + effect stream | Event-sourced state; fork/merge for speculation |
| **ExecutionLifecycle** | Single task execution | 9-phase pipeline with rollback |
| **Task (@task)** | Declarative task definition | Pydantic model with typed field markers |
| **Combinator** | Task composition | Fork-based isolation: retry, parallel, gate, speculate |
| **Device** | Execution environment | Protocol-based; pluggable backends |
| **Effect** | State change record | Dual-route: binding_name (stable) or context_id (semantic) |
| **Attribution** | Task provenance | Tracks source (LLM vs programmatic) + provider |

### Combinator Library

```python
# Composition
sequence(task1, task2)        # Chain with output→input piping
branch(predicate, t1, t2)    # Conditional execution
loop(task, until=pred)        # Iterative refinement

# Retry & Recovery
retry(task, max_attempts=3, backoff=1.0)  # Fork per attempt, discard on failure
fallback(task1, task2)                     # Try in order, use first success
recover(task, on_error=handler)            # Replace exceptions with fallback

# Parallel & Speculation
parallel(task1, task2, merge=DisjointMerge())  # Concurrent with conflict detection
race(task1, task2)                              # First to complete wins
speculate(task)                                 # Manual commit/abandon control

# Gating & Budget
gate(task, predicate)         # Approve/reject based on result + effects
budget(task, Budget(...))     # Reject if exceeds resource limits
timeout(task, seconds)        # Time-bounded execution

# Effect Manipulation
filter_effects(task, pred)    # Only merge matching effects
map_effects(task, transform)  # Modify effects before merge
tap(task, observer)           # Side-effect logging/metrics
```

### Error Hierarchy

```
AgenticError (base)
├── ConfigurationError      (configure phase — pure, safe)
├── PreparationError        (prepare phase — rollback needed)
├── ExecutionError          (execute phase)
│   ├── SDKExecutionError
│   └── CapabilityError
├── ContainmentError        (scope violations)
├── MaterializationError    (with rollback_errors tracking)
├── CheckFailedError        (pre/post condition checks)
└── TaskExecutionError      (task-level failure)
```

### Export System (Three Tiers)

| Tier | Format | Use Case | Lossiness |
|---|---|---|---|
| 1 | Flat JSON | Quick inspection, no deps | Lossy (flat timeline) |
| 2 | ATIF | Harbor integration | Lossy (step grouping) |
| 3 | Trajectory (dir) | Full replay, debugging | Lossless (preserves scope tree + discarded branches) |

---

## 3. Architecture Overview: Dobby

### Component Model

```
DobbyDaemon (asyncio + aiohttp, port 8420)
├── Store (SQLite with WAL, JSON blobs)
├── QueueManager (priority + per-project concurrency)
├── Dispatcher (subprocess management, semaphore)
├── Collector (multi-format result parsing)
├── EventBus (SSE notifications)
├── WorktreeManager (git worktree lifecycle)
├── GPU Monitor (two-phase remote job tracking)
└── Integration Points
    ├── REST API (~30 endpoints)
    ├── MCP Server (Claude Code tools)
    ├── Slack Bot (interactive task submission)
    └── Spoke Agent (remote execution)
```

### Task Lifecycle

```
DRAFTING → PENDING → RUNNING → COMPLETED
                  ↘           ↗
                   → FAILED → (retry) → PENDING
                  ↘
                   → CANCELLED / PAUSED
```

### Key Patterns

| Pattern | Implementation | Notes |
|---|---|---|
| **Dispatch** | Subprocess spawn (claude CLI) | No in-process agent execution |
| **Isolation** | Git worktrees | Branch per task, auto-merge on success |
| **Scheduling** | ONCE / CRON / INTERVAL / AFTER | croniter + dependency chains |
| **Concurrency** | Global semaphore + per-project locks | Configurable limits |
| **Resilience** | Stale detection + restart recovery | Marks RUNNING→FAILED on daemon restart |
| **Results** | Multi-format parsing with fallback chain | Codex JSONL, Claude JSONL, DOBBY_RESULT block |
| **Remote** | Spoke agent (poll + claim + heartbeat) | Lightweight distributed execution |

---

## 4. Pattern Comparison

### 4.1 Task Execution

| Aspect | poc-crank-v2 | Dobby |
|---|---|---|
| **Granularity** | Individual LLM calls / function calls | Full agent sessions (minutes to hours) |
| **Execution** | In-process (async) or container | Subprocess (claude CLI) |
| **State** | Effect stream (append-only log) | SQLite rows (status + JSON blob) |
| **Composition** | Combinators (sequence, parallel, gate) | AFTER dependencies + auto-chain |
| **Isolation** | Scope fork/merge/discard | Git worktree per task |
| **Retry** | Per-attempt fork with effect discard | Re-queue task as PENDING |

### 4.2 Error Handling

| Aspect | poc-crank-v2 | Dobby |
|---|---|---|
| **Hierarchy** | Rich typed hierarchy (15+ error types) | Generic exceptions + status transitions |
| **Recovery** | Phase-level rollback, OnError policies | Mark FAILED + retry via API |
| **Stale detection** | N/A (in-process) | Log mtime monitoring |
| **Conflict resolution** | DisjointMerge / LastWriteWins | checkout --theirs (always accept branch) |

### 4.3 Device / Resource Management

| Aspect | poc-crank-v2 | Dobby |
|---|---|---|
| **Abstraction** | DeviceProtocol with capabilities enum | InfraConfig (SSH host + conda env) |
| **Backends** | Container, E2B, Modal, K8s, Daytona, Prime | Local + SSH remote |
| **Sandboxing** | OverlayFS with effect extraction | Git worktree (file-level isolation) |
| **Resource limits** | SandboxConfig (CPU, memory, disk, timeout) | Per-task timeout only |

### 4.4 Result Collection

| Aspect | poc-crank-v2 | Dobby |
|---|---|---|
| **Format** | Typed Effect stream with structured export | Free-form text parsed via regex/heuristics |
| **Export** | Three tiers (JSON, ATIF, Trajectory) | DOBBY_RESULT JSON block |
| **Observability** | Effect stream comparison (divergence scores) | Task events journal |

---

## 5. What fix/static-device-execution Does

### Problem

Previously, programmatic tasks (Python `@task` classes with custom `execute()` methods) always ran **in-process**, even when a container device was active. Only LLM tasks got container isolation.

### Solution: Dual-Path Execution

The branch introduces `TaskSpec` and extends `ExecutionSpec` to enable container-based execution of programmatic tasks:

```python
@dataclass(frozen=True)
class TaskSpec:
    task_source: str            # Python source of @task class
    task_class_name: str        # Class name to reconstruct
    task_imports: tuple[str, ...]
    task_inputs: Mapping[str, Any]   # Serialized inputs
    output_fields: tuple[str, ...]
    context_fields: Mapping[str, str]
    is_async: bool = False

@dataclass(frozen=True)
class ExecutionSpec:
    prompt: str
    provider_config: Mapping[str, Any]
    task_spec: TaskSpec | None = None  # None = LLM path, set = programmatic path
```

### Key Design Decisions

1. **Shared scaffold**: Both LLM and programmatic paths use the same `_execute_on_device_scaffold()` — cache check, sandbox creation, effect extraction, cleanup.

2. **Graceful fallback**: If no device is active, source code isn't available, or the executor isn't a bound method, falls back to in-process execution silently.

3. **Task reconstruction in container**: The container's `task_runner.py` reconstructs the task class from source code, suppresses auto-execution, attaches deserialized contexts, then calls `execute()`.

4. **Mandatory session forking**: Container execution always forks sessions (never overwrites parent) because container execution is inherently speculative.

5. **Attribution model**: New `Attribution` dataclass tracks whether execution was LLM or programmatic, with provider_id being optional for programmatic tasks.

### Relevance to Dobby

The dual-path pattern is directly relevant. Dobby currently only dispatches Claude Code agents (analogous to poc-crank-v2's "LLM path"). The "programmatic path" pattern could enable Dobby to:
- Execute Python functions/scripts as first-class tasks alongside agent tasks
- Use the same dispatch, monitoring, and result collection infrastructure
- Enable hybrid workflows (agent generates plan → Python script executes steps)

---

## 6. Patterns to Adopt

### P1: Structured Error Hierarchy

**What:** Replace generic exceptions with a typed error hierarchy rooted in `DobbyError`.

**Why:** Dobby currently relies on status transitions and string-based error messages. Typed errors enable:
- Programmatic error handling (catch `DispatchError` vs `TimeoutError`)
- Error context preservation (original error + rollback failures)
- Debug hints pointing to relevant logs/state

**Proposed hierarchy:**
```python
class DobbyError(Exception):
    @property
    def debug_hint(self) -> str: ...

class DispatchError(DobbyError): ...       # Agent spawn failed
class TimeoutError(DobbyError): ...        # Execution exceeded timeout
class CollectionError(DobbyError): ...     # Result parsing failed
class WorktreeError(DobbyError): ...       # Git worktree operation failed
class MergeConflictError(DobbyError): ...  # Merge failed (currently silent)
class SpokeError(DobbyError): ...          # Remote execution failed
class DependencyError(DobbyError): ...     # AFTER dependency failed
class StaleTaskError(DobbyError): ...      # Task detected as stale
```

**Complexity:** Low. Can be introduced incrementally.

### P2: Structured Result Format with Export Tiers

**What:** Replace free-form DOBBY_RESULT parsing with structured result types and multi-tier export.

**Why:** Dobby's Collector uses a 5-stage fallback chain to parse agent output, which is fragile. poc-crank-v2's three-tier export model provides a clean solution:

| Tier | Dobby Equivalent | Purpose |
|---|---|---|
| 1: Flat JSON | DOBBY_RESULT block (current) | Quick status + summary |
| 2: Structured | New: typed Result with artifacts/metrics | Machine-readable results |
| 3: Full log | Raw agent.log (current) | Debugging and replay |

**Proposed `DobbyResult` model:**
```python
@dataclass
class DobbyResult:
    status: Literal["completed", "failed"]
    summary: str
    pr_url: str | None = None
    files_changed: list[str] = field(default_factory=list)
    metrics: dict[str, float] = field(default_factory=dict)
    error: str | None = None
    cost: CostInfo | None = None

    # Export methods
    def to_json(self) -> str: ...
    def to_dict(self) -> dict: ...
```

**Complexity:** Medium. Requires updating Collector + agent prompt format.

### P3: Task Combinators for Workflow Composition

**What:** Introduce combinators for composing Dobby tasks into workflows.

**Why:** Dobby currently supports only AFTER dependencies (sequential). poc-crank-v2's combinators enable richer patterns. The most valuable for Dobby:

1. **sequence(task1, task2)**: Already exists as AFTER, but formalized
2. **parallel(task1, task2, merge_strategy)**: Run N tasks concurrently, merge results
3. **retry(task, max_attempts, backoff)**: Already exists informally, but with exponential backoff
4. **gate(task, check_fn)**: Run task, approve/reject result before merging
5. **fallback(task1, task2)**: Try preferred approach, fall back on failure

**Implementation sketch:**
```python
# In Dobby's batch API
batch = DobbyBatch(project="my-project")
batch.add("task-a", description="...")
batch.add("task-b", description="...", depends_on="task-a")  # sequence
batch.add("task-c", description="...", depends_on="task-a")  # parallel with task-b
batch.add("task-d", description="...",
          depends_on=["task-b", "task-c"],                   # fan-in
          gate=lambda r: r.metrics.get("test_pass_rate", 0) > 0.95)  # gate
```

**Complexity:** Medium. Extends existing AFTER + batch system.

### P4: Device Protocol for Execution Backends

**What:** Abstract execution backends behind a protocol, enabling pluggable dispatch.

**Why:** Dobby currently hardcodes two dispatch modes (local subprocess, SSH remote). poc-crank-v2's `DeviceProtocol` shows how to abstract this cleanly:

```python
class DobbyBackend(Protocol):
    """Pluggable execution backend."""

    async def create_workspace(self, task: Task) -> Workspace: ...
    async def execute(self, workspace: Workspace, task: Task) -> RawResult: ...
    async def collect_result(self, workspace: Workspace) -> DobbyResult: ...
    async def cleanup(self, workspace: Workspace) -> None: ...

    @property
    def capabilities(self) -> BackendCapabilities: ...

@dataclass
class BackendCapabilities:
    supports_gpu: bool = False
    supports_worktree: bool = True
    isolation: Literal["worktree", "container", "vm"] = "worktree"
    max_concurrent: int = 5
```

Implementations:
- `LocalBackend`: Current worktree + subprocess logic
- `SpokeBackend`: Current SSH/spoke logic
- `ContainerBackend`: Docker/Podman isolation (from poc-crank-v2)
- `ModalBackend`: Modal sandbox (future)

**Complexity:** Medium-High. Requires refactoring Dispatcher.

### P5: Speculative Execution with Commit/Abandon

**What:** Enable "dry run" task execution where results can be reviewed before merging.

**Why:** Dobby auto-merges worktree on task completion. poc-crank-v2's `speculate()` combinator shows a cleaner pattern:

```python
# Current Dobby: auto-merge on success
task → worktree → execute → success? → merge to main

# Proposed: speculative execution
task → worktree → execute → success? → hold for review
                                        → approve → merge
                                        → reject → discard worktree
```

This maps naturally to Dobby's existing checkpoint mode, but formalized as a first-class concept.

**Implementation:** Add `speculative: bool` field to Task model. When true, completed tasks enter a REVIEW state instead of auto-merging. Expose approve/reject endpoints.

**Complexity:** Low-Medium. Extends existing checkpoint flow.

### P6: Effect Stream Comparison for Result Analysis

**What:** Compare results across task attempts or similar tasks using structured divergence analysis.

**Why:** poc-crank-v2's `compare_streams()` produces quantified divergences (significance 0.0–1.0) across multiple aspects. For Dobby, this enables:

- Comparing retry attempts to understand what changed
- Comparing results across different backends (Claude vs Codex)
- Detecting regressions in recurring tasks

**Implementation sketch:**
```python
def compare_results(result_a: DobbyResult, result_b: DobbyResult) -> ComparisonReport:
    return ComparisonReport(
        same_outcome=result_a.status == result_b.status,
        same_files=set(result_a.files_changed) == set(result_b.files_changed),
        metric_deltas={
            k: result_b.metrics.get(k, 0) - result_a.metrics.get(k, 0)
            for k in set(result_a.metrics) | set(result_b.metrics)
        },
        divergences=[...],  # Structured list of differences
    )
```

**Complexity:** Low. Can be implemented as a utility function.

---

## 7. Patterns to Skip

### S1: Effect-Sourced State Management (Scope + Effects)

**Why skip:** poc-crank-v2's scope/effect system is designed for fine-grained, in-process state tracking (individual tool calls, file changes). Dobby operates at the session level where SQLite + git history provides equivalent state tracking with much less complexity.

### S2: 9-Phase Lifecycle Pipeline

**Why skip:** The lifecycle pipeline manages intra-task execution phases (configure bindings → prepare contexts → execute → extract effects → apply). Dobby's task lifecycle is simpler and appropriate for its abstraction level (queue → dispatch → monitor → collect).

### S3: Declarative Task Definition (@task decorator with field markers)

**Why skip:** poc-crank-v2's `@task` decorator with `Input(T)`, `Output(T)`, `Context(T)` markers is designed for composable, typed LLM task pipelines. Dobby tasks are free-form natural language instructions dispatched to agents. Adding typed task definitions would over-constrain the system.

---

## 8. Integration Proposals

### Proposal A: Structured Backend Protocol (Priority: High)

**Goal:** Replace hardcoded dispatch logic with a pluggable backend protocol.

**Files to modify:**
- `dobby/core/dispatcher.py` → Extract `LocalBackend`, `SpokeBackend`
- `dobby/models.py` → Add `BackendCapabilities`
- New: `dobby/backends/protocol.py`, `dobby/backends/local.py`, `dobby/backends/spoke.py`

**Steps:**
1. Define `DobbyBackend` protocol with `create_workspace`, `execute`, `collect_result`, `cleanup`
2. Extract current local dispatch logic into `LocalBackend`
3. Extract current spoke/SSH logic into `SpokeBackend`
4. Update Dispatcher to route via backend selection
5. Add `ContainerBackend` stub for future Docker/Podman support

**Benefits:**
- Clean separation of concerns
- Easy to add new backends (Modal, E2B, etc.)
- Testable dispatch logic (mock backends)
- Enables hybrid execution (some tasks local, some remote, some containerized)

### Proposal B: Workflow Combinators (Priority: Medium)

**Goal:** Enable rich task composition beyond sequential AFTER dependencies.

**Files to modify:**
- `dobby/core/queue.py` → Add parallel fan-in resolution
- `dobby/models.py` → Extend schedule/dependency model
- New: `dobby/core/workflow.py`

**Steps:**
1. Add `fan_in` dependency type (task depends on ALL of a set completing)
2. Add `gate` field to Task (condition evaluated post-completion)
3. Add `fallback_task_id` field (alternative if primary fails)
4. Implement `retry_with_backoff` (exponential delay between retries)
5. Expose workflow API: `POST /workflows` with DAG specification

**Benefits:**
- Complex multi-agent workflows without manual orchestration
- Gate checks prevent bad results from propagating
- Fallback enables graceful degradation

### Proposal C: Speculative Execution Mode (Priority: Medium)

**Goal:** Allow task results to be reviewed before merging to main.

**Files to modify:**
- `dobby/models.py` → Add `speculative` field, REVIEW status
- `dobby/core/daemon.py` → Skip auto-merge for speculative tasks
- `dobby/core/api.py` → Add `/tasks/{id}/approve`, `/tasks/{id}/reject`
- `dobby/core/worktree.py` → Support deferred merge

**Steps:**
1. Add `speculative: bool = False` to Task model
2. Add `REVIEW` to TaskStatus enum (between RUNNING and COMPLETED)
3. On speculative task success: transition to REVIEW, keep worktree alive
4. Expose approve endpoint: merge worktree → COMPLETED
5. Expose reject endpoint: discard worktree → CANCELLED
6. Add timeout for REVIEW state (auto-reject after N hours)

**Benefits:**
- Human-in-the-loop approval for critical tasks
- Safe experimentation (agent can try, human decides)
- Natural extension of existing checkpoint mode

---

## 9. Appendix: Key Code References

### poc-crank-v2 (Agentic Framework)

| Component | Path | Key Patterns |
|---|---|---|
| Scope (immutable core) | `packages/agentic-core/src/agentic_core/scope/model.py` | Event-sourced state, fork/merge |
| Scope (mutable proxy) | `packages/agentic-core/src/agentic_core/scope/scope.py` | Proxy pattern over immutable core |
| Lifecycle pipeline | `packages/agentic-core/src/agentic_core/lifecycle/lifecycle.py` | 9-phase pipeline with rollback |
| Phase protocol | `packages/agentic-core/src/agentic_core/lifecycle/_pipeline.py` | Phase.execute() + Phase.rollback() |
| Task mixin | `packages/agentic-core/src/agentic_core/task/_mixin.py` | Dual-path execution (LLM vs programmatic) |
| TaskSpec | `packages/agentic-core/src/agentic_core/foundation/protocols/device.py` | Serializable task specification |
| Container task runner | `packages/agentic-core/src/agentic_core/device/container/task_runner.py` | Reconstruct + execute in container |
| Device protocol | `packages/agentic-core/src/agentic_core/foundation/protocols/device.py` | Pluggable execution backends |
| Combinators | `packages/agentic-core/src/agentic_core/combinators/` | retry, parallel, gate, speculate |
| Error hierarchy | `packages/agentic-core/src/agentic_core/errors.py` | 15+ typed error classes |
| Effect comparison | `packages/agentic-core/src/agentic_core/effects/comparison.py` | Stream divergence analysis |
| Agent facade | `packages/agentic/src/agentic/agent.py` | High-level Agent + Result |
| Export: JSON | `packages/agentic-core/src/agentic_core/export/json_export.py` | Tier 1 flat JSON |
| Export: ATIF | `packages/agentic-core/src/agentic_core/export/atif.py` | Tier 2 Harbor format |
| Export: Trajectory | `packages/agentic-core/src/agentic_core/export/trajectory.py` | Tier 3 lossless |
| Meta: Optimize | `packages/agentic-core/src/agentic_core/meta/optimize.py` | Task optimization from feedback |

### Dobby

| Component | Path | Key Patterns |
|---|---|---|
| Daemon (orchestrator) | `dobby/core/daemon.py` | Main loop, recovery, GPU monitoring |
| Dispatcher | `dobby/core/dispatcher.py` | Subprocess spawn, semaphore, PID tracking |
| Queue manager | `dobby/core/queue.py` | Priority + per-project concurrency |
| Collector | `dobby/core/collector.py` | Multi-format result parsing |
| Worktree manager | `dobby/core/worktree.py` | Git worktree lifecycle |
| Models | `dobby/models.py` | Task, Result, Project, Spoke |
| API | `dobby/core/api.py` | REST endpoints + EventBus |
| Spoke agent | `dobby/core/spoke_agent.py` | Remote execution + heartbeat |
| MCP server | `dobby/mcp/server.py` | Claude Code tool integration |

---

## Summary Matrix

| Pattern | poc-crank-v2 | Dobby Today | Recommendation | Priority |
|---|---|---|---|---|
| Error hierarchy | Rich typed hierarchy | Generic exceptions | **Adopt** (P1) | High |
| Structured results | Three-tier export | Regex parsing | **Adopt** (P2) | High |
| Task combinators | Full combinator library | AFTER only | **Adopt** (P3) | Medium |
| Backend protocol | DeviceProtocol | Hardcoded dispatch | **Adopt** (P4) | High |
| Speculative execution | speculate() combinator | Auto-merge only | **Adopt** (P5) | Medium |
| Result comparison | Stream divergence | None | **Adopt** (P6) | Low |
| Effect-sourced state | Scope + Effects | SQLite + git | **Skip** (S1) | — |
| Lifecycle pipeline | 9-phase pipeline | Simple lifecycle | **Skip** (S2) | — |
| Typed task definition | @task decorator | Free-form instructions | **Skip** (S3) | — |
