Skip to content

Feature parity with pi-durable

This file tracks the capabilities of @earendil-works/pi-durable (repos/pi/packages/durable) and their Effect-native counterparts. Tick an item when it is implemented and covered by a test. Design and milestones are in Analysis and plan.

How to read the table columns:

  • Tier: Core is the first deliverable. Parity comes after core.
  • M: the milestone the item lands in (M1–M5 for core; P for the parity track).
  • pi ref: a README section or test file in repos/pi/packages/durable.
Done Feature Tier M pi ref
[x] Atomic commits: entries, documents, tasks and submissions in one batch Core M1 spec §Storage, session-*
[x] Single serialized commit line; observers see a change only after storage succeeds Core M1 spec inv. 1–3
[x] Uninterruptible once storage has admitted a commit Core M1 spec §Commit
[x] StorageRejected rolls back; any other storage failure poisons the session Core M1 session-*
[x] Global ID space; IDs never reused after a committed write Core M1 types
[x] Storage port + storage conformance suite (testing/StorageConformance.ts) Core M1 /testing registerStorageConformance
[x] MemoryStorage adapter Core M1 memory-storage
[x] SqlStorage adapter over any SqlClient (sqlite-node first; NodeSqliteStorage.layer({ filename })) Core M4 sqlite-storage, sqlite-facade
[x] SQL schema migrations Core M4 sqlite-migrations
[x] Crash recovery on disk (reopen the same file) Core M4 harness-*-recovery; examples 13, 23, 24, 31
[x] JsonlStorage adapter (sidecars, commit markers, torn-line recovery, fsync option) Parity P jsonl-storage
[ ] StorageLease port (single owner enforced) Parity P — (new)
Done Feature Tier M pi ref
[x] Root conversation created on first use (Conversation.root); agent choices land with pi.agent in M3 Core M1 Quick Start
[x] Additional ownerless conversations Core M1 More Conversations
[x] Custom entry kinds appended in commits Core M1 Concepts
[x] Built-in entries: user, assistant, system, tool-result, reset, compaction (Entry.Compaction) Core M3e entries.ts
[x] Context derivation: head marker, edits, dropping failed assistants, tool-result ordering and synthesis (Conversation.context) Core M3b harness-context
[x] Context edits (omit / replace) Core M3b harness-context
[x] Conversations owned by a task (subagent children): creation with owner liveness checks (M1), abort and idle semantics (M2) Core M2 Abort and Subagents
[ ] reset() with an optional handoff note Parity P Reset and Handoff
[x] Tx.forkConversation / Conversation.fork(id, at): transcript through the entry, state copied by fork policy Parity M3a session-forks
Done Feature Tier M pi ref
[ ] Document families (defineDocFamily, keyed members). Storage already supports key Parity P session-documents
[x] Typed state (State.session / State.conversation / State.task, pi’s defineDoc): Schema-typed, versioned, migrate Core M1 session-documents
[x] Scopes session / conversation Core M1 Your Own State
[x] Scope task (retired in the commit that makes the task terminal; kept while it is completing) Core M2 session-documents
[x] Storage as base + delta (JSON Patch), checkpointWhen Core M1 spec §Documents
[x] Read a snapshot (State.snapshot) and watch one document (State.watch, collapsing after 100 pending frames) Core M1 session-watches
[x] Live read-only state (State.live, pi’s Chord documentState) Parity M3a session-states
[x] conversationCreated hook and init / agent on create and fork Core M3b Your Own State
[x] history: "rewindable" + State.snapshotAsOf(ref, entryId), through fork ancestry Parity M3a session-checkpoints-migrations
[x] Fork policies initial / current / asOf (copies run inside storage; a copy accessed in the fork commit becomes one creation) Parity M3a session-forks
Done Feature Tier M pi ref
[x] Task.make: phases keyed by a Schema-typed checkpoint, plus an abort handler Core M2 harness-tasks
[x] Advancing only through TaskRuntime.commit; a phase with no durable progress faults Core M2 spec §Tasks
[x] Recovery: running becomes pending on open; resume dispatches Core M2 harness-tasks-recovery
[x] Child tasks and the ownership tree Core M2 Child Tasks
[x] waiting with allSettled / failFast Core M2 24-child-tasks
[x] completing holds until owned work drains Core M2 spec §Holds
[x] Bottom-up abort cascade, re-derived on open Core M2 harness-ownership
[x] Background boundary (background: true, abort({background: true})) Core M2 Abort and Subagents
[x] Versioning: a newer stored version blocks; migrate runs at reservation; a missing definition blocks Core M2 harness-lifecycle
[x] Task.await(id) (pi’s waitForTask) Core M2 Compaction example
[x] TaskDispatcher port + in-process adapter with a concurrency limit Core M2 — (new)
[x] TaskRegistry (installed task definitions, scoped install, change notification); extensions build on it in M5 Core M2 harness-registry
[x] Blocked reasons and per-task scheduling state (Scheduler.inspect); the Harness-level inspect joins with M3 Parity M2 harness-inspect
[x] Task graph view and watch (TaskGraph.get / TaskGraph.watch, JSON Patch frames) Parity M3e harness-task-graph, 24-child-tasks
[x] Invocation-bound conversation handles (TaskRuntime.conversation, ToolCall.conversation) Parity M3e harness-ownership
Done Feature Tier M pi ref
[x] Submit input, run generation, get the answer, settle the submission Core M3c Quick Start
[x] Streaming partials persisted to pi.live (100 ms trailing throttle) Core M3c harness-live-deltas
[x] Durable retry with backoff (retry{until} survives a restart) Core M3c harness-generation-recovery
[x] Error classification: retryable / overflow / fatal Core M3c harness-generation
[x] Thinking level, applied per request by the catalog model’s withThinking (the Anthropic mapping lands with anthropicProfile) Core M3c Per-Conversation Agent
[x] ModelCatalog: a stored ModelRef resolves to a LanguageModel layer with limits and pricing; FauxModel (a real effect/ai LanguageModel) Core M3c —
[ ] anthropicProfile (overflow detection, pricing, thinking) Core M4 —
[x] Stream timeout setting Core M3c Settings
[ ] Provider fallback (ExecutionPlan) Parity P — (new)
[ ] OpenAI / OpenRouter (just their @effect/ai-* model(...) + a profile) Parity P —
[ ] Deferred responses (poll, fetchDeferred, cancelDeferred) Parity P spec §generation
Done Feature Tier M pi ref
[x] Tools are the harness’s own Tool.make (Schema parameters, offered to effect/ai as Tool.dynamic declarations; see plan 4.7) Core M3c Tools
[x] Each call is a durable task; intent committed before execute Core M3c harness-tools
[x] Tool.Idempotent (pi replay: "safe") reruns after a crash; otherwise an interrupted result with partial output Core M3c harness-tools-recovery
[ ] Streamed output from preliminary results, committed with the adaptive throttle Core M3 harness-output
[x] ToolCall service (details, commit, conversation, env, taskId) as a tool dependency Core M3c Abort and Subagents
[x] Result truncation (50 KiB / 2000 lines) and diagnostics block Core M3c harness-output
[x] Thrown error becomes an error result; unknown tool / invalid args become error results Core M3c harness-tools
[x] Parallel vs sequential execution (setting and per-tool executionMode) Core M3c Settings
[x] Tool-reported usage Core M3c Tools
[x] ExecEnv port + NodeExecEnv (cwd per conversation; process-group kill on interrupt and timeout; output spill) Core M3d env-node, env-node-spill
[x] Coding tools read, write, edit, bash (CodingTools extension) Core M3d tools, env-truncate
[x] Per-file serialization of edit / write by env id and canonical path Core M3d tools
[x] control: { terminate } Parity M3c Tools
[ ] control: { handoff } Parity P Tools
[ ] addTools from a tool round Parity P spec §generation
[ ] Reading images Parity P (unsupported in pi too)
Done Feature Tier M pi ref
[x] requestId idempotency Core M3c Persist and Resume
[x] whenBusy: followUp (default), steer, reject → ConversationBusy Core M3c Busy Conversations
[x] write submissions (append without asking the model) Core M3c harness-submissions
[x] Withdrawing a queued submission (Submission.abort) Core M3c harness-inbox
[x] steeringMode / followUpMode "all" Core M3c Busy Conversations
[x] Reacquire and await a submission by ID after a restart Core M3c Persist and Resume
[x] Conversation.abort: withdraws queued inputs, aborts the work, resolves when idle Core M3c Abort and Subagents
[ ] Ingress adapters (at-least-once queue → idempotent submit) Parity P — (new)
Done Feature Tier M pi ref
[x] pi.agent state + Conversation.configure / Agent.configure (model, thinking, instructions, cwd) Core M3b Per-Conversation Agent
[x] Settings read at each use (Settings.layer(settings) with getters) Core M3b Settings
[x] Registry with install / uninstall / in-place replacement (resolution takes the current snapshot; no mid-invocation handover) Core M3b Reload, harness-registry
[ ] Extension.layer (install on build, uninstall on scope close) Core M5 — (new)
[x] Extension tools, with later same-name tools overriding earlier ones Core M3b 30-tool-override
[x] Extension tasks Core M3b Extensions
[x] System prompt sections + instructions Core M3c System Prompt
[x] pi.system diffing for prompt-cache stability Core M3c harness-prompt
[x] configure of extension / tool selection (add / remove / exact lists, null resets) Core M3b Per-Conversation Agent
[x] Generation hooks: beforeRequest, afterResponse, onYield, afterTools Parity M3c Hooks
[x] Tool hooks: beforeTool (block / rewrite), afterTool Parity M3c Hooks
[x] Wraps (Extension.wrapTool, Extension.wrapSection) in agent resolution Parity M3b 30-tool-override
Done Feature Tier M pi ref
[x] Manual Conversation.compact(id, instructions?); the task’s result carries the summary’s submission Parity M3e Compaction, 25-compaction
[x] Automatic blocking compaction above contextWindow - reserveTokens Parity M3e harness-compaction
[x] Background compaction (backgroundTokens) Parity M3e harness-compaction
[x] Overflow error leads to compact and retry once Parity M3e 25-compaction
[x] Stale summaries settle as stale Parity M3e spec §compaction
[x] beforeCompact hook (decline or supply a summary; Hooks.compaction) Parity M3e Compaction
[ ] Token estimates through the effect/ai Tokenizer (heuristic layer first; M3e estimates with pi’s chars/4 heuristic behind one internal module) Core M3 —
Done Feature Tier M pi ref
[x] Conversation view stream: entries + docs, per-commit ops (Conversation.view / Conversation.watch, JSON Patch instead of Chord ops) Core M3d Watching a Conversation
[x] Overflow collapses undelivered view frames and event batches into one snapshot (Session.MaxPendingWatchFrames, default 100), like document watches (M1); no separate ViewBuffer port Core M3d spec §watch
[x] AgentEvent stream (message_*, tool_execution_*) with snapshot-on-lag (AgentEvent.watch) Core M3d Agent Events
[x] Late join and reconnect start from the current view Core M3d 21-late-join
[x] Usage and cost per conversation (pi.usage) Core M3c Usage and Cost
[ ] Session-wide usage total (pi harness.usage()) Parity P Usage and Cost
[ ] Remote views and control over effect/rpc Parity P — (new)
[ ] Expose harness tools over MCP (McpServer.registerToolkit) Parity P — (new)

Subagents (examples on top of the primitives)

Section titled “Subagents (examples on top of the primitives)”
Done Feature Tier M pi ref
[x] Foreground subagent tool (replay-safe, owned child) Parity M3e 22-subagent-foreground
[x] Background persistent subagents (spawn, steer, stop, list, report back) Parity M3e 23-subagent-background
[x] Reviewer / plan-mode examples Parity M3d 27-plan-mode, 28-reviewer