feat(dream): --archive-dir flag persists CycleReport JSON + atomic latest.json symlink#1133
Open
ChenyqThu wants to merge 1 commit into
Open
feat(dream): --archive-dir flag persists CycleReport JSON + atomic latest.json symlink#1133ChenyqThu wants to merge 1 commit into
ChenyqThu wants to merge 1 commit into
Conversation
…on symlink Adds an --archive-dir <path> flag to `gbrain dream` that, when paired with --json, writes the CycleReport to <path>/<iso>.json (fs-safe colon-free timestamp) and atomically swaps a <path>/latest.json symlink to point at it. Motivation: the cron pattern of "spawn dream --json, capture stdout, parse, archive, swap a latest pointer" repeats across every downstream that wraps dream. Pushing the archive surface into core dream removes ~80 LoC from each wrapper while giving everyone the same atomic-swap contract (no dangling symlink visible to readers — rename is atomic on the same fs). Concrete fork case: jarvis-knowledge-os-v2 has a 205-line dream-wrap launchd worker whose primary value (after this PR lands) becomes the exit-code translation block (~30 lines); the entire archive + symlink surface (~80 lines) collapses into a single --archive-dir arg. Behavior: - --archive-dir without --json is a no-op + emits a stderr warning (printed human report has no JSON to archive) - Directory is auto-created (mkdirSync recursive) - ISO timestamp is colon-free (2026-05-17T23-45-12Z) so SMB / Windows shares accept the filenames - latest.json swap uses symlink-to-tmp + rename pattern (atomic on same fs); on platforms where symlink isn't supported the per-cycle file still lands and a stderr warning fires - Cycle status semantics unchanged (--archive-dir affects archive side-effect only, not exit code or report shape) Tests (29 pass, 0 fail in 19.46s): - test/dream-cli-flags.test.ts: 5 new static-introspection cases (flag declared, archive helper exists, no-op-without-json contract, isoStamp colon-free contract) - test/dream.test.ts: 5 new integration cases against real PGLite + real archive dir (per-cycle file + symlink shape, fs-safe filename, atomic swap on second run, auto-creates missing dir, no-op without --json) Typecheck: clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ChenyqThu
pushed a commit
to ChenyqThu/jarvis-knowledge-os-v2
that referenced
this pull request
May 17, 2026
…on 1) Filed 2026-05-17 with 29 pass / 0 fail test coverage. On merge, fork dream-wrap drops from 205 → ~30 LoC (exit-code translation only). 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
Adds an
--archive-dir <path>flag togbrain dreamthat, when paired with--json, writes the CycleReport to<path>/<iso>.json(fs-safe colon-free timestamp) and atomically swaps a<path>/latest.jsonsymlink to point at it.Motivation
The cron pattern of "spawn
dream --json, capture stdout, parse JSON, archive to a per-cycle file, swap alatestpointer" repeats across every downstream that wrapsdream. Pushing the archive surface into core removes ~80 LoC from each wrapper while giving everyone the same atomic-swap contract (no dangling symlink ever visible to readers —renameis atomic on the same fs).Concrete downstream case: my fork
jarvis-knowledge-os-v2ships a 205-linedream-wraplaunchd worker whose primary value (after this PR lands) becomes the exit-code translation block (~30 lines). The entire archive + symlink surface (~80 lines) collapses into a single--archive-dirarg.Behavior
--archive-dirwithout--jsonis a no-op + emits a stderr warning (printed human report has no JSON to archive)mkdirSyncrecursive)2026-05-17T23-45-12Z) so SMB / Windows shares accept the filenameslatest.jsonswap uses symlink-to-tmp + rename pattern (atomic on the same fs); on platforms where symlink isn't supported the per-cycle file still lands and a stderr warning fires--archive-diraffects archive side-effect only, not exit code or report shape)Help text
Test plan
bun run typecheck— cleanbun test test/dream-cli-flags.test.ts test/dream.test.ts— 29 pass / 0 fail / 72 expect() calls / 19.46stest/dream-cli-flags.test.ts(flag declared, archive helper exists, no-op-without-json contract, isoStamp colon-free contract)test/dream.test.tsagainst real PGLite + real archive dir::, sortable, matches regex)--json+ stderr warning emittedDiff size
3 files / +205 / -3 — additive flag, no behavior change for existing callers.
Related downstream cleanup
On merge, my fork drops
skills/kos-jarvis/dream-wrap/run.tsfrom 205 LoC to ~30 (exit code translation only). Filed as PR-3 in my fork's TODO.Pattern matches the
garrytan/gbrainPR style of #1016 (additive AI recipe field) and the superseded #1017 (bootstrap probes) — fork-side experience codified into upstream so the wrapper layer thins.🤖 Generated with Claude Code