brain_write was an ungated, durable prompt-injection path: a session that
just read an untrusted page could write an entry every later session
retrieves as trusted guidance (OWASP MCP06). Decision (#145): tag
provenance rather than stage writes.
Every write and update stamps origin (static | jwt | unknown) and
written_by (the authenticated principal) into frontmatter. Server-owned:
origin/written_by in caller content or an update fragment are discarded,
so a caller cannot claim a more trusted origin. No principal stamps
origin: unknown, never silence. brain_update re-stamps to the last
writer. capture (the claude.ai connector door) stamps too, via a new
server-derived CaptureContext.AuthPath set by both capture doors after
decode. REST POST /write carries no principal and stamps unknown.
brain_query results carry origin/written_by when the note has them;
older notes omit them rather than fabricate. brain_get already returns
frontmatter.
Refs #145
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
brain_query and brain_read left no record of who read what; only capture
and governance edits reached the audit sink (OWASP MCP08).
One slog record per call: tool, principal, origin (static/jwt/unknown),
wing/hall when given, outcome, duration. Content is reduced to
content_bytes so the audit line never copies brain content.
Refs #144
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>