One of Tap’s three primitive planes. Replay takes an immutable bare v2 Plan plus your identity context and produces rows. Zero LLM tokens — the plan is already compiled. This is the plane that ships in every Tap install and runs forever.
Replay solves A2 (LLMs are probabilistic) by separating compile-time AI use from run-time execution: AI participates in Capture, never in Replay. It also solves R2 (copies drift) — the plan is a single artifact every runtime targets, so there’s only one source of truth to keep in sync.
| Component | Role |
|---|---|
plan-runtime |
the op-handler dispatcher (INV-P3 pure: no new Worker, no new Function, no bare eval, no dynamic import) |
plan-dispatch |
the tapToPlanHandle adapter + the bounded exec op bridge |
plan-lint |
static lint at save / capture / resolvePlan time |
| Op handlers | one per op-name; the closed 11-op v2 union (7 substrate · 3 control flow · 1 typed-eval) |
Replay can only execute ops in the closed OP_NAMES_V2 set defined by @taprun/spec v1.0+. Adding an op requires:
2026-05-03-unified-tap-primitive).This keeps Replay’s surface stable and re-implementable across runtimes (Chrome extension / Playwright / macOS).
Replay is the runtime-neutral substrate. Concrete runtimes implement the op handlers:
| Runtime | Where | Default for |
|---|---|---|
| Chrome extension | the user’s logged-in browser | MCP tools, write actions |
| Playwright | local headless / headed Chromium | --runtime playwright |
| macOS | AX API + JXA + CGEvent | --runtime macos |
All three replay the same .tap.json against the same op semantics. Identity (cookies / API keys / OS-level auth) flows through the identity cross-cut, never embedded in the plan.
observe; write variant declares act+confirm).plan-v1 reference — the format Replay executes