- B1: search.extractProvenance locates the frontmatter with
frontmatter.Split (fence at column 0), so an indented "---" inside a
block scalar no longer hides provenance from brain_query.
- B2: brain_edit refuses to edit without a snapshot, and if the stamp
cannot be verified restores the note and reports failure; a failed
restore is reported as exactly that, never as "rolled back".
- B3: internal/provenance gets direct tests for the whole-document
backstop (a stamp that cannot read back is refused), standalone group
decoding, duplicates, lone CR, tab continuations and unclosable
fences. Removing verify or the restore now fails the suite.
- Principals YAML would read as non-strings (true, 123, null, ~) are
quoted instead of refused. An unclosable fence ("---x") is refused
rather than demoted into the body. writeHallNote creates the hall
directory only after the note passes, so a refused write leaves
nothing behind (brain#21).
- MCP brain_ingest (stub LLM) asserted to stamp the caller.
Refs #145#144
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Round 2 of the PR #147 review forged origin: static for yaml.v3 with an
alias key plus a "..." document-end line: per-line judgement cannot see
context-dependent YAML. It also found REST ingest writing pages with no
provenance (stampPages lived only in the MCP server).
- New package internal/provenance. Apply keeps only top-level groups
`key: value` with a bare-identifier key whose group decodes on its own
to exactly that key, drops reserved and duplicate keys and everything
else (aliases, anchors as keys, document markers, complex/merge keys,
flow maps, tags, quoted keys), appends the stamp, then decodes the
whole result with yaml.v3 and refuses the write unless it reads back
exactly the stamp. api.StampProvenance wraps it and now returns an
error, which every caller propagates.
- The ingest pipeline stamps every page it writes or merges, from
provenance.FromContext(ctx); MCP attaches the caller's stamp, REST and
the watcher stamp unknown. RunRaw takes a ctx.
- brain_edit snapshots the note and rolls the edit back if the stamp
cannot be verified.
Tests: R1/R2 payloads join the write/update variant table, plus
brain_edit with the alias payload; REST /ingest-raw (title newline
checked with the line-oriented reader) and REST /ingest (stub LLM) stamp
unknown. Two existing byte-exact tests updated for the stamp line.
Refs #145#144
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>