Operator-invoked, operator-gated loop:
- --gather reads published bodies directly (parsePublishedRecord, filtered by
published_date > last_run) + current profile, for the session to extract candidates.
- --propose validates candidates (shape + single-line key/value, else non-zero/no-write),
proposeDiff, writes brain/pending-diff.{json,md}; never touches profile.md.
- --apply --diff <json> --confirm is the ONLY path that writes profile.md (refuses
without --confirm), then records brain/consolidation-state.json last_run.
init/ingest/published preserved. 7 subprocess CLI tests (SC5). brain 75→82, tsc clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4