# Span-level replay: fork from the failure — full documentation (P12) Provider: TextForAgents LLC · Support: support@textforagents.com ## What it does Fork-replay ONE recorded span out of a failed agent run and return an attribution verdict, without re-running the whole run. A span is one JSON tool or model step as recorded by a tracer (normalized JSONL span records, or OTel-shaped spans including LangGraph/Langfuse-shaped foreign traces). ## Verdict taxonomy (unchanged from the lab) - DETERMINISTIC-OK (determinism) — replay reproduces the recorded output/tool_call. - TOOL-NONDETERMINISM — same span, same env, two live executions disagree. - TOOL-DRIFT — live output differs from the recording AND the env diff touches tool_version / tool_schema_hash. - ENV-DRIFT — live output differs AND the env diff touches other fields. - WORLD-STATE — deterministic now, env identical, output still differs: the world the tool reads changed. - MODEL-DECISION — (model spans) the second-model replay of the recorded prompt/schema produces a different tool_call. - UNREPLAYABLE — the span cannot be executed safely (stub miss on a side-effecting tool, oversized/malformed span, env_digest tamper, rate/budget cap, executor error). The reason field says which. ## The live/stub split (binding safety contract) - Read-only tool spans execute TWICE (double execution is what separates nondeterminism from drift/world-state). - Side-effecting tools NEVER execute — not once, not as a NOOP. A side-effecting span is served only from a recorded result with the identical canonical (tool, arguments) fingerprint in the stub registry built from the submitted run's own recording. A miss fails closed: verdict UNREPLAYABLE, zero live calls. - If the recording carries an env_digest, it is recomputed over span.env BEFORE any execution. A mismatch is refused as tampering — no drift verdict is ever attributed against an unverified baseline. - The span fingerprint is a replay/stub/attribution key only. It is not a general JSON-document signing or equivalence service and must never be relied on as a document signature. ## How replay executes in this hosted service The service never executes customer code and never calls a live model on your behalf. Your harness performs the executions and supplies the results; the service performs the fork, the tamper check, fingerprint comparison, env diffing, stub serving, and attribution: - Tool span arguments: {"span": } or {"spans": [], "span_id": "..."}, plus optional "live_env" (your current env dict), "live_outputs" (the two live re-execution outputs, in order) or "live_output" (one output, used for both executions). Without live outputs, the recorded output is used for both executions — that verifies determinism of the recording only. - Model span arguments: the same span selection, plus optional "live_tool_call" (the second model's tool_call for the recorded messages/tools_schema). Without it, the recorded tool_call is used, which verifies determinism of the recording only. - Side-effecting spans ignore live outputs entirely: stub-served or fail-closed. ## Prices — NO free tier, NO trial Tool-span replay $0.02 per replay (20000 atomic USDC). Model-decision replay $0.05 per replay (50000 atomic USDC). Pay per replay via x402 (scheme exact, Base mainnet USDC, payTo 0xAc2E243a075fEe442e4c6864DcF880eb4e3A3862). Metered from the first call. There is no free tier, no trial grant, and no subscription. An unpaid tools/call returns HTTP 402 with the x402 challenge; a payment must VERIFY (EIP-3009 signature, amount, payTo, validity window, unused nonce) — a header alone is never proof, and a spent nonce is rejected as a replay. ## Accounts and tokens POST /register {account_name, payer_wallet} returns {account_id, token}. The token is shown ONCE; only its SHA-256 hash is stored. The token scopes account-bound routes only (GET /history — your own replays) and is never taken from a request body field as identity. POST /tokens/revoke {token} revokes a token under your own account only. Payment is the credential for replay calls themselves; presenting your token with a paid call files the verdict in your history. ## Limits (stated plainly) - Span level only. No instruction/thread/snapshot recording. No cross-platform or cross-runtime comparison mode. - Accuracy is claimed only for the seeded lab set: 24/24 attribution vs 0.167 for the full-re-run baseline (LABREPORT-008, 37/37 lab tests). Real-trace sampling has not been done; no accuracy beyond the seeded set is claimed. - Model-decision replay: the $0.05 covers fork + comparison + attribution. The model call itself is yours (one call of the span's own size); live-model token cost across span sizes is unmeasured and not claimed. - Recorder/enricher: this service does not record or enrich your traces. Traces recorded without tool_version / tool_schema_hash / side_effecting enrichment receive reduced verdicts labeled drift-unavailable — drift is never guessed. - Transport bound: request bodies over 2 MB are refused (HTTP 413). A single span whose canonical size exceeds 1 MB is UNREPLAYABLE. - Lost-token recovery is a manual support@ step. ## Routes GET / (descriptor) · GET /docs (this text) · GET /openapi.json · GET /llms.txt · GET /.well-known/x402 · GET /health (all public, no auth) POST /register · POST /mcp (MCP JSON-RPC; tools/call replay_span is the paid route) · GET /history (Bearer token) · POST /tokens/revoke (Bearer token)