# Workflow Exec Payload Continuation

> Canonical path: `specs/daemon/workflow-exec-payload-reads.md`
> Related Workflow contract: [`specs/workflow/agentteam-workflow-platform.md`](../workflow/agentteam-workflow-platform.md)

Agent-facing Workflow Exec reads must preserve semantic payloads without asking
Desktop's generic result budget to recover a cut JSON value. Plan draft source,
exact version source/layout, Run input/output, Run log details, and authorized
callback Step input/output-contract/WorkItems-contract reads use the following
contract:

- default and compact responses carry convenient bounded values plus an opaque
  continuation reference when a value is oversized;
- explicit section reads accept only bounded selectors and a bounded page size;
  optional JSON-pointer narrowing happens before paging;
- each continuation cursor binds the authenticated workspace and the relevant
  Plan/version, Run/event, or Run/Step identity. Authorization is repeated for
  every page;
- each cursor also binds the authoritative immutable content version/digest.
  Plan draft reads use the draft revision plus source digest; live Run and
  callback reads use the current immutable payload digest. If the snapshot
  changes between pages, the read returns a stable conflict diagnostic and no
  payload bytes; clients restart from an empty cursor;
- a page contains an exact text/JSON slice and an optional `nextCursor`.
  Consumers concatenate slices until `nextCursor` is absent, then parse JSON;
- callback reads use the same frozen responder authorization and waiting-state
  capability checks as the ordinary Step `get` operation;
- sensitive operational error JSON is not made recoverable through a new
  continuation path.

The Workflow platform spec is the source of the public action names and section
values. The generic MCP result-budget policy remains a fallback boundary and is
owned independently; this contract does not change that policy.

## Continuation classes

The two storage paths intentionally implement one read contract with different
backends, not one interchangeable capability:

- **Live payloads** (`internal/workflow/payload`) are already loaded only after
the owning Plan/Run/Step authorization. Their opaque cursor carries the
resource IDs, canonical JSON-pointer path, offset, and content digest/version;
every page repeats authorization and digest validation, so a MAC secret is not
needed for this short-lived re-read path.
- **Durable Run artifacts** (`internal/workflow/runartifact`) may be retained
across retries and read through a separate artifact endpoint. Their cursor is
only `{offset, mac}`; the complete artifact reference, canonical path, limit,
and digest/version are MAC input and are rechecked against the locked artifact
row on every page. This prevents a cursor copied between artifact references
from becoming a read capability.

Both paths use the same canonical JSON-pointer path meaning, bounded page
semantics, and `nextCursor` concatenation rule. The live payload ceiling stays
at 32 KiB to fit ordinary Exec envelopes; the durable artifact reader permits a
64 KiB default and 256 KiB maximum because it has a dedicated blob endpoint.
Those are backend transport budgets, not different continuation semantics. The
different authentication mechanisms are therefore an explicit trust-boundary
distinction, not accidental contract drift.
