v0.23.0 feat: gbrain dream synthesizes conversations into brain pages (v0.23.0)#462
Merged
v0.23.0 feat: gbrain dream synthesizes conversations into brain pages (v0.23.0)#462
Conversation
Adds the v25 schema migration creating the dream_verdicts table (file_path, content_hash, worth_processing, reasons, judged_at; PRIMARY KEY (file_path, content_hash); RLS-enabled when running as a BYPASSRLS role). Distinct from raw_data (which is page-scoped) — transcripts being judged for synthesis aren't pages. The (file_path, content_hash) key means edited transcripts re-judge automatically. BrainEngine gains: - DreamVerdict + DreamVerdictInput types - getDreamVerdict(filePath, contentHash) → DreamVerdict | null - putDreamVerdict(filePath, contentHash, verdict) — ON CONFLICT upsert Both engines implement (postgres-engine.ts, pglite-engine.ts). This commit alone is functionally inert — nothing reads/writes the table yet. The synthesize phase (later commit) is the consumer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds OperationContext.allowedSlugPrefixes — when set, put_page enforces slug membership in the allow-list instead of the legacy wiki/agents/<id>/... namespace. The trust signal is the SUBMITTER (PROTECTED_JOB_NAMES gates subagent submission so MCP can't reach this field), not the runtime ctx.remote flag — every subagent tool call has remote=true for auto-link safety, so basing trust on remote is incoherent. matchesSlugAllowList(slug, prefixes) helper supports glob suffix '/*' (recursive — wiki/originals/* matches ideas/foo/bar) and exact match for unsuffixed entries. put_page check shape: if (viaSubagent && allowedSlugPrefixes set) → allow-list check else if (viaSubagent) → existing namespace check (regression guard) else → no check (regular CLI) Auto-link is re-enabled for the trusted-workspace path so the cycle's extract phase doesn't have to recompute every edge after synthesize writes. Untrusted remote writes still skip auto-link as before. SubagentHandlerData.allowed_slug_prefixes is the wire field; the synthesize/patterns phases (later commit) populate it from a single source of truth in skills/_brain-filing-rules.json's dream_synthesize_paths.globs array. The model's tool schema description mirrors the allow-list so it writes correct slugs on the first try. IRON RULE security tests: - test/operations-allow-list.test.ts: allow-list ALLOW/REJECT, glob semantics, regression guard for the v0.15 namespace fallback when allow-list is unset, FAIL-CLOSED when subagentId is missing. - test/e2e/dream-allow-list-pglite.test.ts: end-to-end on PGLite, poisoned-transcript style write outside allow-list → REJECTED. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extends ALL_PHASES from 6 → 8: synthesize between sync and extract, patterns between extract and embed. Codex finding #7: patterns MUST run after extract because subagent put_page sets ctx.remote=true and skips auto-link/timeline by default — extract is the canonical edge materialization step. Without that ordering, patterns reads stale graph state. Final order: lint → backlinks → sync → synthesize → extract → patterns → embed → orphans CycleOpts gains: - yieldDuringPhase callback — generic in-phase keepalive for long waits (synthesize fan-out, patterns roll-up). Renews cycle-lock TTL + worker job lock. Mirrors yieldBetweenPhases shape. - synthInputFile / synthDate / synthFrom / synthTo — forwarded to runPhaseSynthesize for the CLI's --input/--date/--from/--to flags. CycleReport.totals additively grows (no schema_version bump): transcripts_processed, synth_pages_written, patterns_written. src/core/cycle/transcript-discovery.ts is a pure filesystem walk: - .txt files only, sorted by path for determinism - date-prefixed basename filter (--date / --from / --to) - min_chars filter (default 2000) - exclude_patterns auto-wraps bare words as \b<word>\b regex (Q-3), power users may pass full regex with anchors - compileExcludePatterns is exported for unit tests Phase implementations land in the next commit; this one only adds the dispatcher slots so commit-by-commit bisect doesn't crash on import-not-found. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Synthesize phase (src/core/cycle/synthesize.ts) reads conversation
transcripts from dream.synthesize.session_corpus_dir and writes
brain-native pages: reflections to wiki/personal/reflections/...,
originals to wiki/originals/ideas/..., timeline entries on existing
people pages.
Pipeline:
1. discoverTranscripts (filesystem walk + filters)
2. cooldown check via dream.synthesize.last_completion_ts config
(default 12h; bypassed by --input/--date/--from/--to)
3. cheap Haiku verdict per transcript, cached in dream_verdicts
table keyed by (file_path, content_hash) — backfill re-runs
skip already-judged transcripts at zero cost
4. fan-out: one Sonnet subagent per worth-processing transcript
dispatched with allowed_slug_prefixes (read from
skills/_brain-filing-rules.json's dream_synthesize_paths.globs)
and idempotency_key dream:synth:<file_path>:<content_hash>
5. wait via waitForCompletion; yieldDuringPhase ticks every child
terminal so the cycle-lock TTL refreshes on long backfills
6. collect slugs from subagent_tool_executions for each child
(codex finding #2: NOT pages.updated_at, which would pick up
unrelated writes)
7. orchestrator dual-write — query each new page from DB,
reverse-render via serializeMarkdown, write file to brain_dir.
Subagent never gets fs-write access.
8. deterministic summary index page at dream-cycle-summaries/<date>
(codex finding #4: slug shape is regex-compatible — no
underscores, no .md extension)
9. write completion timestamp ONLY on successful runs
Patterns phase (src/core/cycle/patterns.ts) runs after extract so
the graph state is fresh. Single Sonnet subagent gathers reflections
within dream.patterns.lookback_days (default 30); names a pattern
only when ≥dream.patterns.min_evidence (default 3) reflections
support it. Same allow-list path as synthesize.
CLI flags on `gbrain dream` (src/commands/dream.ts):
--input <file> ad-hoc transcript synthesis (implies
--phase synthesize; bypasses cooldown)
--date YYYY-MM-DD restrict synthesize to one date
--from <d> --to <d> backfill range
--dry-run runs Haiku verdict (cached), skips Sonnet
synthesis. NOT zero LLM calls (codex #8).
Conflict detection: --input + --date/--from/--to exits 2.
ISO 8601 date format validated; range start > end exits 2.
Auto-commit / push deferred to v1.1 (codex finding #5). v1 writes
files to brain_dir; user or autopilot handles git.
Tests:
- test/cycle-patterns.test.ts: structural assertions on the patterns
phase (queue + waitForCompletion wired, allow-list threading,
subagent_tool_executions provenance, no raw_data dependency).
- test/dream-cli-flags.test.ts: argv parsing, conflict detection,
ISO date validation, --input implies --phase synthesize, dry-run
semantics doc string.
- test/e2e/dream-synthesize-pglite.test.ts: 8 cases on PGLite
in-memory exercising not_configured, empty corpus, no API key
skip path, dry-run, cooldown active vs --input bypass, and the
dream_verdicts cache hit path. Per-test rig isolation (each
test creates and tears down its own engine) avoids
cross-test PGLite WASM contention.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- skills/maintain/SKILL.md: synthesize + patterns phases documented with quality bar (Iron Law for synthesis), trust boundary, idempotency, cooldown semantics, CLI invocation patterns. New triggers added so "process today's session" / "synthesize my conversations" route here. - skills/RESOLVER.md: dream cycle triggers route to maintain. - skills/_brain-filing-rules.md: directory table for the five output types (reflections, originals, patterns, people enrichment, cycle summary) with slug shape per row; Iron Law repeated. - skills/migrations/v0.27.0.md: agent-readable migration narrative. Schema migration v25 runs automatically on `gbrain apply-migrations`; synthesize ships disabled by default — opt-in via dream.synthesize.session_corpus_dir + dream.synthesize.enabled. - CLAUDE.md: file inventory updated with new files (cycle/synthesize.ts, cycle/patterns.ts, cycle/transcript-discovery.ts), the 8-phase ordering, the trusted-workspace allow-list trust model, and the v25 schema migration line in the migrate.ts entry. - VERSION: 0.20.4 → 0.27.0 - CHANGELOG.md: v0.27.0 release-summary section per CLAUDE.md voice rules (numbers that matter table, what-this-means closer, "to take advantage of" block), followed by the itemized changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merges v0.21.0 (Code Cathedral II — call-graph edges, two-pass retrieval, parent-scope chunking) and v0.22.0 (source-aware search ranking) from master into the transcript-dream branch. Conflict resolutions: - VERSION: kept this branch's reserved 0.27.0 slot (master at 0.22.0; intermediate slots 0.22.1-0.26.0 are claimed by sibling branches). - CHANGELOG.md: kept v0.27.0 entry at top, then master's v0.22.0 + v0.21.0 entries below in version order. - src/core/migrate.ts: master added migrations v25-v29 (Cathedral II); this branch's dream_verdicts migration moved from v25 → v30 to slot cleanly after master's last migration. The dream_verdicts table DDL is unchanged. Only the migration version number changed. Tests pass: 66/66 dream tests, 91/91 regression- sensitive tests (parity, cli, brain-allowlist, migrate). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…outs Two new E2E test files on PGLite (no DATABASE_URL or API key required): - test/e2e/dream-patterns-pglite.test.ts (6 cases) — exercises runPhasePatterns skip paths against a real engine: disabled, default-enabled-but-insufficient-evidence, no-API-key, dry-run. Sibling of dream-synthesize-pglite.test.ts; same per-test rig pattern for engine isolation. - test/e2e/dream-cycle-eight-phase-pglite.test.ts (5 cases) — end-to-end runCycle with the v0.27 8-phase order. Asserts: ALL_PHASES is the documented 8 phases in the right sequence, the dry-run report's phases array preserves that order, CycleReport.totals carries the new transcripts_processed / synth_pages_written / patterns_written fields, --phase synthesize and --phase patterns each run only that phase, and synthInputFile is plumbed correctly through runCycle to runPhaseSynthesize. Bump per-test timeout to 30s on the two synthesize-cooldown E2E tests that create two PGLite engines back-to-back. Default Bun 5s budget is tight under sustained suite pressure (PGLite WASM init costs ~1-2s per engine on macOS); each test passes alone but flakes in the full E2E suite. The third arg `30_000` is Bun's standard test-timeout knob. Full E2E suite (test/e2e/) now: 86 pass / 0 fail / 258 skip. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- src/core/cycle/synthesize.ts + patterns.ts: PageType 'default' → 'note' (TS strict typecheck rejected 'default'; 'note' is a valid PageType for orchestrator-written summary index pages and reverse-render fallback). - src/core/pglite-engine.ts: re-import DreamVerdict + DreamVerdictInput types after the master merge dropped them from the import line. - test/e2e/dream-allow-list-pglite.test.ts: ToolCtx now requires remote: true literal; thread it through every put_page tool call. - test/e2e/dream-patterns-pglite.test.ts: PageType 'default' → 'note' in the seedReflections helper. - test/core/cycle.test.ts: bump expected hook-call count + phase count 6 → 8 to match v0.27 ALL_PHASES extension. - llms-full.txt: regenerate against the updated CHANGELOG + CLAUDE.md so the committed snapshot matches what the generator now produces. Full bun test suite: 2793 pass / 0 fail / 258 skip (3051 tests, 177 files). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
README: maintain skill row mentions synthesize/patterns; gbrain dream command-reference block describes the 8-phase pipeline and the new --input/--date/--from/--to flags. INSTALL_FOR_AGENTS: dream cycle bullet calls out v0.27 conversation synthesis + cross-session pattern detection. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Merges 5 master commits since last merge: v0.22.1 autopilot fix wave (#447), v0.22.2 minions worker reliability (#458), v0.22.4 frontmatter-guard (#448), sourceId in cycle sync phase (#475), and post-migration schema verification (#488). Conflict resolutions: - VERSION: kept this branch's reserved 0.27.0 slot (master at 0.22.6). - CHANGELOG.md: kept v0.27.0 entry at top, then master's v0.22.6 → v0.21.0 entries below in order. - CLAUDE.md: merged the v0.27 cycle bullet (8 phases, synthesize, patterns, transcript-discovery, dream CLI flags) with master's v0.22.1/v0.22.5 cycle additions (signal: AbortSignal, willRunExtractPhase, resolveSourceForDir). - src/core/cycle.ts: kept v0.27 yieldDuringPhase + synthInputFile/synthDate/synthFrom/synthTo CycleOpts fields AND added master's v0.22.1 signal: AbortSignal field. Both coexist. - llms-full.txt: regenerated against the merged tree. The dream_verdicts schema migration moved v25 → v30 in the prior merge. Master ended at v29 (cathedral_ii_code_edges_rls); v30 is uncontested. Tests pass post-merge: 105/105 dream + cycle tests across 9 files. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Master is at v0.22.5; v0.23.0 is the next natural slot for the dream-cycle synthesize + patterns release. Bulk rename across VERSION, package.json, CHANGELOG, migration file, source comments, skills, and llms.txt bundles. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-dream # Conflicts: # CHANGELOG.md # CLAUDE.md # VERSION # llms-full.txt # package.json
garrytan
added a commit
that referenced
this pull request
Apr 30, 2026
PR #506 claims v0.22.15, PR #521 claims v0.22.10, intermediate slots (.11/.12/.13/.14) are claimed by other open PRs. v0.22.16 is the next clean PATCH slot. v0.23.0 is claimed by PR #462 so MINOR isn't free. This release fits the 0.22.x train; v0.23.0 lands when #462 ships. Updates VERSION, package.json, CHANGELOG.md header, TODOS.md follow-up labels. Code is unchanged.
garrytan
added a commit
that referenced
this pull request
Apr 30, 2026
…arness (#522) * feat: hermeticity migration — every $GBRAIN_HOME write site honors the env override configDir() in src/core/config.ts already implemented $GBRAIN_HOME as a parent-dir override (returns <override>/.gbrain), but ~12 consumers built paths from os.homedir() directly and bypassed it. Critically, loadConfig/saveConfig themselves used a private getConfigDir() that ignored the env. Fixed. Migrated every write site to gbrainPath() — fail-improve, validator-lint, cycle lock, shell-audit, backpressure-audit, sync-failures, integrity logs, integrations heartbeat, init pglite path, migrate-engine manifest, import checkpoint, v0_13_1 rollback, v0_14_0 host-work. Read-side host-detection in init.ts (~/.claude / ~/.openclaw probes) intentionally NOT migrated; that's a v1.1 follow-up under a separate $GBRAIN_HOST_HOME override. Adds gbrainPath(...segments) sugar plus path validation: $GBRAIN_HOME must be absolute and contain no '..' segments (throws GbrainHomeInvalidError). test/gbrain-home-isolation.test.ts proves write-isolation across all migrated sites. test/migrations-v0_14_0.test.ts updated to use $GBRAIN_HOME instead of the old HOME-swap pattern. Closes part of the claw-test E2E harness preconditions (D13 + D21). * feat: gbrain friction {log,render,list,summary} — agent friction reporter Append-only JSONL writer at $GBRAIN_HOME/friction/<run-id>.jsonl. Schema is a flat extension of StructuredAgentError (D20), one envelope shape across both agent-emitted entries and harness-wrapped command failures. Run-id resolves from --run-id > $GBRAIN_FRICTION_RUN_ID > 'standalone'. Subcommands stay ≤30 LOC each; core lives in src/core/friction.ts (writer + reader + renderer + redactor). render --redact (default for md output) strips \$HOME / \$CWD to placeholders so reports paste safely in PRs/issues. Severity: confused | error | blocker | nit. Kind: friction | delight (D7) | phase-marker | interrupted. Readers tolerate malformed lines (skip + warn). 40 unit tests; this is the channel the claw-test harness writes to and that agents emit through during live-mode runs. * feat: gbrain claw-test — end-to-end fresh-install friction harness Two modes: scripted (CI gate, no agent) and --live (real agent subprocess). Phases: setup → install_brain (gbrain init --pglite) → import (--no-embed) → query → extract all --source fs → verify (gbrain doctor --json, asserts status==='ok' and progress.jsonl phase coverage). AgentRunner interface + registry — interface stays narrow (detect, invoke, optional postInstallHook). v1 ships only OpenClawRunner; the registry pattern lets v1.1 land hermes/codex as ~50-line additions without refactoring callers. OpenClaw invocation: 'openclaw agent --local --agent <name> --message <brief>' matching test/e2e/skills.test.ts (NOT --prompt-file, which doesn't exist). transcript-capture: spawns child with piped stdio, async-drains via fs.createWriteStream + 'drain' events so 256KB+ bursts don't stall the child (D17 backpressure). Writes <run>/transcript.jsonl with schema_version + ts + channel + byte_offset + bytes_b64. Friction entries' transcript_offset field references byte offsets here so render --transcripts can resolve back. progress-tail: parses gbrain's --progress-json events out of child stderr. Phase verification asserts each scenario.expected_phases entry (dotted names like import.files, extract.links_fs, doctor.db_checks) saw at least one event from the actual command — proves the COMMAND ran, not that the agent obeyed prompts. seed-pglite: ~50 LOC SQL replay primitive for the upgrade-from-v0.18 scenario. Existing migration helpers (test/e2e/helpers.ts) are Postgres-only; PGLite has no equivalent. seedPglite opens a fresh PGLite, executes each statement individually (errors name the failing one), then disconnects so gbrain init can take over and walk forward. 53 unit tests covering registry selection, runner detection, multi-byte UTF-8 chunk-boundary safety, PIPE buffer drain, scenario load+validate, progress event parsing, and SQL splitter. * feat: claw-test scenario fixtures + friction-protocol skills convention Two scenarios ship in v1 — fresh-install and upgrade-from-v0.18. Each is a self-contained directory: brain/ (markdown pages), BRIEF.md (live-mode prompt), expected.json (scripted-mode assertions), scenario.json (kind, expected_phases, optional from_version + seed paths). Schema is owned by src/core/claw-test/ scenarios.ts. upgrade-from-v0.18 ships scaffolded — seed/dump.sql is the v1.1 follow-up (needs a real v0.18-shape PGLite dump; seed/README.md documents the gen procedure). The harness gracefully no-ops the seed phase when dump.sql is absent. skills/_friction-protocol.md is a cross-cutting convention skill (like _brain-filing-rules.md). Tells agents when to call gbrain friction log and how to choose severity. Skills the claw-test exercises will gain a > Convention: callout pointing here in a v1.1 sweep. 13 unit tests for the scenario loader + 'shipped scenarios load cleanly' for both. * feat: register gbrain claw-test + gbrain friction; CLAUDE.md + llms sync Wires both commands into src/cli.ts CLI_ONLY allow-list and adds dispatch in handleCliOnly so neither command requires a brain engine connection. CLAUDE.md gains entries for src/commands/{friction,claw-test}.ts + src/core/claw-test/ + skills/_friction-protocol.md, and a Commands section listing all 8 new gbrain claw-test ... and gbrain friction ... invocations with the v0.23 marker. Documents the GBRAIN_HOME write-isolation contract and the v1 caveat (read-side host-fingerprint detection deferred to v1.1). llms.txt + llms-full.txt regenerated via 'bun run build:llms' so the committed generator-output gate passes. test/e2e/claw-test.test.ts is the scripted-mode E2E. Builds a tiny shim that delegates to 'bun run src/cli.ts' (NOT bun --compile, which doesn't bundle PGLite's runtime assets), points the harness at it via GBRAIN_BIN_OVERRIDE, runs --scenario fresh-install end-to-end. Asserts exit 0, zero error/blocker friction. Includes a deliberate-break test that proves the friction signal fires when a phase command rejects. test/claw-test-cli.test.ts covers shipped-scenario load + agent registry + OpenClawRunner detection (relative-path / .. / missing-bin guards) + the GBRAIN_FRICTION_RUN_ID env handoff between harness and friction CLI. Closes the v0.23 claw-test E2E feature. * chore: bump version and changelog (v0.24.0) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(tests): typecheck failures + spawnWithCapture timeout headroom in CI Three CI fixes after PR #522 landed: 1. test/agent-runner.test.ts:89 — UnavailableRunner.invoke() returns Promise<void> by default but the AgentRunner contract requires Promise<InvokeResult>. Annotate the throw-only invoke explicitly so tsc sees the contract is satisfied (the throw makes the body unreachable as far as the return type is concerned). 2. test/seed-pglite.test.ts — bun:test signature is test(name, fn, timeoutMs: number), not test(name, opts: {timeout}, fn). The {timeout: 30_000} object form was a guess that tsc on bun 1.3.13 rejects. Move the 30s cap to the trailing positional number arg on each PGLite-using test. 3. test/transcript-capture.test.ts — `spawnWithCapture > timeout fires SIGTERM/SIGKILL` blew the 10s outer cap on the GitHub runner. Two fixes: (a) use `exec sleep` so the child we spawn IS sleep — SIGTERM goes directly to it, no `/bin/sh` fork-vs-exec process-group ambiguity that could orphan the sleep and force the SIGKILL grace path. (b) bump outer cap to 30s for headroom even when the runner is slow and SIGKILL after the 5s grace is what actually ends the child. * chore: rebump to v0.22.16 (next free 0.22.x patch slot per queue) PR #506 claims v0.22.15, PR #521 claims v0.22.10, intermediate slots (.11/.12/.13/.14) are claimed by other open PRs. v0.22.16 is the next clean PATCH slot. v0.23.0 is claimed by PR #462 so MINOR isn't free. This release fits the 0.22.x train; v0.23.0 lands when #462 ships. Updates VERSION, package.json, CHANGELOG.md header, TODOS.md follow-up labels. Code is unchanged. --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…-dream # Conflicts: # CHANGELOG.md # CLAUDE.md # VERSION # llms-full.txt # package.json
The dry-run full-cycle test asserted 6 phases. v0.23 added synthesize and patterns, bringing the total to 8. The unit-side equivalent (test/core/cycle.test.ts) was already updated; this catches the E2E sibling that surfaced after the latest master merge. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extends
gbrain dreamfrom a 6-phase brain-maintenance cycle into an 8-phase one that consolidates yesterday's conversations into long-term memory. Two new phases run alongside the existing tidying:Synthesize reads conversation transcripts (OpenClaw session corpus, meeting transcripts, ad-hoc files via
--input) and writes brain-native pages: reflections atwiki/personal/reflections/YYYY-MM-DD-<topic>-<hash[:6]>, originals atwiki/originals/ideas/..., and timeline entries on existing people pages. Cheap Haiku verdicts cached in a newdream_verdictstable filter routine ops sessions before any Sonnet call. One subagent per worth-processing transcript, dispatched in parallel up to the rate-lease cap.Patterns runs after
extract(so the graph state is fresh) and surfaces recurring themes across recent reflections — when ≥3 reflections withinlookback_days(default 30) mention the same motif, a pattern page is written towiki/personal/patterns/<theme>citing every reflection that constitutes its evidence.Phase order:
lint → backlinks → sync → synthesize → extract → patterns → embed → orphans.Trust boundary — subagent put_page calls are bounded to a path allow-list sourced from
skills/_brain-filing-rules.json'sdream_synthesize_paths.globs. Even on prompt-injection success, writes are bounded to the allow-listed prefixes. The legacywiki/agents/<id>/...namespace check stays the default for non-cycle subagents (regression guard).Idempotency — slug includes content-hash suffix, so edited transcripts produce new files alongside the old (no silent overwrite). Idempotency key is
dream:synth:<file_path>:<content_hash>. Cooldown viadream.synthesize.last_completion_tsconfig key (default 12h) bounds spend at ~$1-2/day under autopilot.Provenance — orchestrator collects slugs from
subagent_tool_executions(NOTpages.updated_at— would pick up unrelated writes). Subagent never gets fs-write access; orchestrator does the dual-write at phase boundary.Auto-commit / push and daily token budget deferred to v1.1 per codex finding #5.
Commits (chronological):
feat: dream_verdicts schema + engine methods— schema migration v30 + engine interfacefeat: trusted-workspace allow-list for subagent put_page—allowedSlugPrefixescontext,matchesSlugAllowListhelper, IRON RULE security regression testsfeat: cycle scaffolding — 8-phase order + transcript discovery—ALL_PHASESextension,yieldDuringPhasehook, transcript discovery modulefeat: synthesize + patterns phases — gbrain dream actually dreams— both phase implementations, CLI flags, all unit + E2E testsdocs: dream cycle v0.23.0 — skills, CLAUDE.md, migration, changelog— release notes, migration narrative, skill updatesMerge origin/master into garrytan/transcript-dream— merge of v0.21.0 (Cathedral II) + v0.22.0 (source ranking)test: add patterns E2E + 8-phase cycle E2E + bump synth-cooldown timeouts— additional E2E coveragefix: ship-prep — typecheck fixes, llms.txt regen, 8-phase test update— typecheck fixes after mergeTest Coverage
Coverage gate: PASS (100%). Full suite: 2793 pass / 0 fail / 258 skip in 722s.
Pre-Landing Review
Covered by
/plan-eng-reviewat plan stage (15 issues found and resolved across architecture / code quality / tests / performance) plus codex outside voice (8 findings, all resolved per the resolution bundle). Implementation followed the resolved plan; the test evidence covers the result. No new structural issues surfaced during ship.Highlights from the plan-stage review (all addressed):
trusted_workspace: bool— bounds blast radius even on prompt-injection successctx.remoteflagsubagent_tool_executions, not time-windowedpages.updated_atdream_verdictstable (raw_data is page-scoped, wrong shape)_or.md)Eval Results
No prompt-related Rails files changed — gbrain doesn't use the eval harness in this branch's diff. Eval suites for synthesis quality + significance accuracy ship in the sibling
gbrain-evalsrepo as a follow-up.Plan Completion
Plan:
~/.claude/plans/system-instruction-you-are-working-iridescent-volcano.mdVerification Results
No dev server (CLI feature) — plan verification skipped. Functional verification covered by the 91-case unit + E2E suite.
TODOS
No TODOS.md items closed by this branch — net-new feature, not a fix for tracked work.
Documentation
Two non-skill docs updated for the v0.23.0 dream cycle (most user-facing docs were already covered in commit 6b80e07):
maintainskill row now notes the synthesize + patterns phases; thegbrain dreamcommand-reference block describes the 8-phase pipeline and the new--input <file>,--date YYYY-MM-DD,--from/--toad-hoc/backfill flags.Already up to date (v0.23.0 was prepped in earlier branch commits): CHANGELOG.md, CLAUDE.md, VERSION, skills/maintain/SKILL.md, skills/RESOLVER.md, skills/_brain-filing-rules.{md,json}, skills/migrations/v0.23.0.md, llms.txt, llms-full.txt.
Test plan
gbrain dream --helpdocuments the 8-phase pipeline and new flagsgbrain dream --phase synthesize --dry-runruns Haiku verdict, skips Sonnet, produces zero pages🤖 Generated with Claude Code