Turn Context and Isolation
Explains how each agent turn is trust-isolated — the delegated JWT scope the agent receives, the call-back architecture where all tool calls route through markdocket-api, and why the agent worker holds no direct database access or worker API keys.
The MarkDocket agent is a stateless, trust-isolated microservice. Every agent turn operates within a narrow, user-scoped permission boundary enforced by delegated credentials, a durable turn state machine, and an architecture that routes all data access back through markdocket-api rather than allowing direct connections to any data store or sibling service.
How the Agent Receives Its Turn Credentials
When you start an agent turn, markdocket-api acts as the trust broker:
- Your session (cookie, API key, or OAuth token) is authenticated by
markdocket-api. markdocket-apimints a delegated JWT scoped to your user identity for that turn and forwards it to the agent worker alongside the turn request.- The agent worker uses this delegated token — carried as
X-Delegated-Token— for every tool call it makes during that turn.
The agent worker never sees your original session credential. It receives only the delegated token, whose scope is bounded to what markdocket-api determines you are authorized to do.
Automation agent nodes follow the same pattern
Tool Calls Always Route Back Through the API
The agent worker holds no direct connections to:
- The Neon Postgres database
- The USPTO worker
- The brand-intel worker
- Stripe or any billing system
- Any other sibling service
Every tool in the agent's registry calls back to markdocket-api using the delegated JWT. markdocket-api then re-dispatches the request to the appropriate worker or data source, enforcing its own authorization and metering checks on each call.
This means the agent's blast radius is structurally bounded: compromising the agent worker process exposes only what the current delegated token permits — not worker API keys, database credentials, or any other service secrets.
Your browser or client
│
▼
markdocket-api ← authenticates you, mints delegated JWT
│
│ X-Delegated-Token
▼
markdocket-agent ← runs the LLM turn loop
│
│ tool call with X-Delegated-Token
▼
markdocket-api ← validates token, re-dispatches to workers
│
▼
USPTO worker / brand-intel worker / Neon DB / ...The Turn State Machine
Every agent interaction is tracked as a durable turn in the database, progressing through the following states:
| State | Meaning |
|---|---|
authorizing | Billing reservation is being created |
authorized | Reservation confirmed; file uploads may begin |
uploading | Attached files are being committed to the turn |
running | The LLM loop is active |
completed | Turn finished successfully |
denied | Authorization or billing reservation failed |
failed | An error terminated the turn |
expired | The turn timed out before completion |
cancelled | The turn was explicitly cancelled |
State transitions use compare-and-swap (CAS) operations, so no two concurrent processes can advance the same turn to conflicting states. A background sweep releases any billing reservation and cleans up orphaned files for turns that reach expired without completing.
Billing Is Pre-Authorized Before Any Work Starts
The transition from authorizing to authorized is atomic with the creation of a billing reservation. No file upload or message commit is permitted until this reservation exists. This means:
- The agent loop cannot start without confirmed billing authorization.
- If authorization fails, the turn moves to
deniedimmediately and no LLM call is made.
File Uploads Within a Turn
Files attached to an agent turn are scoped to that turn and validated against the active billing reservation before being committed. Upload identifiers are derived deterministically from the turn identity and an idempotency key, so re-submitting the same file under the same key produces the same result without a redundant database check.
All attachments are stored in Vercel Blob and referenced from the turn record — the agent worker fetches image URLs from Blob for multimodal processing but does not write to any persistent store directly.
Why the Agent Has No Direct Database Access
The isolation is intentional and architectural, not a configuration choice:
markdocket-apiis the sole writer to the Neon Postgres database across the entire platform. No other service — including the agent worker — holds database credentials.- All agent actions that produce persistent side effects (saving messages, updating portfolios, filing submissions) go through
markdocket-apiendpoints, which enforce authorization, idempotency, and audit logging. - Every agent action is recorded in the
markdocket-apidatabase (agent sessions, messages, and attachments), giving you a complete audit trail that the agent worker itself cannot alter.
Billing Events and the Agent
The agent worker emits product usage events — it does not emit provider cost (COGS) events. Provider cost accounting for LLM calls is handled by markdocket-api for calls it makes directly, and by the BYOK worker for Bring Your Own Key automation runs. This separation prevents double-counting in multi-service billing scenarios.
If a tool call result indicates that a billing limit has been reached, the agent streams a billing_required SSE event back to the client. This event carries a structured BillingBlockEnvelope that the web app intercepts and surfaces as an upgrade or action prompt — the turn stops cleanly rather than failing with an unhandled error.
BYOK keys are not available to interactive agent chat
Trust Boundary Summary
| What the agent worker can do | What the agent worker cannot do |
|---|---|
Use the delegated JWT to call markdocket-api endpoints on your behalf | Hold or use worker API keys (USPTO, brand-intel, etc.) |
| Run tool calls within your authorized scope | Connect to the database directly |
| Stream SSE events (text, tool calls, billing blocks) back to the API proxy | Write to any persistent store without going through markdocket-api |
| Fetch image URLs from Blob for multimodal turns | Access your session credential or original auth token |
| Emit product usage billing events | Emit provider COGS billing events |
This architecture means that the agent's capabilities are always a strict subset of your own permissions, enforced at the API layer on every tool call — not just at the start of the turn.
Agent Tool System
Documents the MarkDocket agent tool registry: how it works, which tools are available in agent chat versus the public CLI/MCP/API surface, how the agent calls back to the API with delegated tokens, and how billing blocks flow through tool results.
System Prompt and Context
Documents the context the MarkDocket agent receives at the start of each turn, including portfolio state, user preferences, session history, and how the agent's turn lifecycle shapes what information is available.