Repository navigation
Open
Description
Feature Area
Backend API / Server
Problem Statement
Statewave's audit story works over the HTTP API and not over MCP, which is how most people first use it.
In statewave-connectors, packages/mcp-server/src/client.ts:
getContext()sends onlysubject_id,taskandmax_tokens. It never sendsemit_receipt, and the server default ison_request, so no receipt is written for a call made through the MCP tool.RawContextBundledeclares neitherreceipt_idnorreceipt_emitted, so both fields are discarded at parse time even when a receipt was written (for example under tenant configreceipts: always).RawMemorydoes not declaresource_episode_ids, andtoMemorySearchResult()keeps onlyid,subject,kind,textandscore. Provenance never reaches the agent.toMemorySearchResult()is shared withsearchMemories(), sostatewave_search_memoriesdrops provenance the same way.
Observed: after recording a demo through Claude Code, GET /v1/receipts?subject_id=… held exactly one receipt, written by a manual curl call — none from the agent's statewave_get_context calls.
The server side is complete: /v1/context accepts emit_receipt and returns receipt_id plus receipt_emitted.
Proposed Solution
- Add an optional
emit_receiptboolean to thestatewave_get_contextinput schema and pass it through. The tool's schema setsadditionalProperties: false, so it has to be declared, not only forwarded. - Widen
RawContextBundlewithreceipt_idandreceipt_emitted, and return both in the tool result. Both are needed: withoutreceipt_emitted, an agent cannot tell "no receipt was requested" from "a receipt was requested and emission failed". - Add
source_episode_idstoRawMemoryand carry it throughtoMemorySearchResult(), so bothstatewave_get_contextandstatewave_search_memoriesreturn provenance per memory. - Keep the default off. Tenants that want a receipt for every call set
receipts: always; this change makes that setting visible to the agent. Revisit the default once receipt erasure ([Bug]: Receipts keep the subject's task text after subject deletion and after retention expiry #423, [Feature]: Record key destruction as its own receipt, and restrict who can read a subject key #425) has shipped — until then, a receipt keeps the caller's task text and cannot be erased. - The types to widen (
MemorySearchResult,ContextBundle,RawContextBundle,RawMemory) are all declared insidepackages/mcp-server/src/client.ts, so the change stays inside that package.
Checked against statewave-connectors@a120673 (mcp-server 0.4.8) and statewave main.
API Design (if applicable)
Alternatives Considered
- Tenant config
receipts: alwaysalone: makes the receipt exist, but the agent still never sees its id, so nothing can cite it. - Defaulting
emit_receiptto true in the MCP server: produces an audit trail nobody asked for, and writes the caller's task text into records that currently cannot be erased.
Priority to You
High - Major improvement needed
Additional Context
No response
Contribution
- I would be interested in contributing this feature
- I would be interested in testing this feature
Metadata
Metadata
Assignees
Labels
No labels
Activity