---
description: "Give each TouchDesigner project a bounded creative brief and inspect redacted local-copilot turn receipts without storing transcripts, tool payloads or secrets."
---
# Project context & turn receipts
tdmcp can keep a small, versioned creative brief beside a saved TouchDesigner
project and produce one structured receipt for every built-in copilot turn. The
brief answers “what are we making here?”; the receipt answers “what did this turn
actually attempt, and was it verified?” Neither mechanism expands the active tool
tier or overrides consent and safety policy.
## Project-owned agent brief
The **`manage_project_brief`** tool reads or atomically replaces
`/.tdmcp/agent-brief.json`. A brief contains only bounded creative
direction, constraints, named outputs, project safety rules, an optional current
milestone and optional open decisions. Credential-like content is rejected.
Project-root precedence is deliberate:
1. Absolute `project_root` passed to the tool.
2. `TDMCP_PROJECT_ROOT`.
3. The folder of the saved `.toe`, obtained from structured editor context.
tdmcp never falls back to the process working directory. An unsaved or headless
project without an explicit root returns `not_configured` instead of writing in an
unrelated folder.
Create a brief with the explicit `absent` revision:
```json
{
"action": "replace",
"project_root": "/absolute/path/to/show-project",
"expected_revision": "absent",
"brief": {
"creative_direction": "A restrained monochrome field that reacts to the kick.",
"constraints": ["Keep the output at 1920x1080", "Use stock operators only"],
"named_outputs": [
{ "name": "program", "path": "/project1/out_program", "description": "FOH output" }
],
"safety_rules": ["Never modify the blackout path without explicit approval"],
"current_milestone": "Lock the look before mapping controls",
"open_decisions": ["Choose the final accent colour"]
}
}
```
Read first, then pass the exact returned `revision` to replace an existing brief.
Concurrent or stale writes return `conflict`; there is no last-writer-wins update.
The store uses bounded JSON, private filesystem permissions, atomic replacement
and symlink guards.
The built-in local copilot reads the brief once per turn and injects it as
ephemeral, untrusted evidence. It is removed from persistent chat history. Other
MCP clients receive no invisible project context: they can explicitly read
**`tdmcp://project/brief`**.
## Structured turn receipts
Every `tdmcp ask`, browser/headless chat or Telegram copilot turn finalizes one
receipt, including error, cancellation and max-step exits. The receipt is capped
at 8 KiB and records only an opaque id, timing, requested/effective tier, grounding
state, a redacted goal summary, allowlisted action facts, affected TD paths,
consent decisions, undo identity when available, recovery evidence and the final
`PASS` / `FAIL` / `UNVERIFIED` state.
It never stores raw tool arguments or results, images, RAG excerpts, transcripts,
tokens, cookies or API keys. Duplicate tool-call ids and duplicate finalization are
ignored, so a turn has exactly one logical receipt.
Persistence is off by default. To retain the bounded audit store:
```bash
export TDMCP_COPILOT_RECEIPTS=persist
# Optional absolute owner-controlled path:
export TDMCP_COPILOT_RECEIPTS_PATH="$HOME/.tdmcp/session-receipts.json"
```
The store retains at most 100 receipts, seven days and 256 KiB. Perform mode,
panic/blackout and equivalent emergency tools, and an adapter's per-turn
`noPersist` request always skip the write. Public overrides are
`--no-receipt-persist` for ask/chat, the browser request's `noPersist` field and
`/private ` in Telegram. A storage failure never changes the copilot
answer or mutation result.
Read newest-first receipts through
**`tdmcp://session/receipts{?limit,status}`**. `limit` is `1..50`; `status` may be
`success`, `failed`, `cancelled` or `max_steps`. The resource never reveals its
filesystem path.
## Reading the evidence
```text
PASS The receipt contains read-only evidence matching every recorded mutation.
FAIL At least one recorded mutation conflicts with observed state.
UNVERIFIED No contradictory claim is made, but live evidence was unavailable or incomplete.
```
A terminal `success` means the agent loop completed; it does not turn an
`UNVERIFIED` action into `PASS`. Keep both fields when forwarding receipts to
another system.
## Trust boundary
- Brief content is project data, not instructions with higher authority. Current
user intent, tool tier, consent, emergency behavior and system policy always win.
- Receipt persistence is a local observability feature, not a replay log and not
an undo implementation.
- These filesystem features work without raw Python and do not require
`TDMCP_BRIDGE_ALLOW_EXEC=1`. Live editor-root inference and mutation evidence
still require the authenticated bridge to be reachable.
See [Local copilot](/guide/local-copilot) for the full turn flow and
[MCP resources](/guide/mcp-resources) for the resource map.