For compliance reviewers: Synapse never writes from MCP without a human-accepted proposal (BR-12.3). Every accept, reject and prune appends one JSON line to
.synapse/audit.ndjson(ADR-013) before the workspace mutation. Accepted entities also carry per-file provenance frontmatter (x-ai-*, ADR-012). The trail and the stamps are independent and you can read either one without running Synapse.
1. The two layers
Synapse’s audit story has two layers, each answering a different question:
| Layer | File | Question it answers |
|---|---|---|
| Audit trail | .synapse/audit.ndjson (+ audit-archive/<yyyy-mm>.ndjson after rotation) | Did this decision happen, and when? |
| Provenance frontmatter | x-ai-* fields on the entity’s markdown (PROVENANCE.md) | Is this file AI-authored, and from which decision? |
The trail is the regulator’s receipt. The frontmatter is the file’s self-description.
See also
PROVABILITY.md: the audit trail this document describes is one of the integrity classessyn verifyturns into a signed, reproducible proof. Where this page answers “can I read what happened?”, that one answers “can I prove the memory wasn’t silently corrupted?”: including the honest tamper-evident-not-tamper-proof ceiling.
2. The audit trail
Every decision the pending queue makes: accept, reject, prune, appends one JSON line:
{
"id": 7,
"kind": "capture_fact",
"decision": "accepted",
"proposed_at": "2026-05-25T15:00:00Z",
"decided_at": "2026-05-25T15:30:00Z",
"source": "mcp:capture_fact",
"reason": "user-supplied justification",
"payload_sha256": "sha256:f8e2c1…"
}
idmatchessyn pending showand survives the row’s deletion.decisionisaccepted | rejected | pruned.payload_sha256ties the trail entry to the original proposal payload. The payload itself lives on the queue row until the user prunes it: the hash forever links the two.
Read the trail
syn audit list # live tail (last 100, newest first)
syn audit list --all # include archive months
syn audit list --decision accepted # filter by decision
syn audit list --source mcp: # filter by source prefix
syn audit show 7 # one entry
syn audit list --format json | jq # the canonical interchange
For a human-friendly replay of one decision against the current workspace state:
syn audit replay 7 # surface payload + context snapshot
# + current entity state diff
In v0.3 syn audit replay does not re-run the original prompt
against a model: it surfaces enough to spot drift visually. The
v0.4 follow-up will optionally route through the configured MCP
client to re-run the prompt and diff the output.
Retention and pruning
Default retention is 90 days. After that, on the next append,
rotation moves stale entries into
.synapse/audit-archive/<yyyy-mm>.ndjson and rewrites the live tail.
The archive is never auto-deleted.
syn audit prune --before 2025-01 # remove archive months only
# live tail untouched
Tune retention in ~/.config/synapse/config.toml (or the workspace
config):
[audit]
retention_days = 90 # default; set to a smaller number to roll faster
What the trail never does
- It does not auto-delete anything.
syn audit pruneis the only path to physical removal, and it only touches the archive. - It does not drop unparseable lines on rotation, a corrupted line stays as a forensic artifact, not as a silent deletion.
- It does not lie. If the audit append fails after a successful
workspace mutation, the queue row stays
pendingso the reviewer can see “this needs to retry”; the trail is never written past what actually happened. See ADR-013 for the ordering rationale.
3. The propose / sanction loop
MCP write tool pending queue workspace
───────────────── ─────────────── ─────────
capture_fact ─► enqueue (id=N)
link_entity ◄── syn pending list
update_status ◄── syn pending show N
add_workspace_topic ◄── syn pending accept N
add_workspace_tag apply ────────────► Workspace::tx
audit-append (accepted, id=N)
mark accepted
This is BR-12.3 in one paragraph: MCP never writes directly.
Every write tool returns {pending_id, accept_command, reject_command, kind, summary} and the resulting entity lands on disk only when the
human runs syn pending accept.
4. EU AI Act Article 50 mapping
Article 50 enforcement begins 2026-08-02. Mapping the obligations to Synapse:
| Obligation | Synapse mechanism |
|---|---|
| Machine-readable provenance on AI-authored content | x-ai-* frontmatter (PROVENANCE.md, ADR-012) |
| Decision trace (what informed the action) | pending.context_snapshot JSON + payload_sha256 audit entry |
| Pre-action approval (calibrated autonomy) | The pending queue (BR-12.3) |
| Reproducibility | syn audit replay <id> against context_snapshot |
| Tamper-evident record | .synapse/audit.ndjson append-only + rotation |
The inline = false config flag is the escape hatch for users who
need clean entity files but still want the regulatory receipt, the
audit trail keeps the same metadata regardless.
5. References
- BUSINESS_RULES.md §12: BR-12.3 through BR-12.5, the normative rules this doc operationalises.
- ADR-012: frontmatter stamps.
- ADR-013: audit.ndjson format and rotation.
- ADR-014: portable identity bundle (separate but related: provenance + identity are the two human-owned signatures Synapse ships).
- MCP.md: the MCP write tools and the response shape every accept-command piggybacks on.
- PROVENANCE.md: companion document focused on the per-file frontmatter stamps.