What it is. A local clone of Anthropic's "Dreams" beta (Managed Agents API), built on free Gemini instead of paid Opus/Sonnet, against Brian's local Markdown memory store instead of Anthropic's hosted memory_store.
Why we have it.
MEMORY.mdaccumulates duplicates, retired-rule echoes (e.g., L4 enforcement), and contradictions across thematic files. A weekly reflection job catches that drift before it bloats the always-loaded CORE.Authority. Designed via 2-round round-table (Codex + Gemini + Hermes, 2026-05-09). Final plan in this session's history.
| Guarantee | Mechanism |
|---|---|
Live MEMORY.md is never modified by the job |
Drafts go to drafts/<TS>/MEMORY.md.draft. The only writer to live memory is adopt.sh. |
| Inputs are immutable per run | Every run snapshots inputs to snapshot/<TS>/ before inference. |
| Zero paid model calls | Job uses free Gemini API (Pro→Flash, multi-key rotation). No paid keys involved. |
| Failure leaves live memory pristine | set -euo pipefail + atomic draft writes. Failed runs alert TG LOGS. |
/opt/agent/brian_dreams/
├─ run.sh # core job: snapshot → call Gemini → write drafts
├─ trigger.sh # cron entry: runs run.sh, posts TG COMMS summary
├─ adopt.sh # operator helper: backup live + atomic-swap draft
├─ call_gemini.py # model+key rotation (Pro → Flash, 11 keys)
├─ prompt.md # the curator system prompt
├─ snapshot/<TS>/ # immutable inputs (Markdown corpus + _full_prompt.txt)
├─ drafts/<TS>/ # outputs:
│ ├─ MEMORY.md.draft
│ ├─ CHANGELOG.md
│ ├─ CONTRADICTIONS.md
│ ├─ diff_vs_live.txt
│ ├─ _raw_gemini_output.txt
│ ├─ _raw_gemini_output.txt.meta.json # which model+key+latency won
│ └─ _request.json
└─ logs/<TS>.log
0 3 * * 0 (Sunday 03:00 UTC = 06:00 Beirut, low-traffic)./opt/agent/brian_dreams/trigger.sh (cron).Memory dream ready: <TS> with adopt/discard one-liners.brian-dreams: run failed (errors never go to COMMS — memory rule)./opt/agent/brian_dreams/run.sh # default scope (Markdown corpus only)
/opt/agent/brian_dreams/run.sh --include-archive # also include _archive/feedback_*.md
/opt/agent/brian_dreams/run.sh --include-transcripts # Phase-2: also fold in CC session JSONLs
TS=20260509-1234
diff -u /root/.claude/projects/-/memory/MEMORY.md /opt/agent/brian_dreams/drafts/$TS/MEMORY.md.draft
less /opt/agent/brian_dreams/drafts/$TS/CHANGELOG.md
less /opt/agent/brian_dreams/drafts/$TS/CONTRADICTIONS.md
cat /opt/agent/brian_dreams/drafts/$TS/_raw_gemini_output.txt.meta.json # which model/key won
/opt/agent/brian_dreams/adopt.sh <TS>
# Backs up live MEMORY.md → MEMORY.md.pre-dream-<TS>, then atomic-copies the draft in.
# Rollback: cp /root/.claude/projects/-/memory/MEMORY.md.pre-dream-<TS> \
# /root/.claude/projects/-/memory/MEMORY.md
rm -rf /opt/agent/brian_dreams/{drafts,snapshot}/<TS>
call_gemini.py tries in order:
1. gemini-2.5-pro against each key in: GEMINI_FREE_API_KEY, GEMINI_FREE_API_KEY_2, GEMINI_API_KEY, GOOGLE_AI_STUDIO_KEY{,_2,_3,_4}, GEMINI_KEY_{1..4}.
2. gemini-2.5-flash against the same key list.
3. If all fail, exit 2 and write the attempt log to _raw_gemini_output.txt.
Round-table consensus: Pro produces sharper curation (more aggressive dedupe). Flash is the safety net when Pro's daily free quota is exhausted, but tends to be conservative — adds pointers without cutting bloat.
Per-attempt outcome is logged in <draft>/_raw_gemini_output.txt.meta.json:
{
"ok": true,
"model": "gemini-2.5-pro",
"key_name": "GEMINI_FREE_API_KEY_2",
"elapsed_s": 41.2,
"attempts": [...]
}
Single source: /opt/agent/brian_dreams/prompt.md. Highlights:
CONTRADICTIONS.md for human review, never silently merged.[src: theme_comms.md]). Uncited additions = hallucination, validator rejects.=== … === blocks: MEMORY.md.draft, CHANGELOG.md, CONTRADICTIONS.md. Anything else is parser-rejected.Decided by round-table; tracked here so it doesn't get lost:
bloom_recent / bloom_sessions as additional signal.*.jsonl transcripts (last N=50) to the corpus for behavioral pattern detection.theme_*.md files, not just CORE.adopt.sh with Ed25519-signed approval marker (matches the existing evidence-gate pattern).| Failure | Symptom | Guard |
|---|---|---|
| All Gemini keys exhausted | run.sh exits 2 with "all attempts failed" | TG LOGS alert; live memory untouched. Wait for daily reset. |
| Model hallucinates a new rule | MEMORY.md.draft contains a line with no [src: ...] citation |
Mandatory diff review before adoption (manual only). |
| Critical nuance over-merged | CHANGELOG.md shows a MODIFY that loses substance |
Diff review + the Full: [theme_X.md] pointer pattern preserves depth elsewhere. |
| Curator drops a hard rule | A 🚨 line missing from draft | CHANGELOG.md REMOVE entries flag this; manual eyeball. Phase 2 will add automated assertion that all 🚨 lines from input survive into draft. |
| Disk fills with old drafts | /opt/agent/brian_dreams/{drafts,snapshot}/* accumulates |
Phase 2: retention policy (keep last 8 runs). For now, eyeball with du -sh /opt/agent/brian_dreams/. |
managed-agents-2026-04-01 + dreaming-2026-04-21). Their docs: https://platform.claude.com/docs/en/managed-agents/dreams./tmp/r{1,2}_{codex,gemini,hermes}.md (ephemeral; the converged plan lives here).20260509-1632 using Flash (Pro was rate-limited). Output was over-conservative — Flash added pointers but didn't shrink. Discarded. Real test will be the first cron run when Pro's quota is fresh.