feat(brain): stamp server-owned write provenance; surface it in brain_query
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>
This commit is contained in:
@@ -95,6 +95,18 @@ func (f *frontmatter) set(key, value string) {
|
||||
f.lines = append(f.lines, fmLine{key: key, value: value})
|
||||
}
|
||||
|
||||
// del removes every top-level line for key. Continuation lines of a
|
||||
// multi-line value are not tracked per key, so del is only for scalars.
|
||||
func (f *frontmatter) del(key string) {
|
||||
kept := f.lines[:0]
|
||||
for _, l := range f.lines {
|
||||
if l.key != key {
|
||||
kept = append(kept, l)
|
||||
}
|
||||
}
|
||||
f.lines = kept
|
||||
}
|
||||
|
||||
// render serialises the frontmatter back into a `---`-fenced block. An
|
||||
// empty frontmatter renders to the empty string so bodies without a
|
||||
// header stay header-less.
|
||||
|
||||
Reference in New Issue
Block a user