v0.41.30.0 fix(brainstorm/lsd): --save writes the advertised .md file via canonical ingestion path#1655
Merged
Merged
Conversation
Lift the v0.38 put_page disk write-through (operations.ts) into a shared src/core/write-through.ts helper and upgrade it to write atomically (unique temp file + rename) so a crash or a concurrent gbrain sync can never read a half-written .md. put_page now calls the helper; behavior is preserved (repo guards, source-awareness, provenance overrides) and its write is now atomic. brainstorm/lsd --save will call the same helper. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ingestion
--save printed 'Saved to <slug>' unconditionally but only did a raw DB
putPage: the promised wiki/ideas/<slug>.md file was never written, the page
had no chunks (unsearchable, and churned by the next sync), and a failed DB
write under PgBouncer still claimed success.
Route save through importFromContent({noEmbed:true}) for a canonical row, then
the shared writePageThrough helper renders the file from that row. persistSavedIdea
+ formatSaveOutcome report honestly which sinks landed and exit nonzero when
nothing persisted. buildIdeaSlug gets a random nonce so same-day ideas don't
clobber. New buildBrainstormFrontmatterObject feeds serializeMarkdown.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…0.41.30.0) Add Key Files entry for the new shared atomic src/core/write-through.ts helper, note the brainstorm/lsd --save canonical-ingestion rewrite on the brainstorm entry, and note put_page now calls the shared atomic helper on the operations.ts entry. Regenerate llms-full.txt to match. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mgunnin
added a commit
to mgunnin/gbrain
that referenced
this pull request
Jun 3, 2026
* upstream/master: v0.41.36.0 feat(mcp): publish agent skills (list_skills / get_skill) for thin clients (garrytan#1661) v0.41.35.0 feat(guardrails): vendor-neutral content guardrail seams (supersedes garrytan#1652) (garrytan#1660) v0.41.34.0 feat(search): retrieval cathedral — max-pool + title + alias + evidence (garrytan#1657) v0.41.33.0 feat(search): intent-aware adaptive return-sizing + agent-facing query param (garrytan#1640) v0.41.32.0 fix(staleness): commit-relative sync staleness (supersedes garrytan#1623) (garrytan#1656) v0.41.31.0 feat(embed): delta-aware sync --all cost gate + real stale-embedding semantics (garrytan#1632) v0.41.30.0 fix(brainstorm/lsd): --save writes the advertised .md file via canonical ingestion path (garrytan#1655) # Conflicts: # src/core/operations.ts
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
Supersedes #1634 (closed). Fixes a silent-data-loss bug in
gbrain brainstorm/lsd --saveand hardens the shared disk write-through.--saveprintedSaved to <slug>unconditionally but only did a raw DBengine.putPage:wiki/ideas/<slug>.mdfile (promised by the help text) was never written.gbrain searchcouldn't find it and the nextgbrain syncchurned the row.gbrain get <slug>returnedpage_not_found. Nothing landed anywhere.The fix routes
--savethrough the same canonical ingestion path the rest of gbrain uses:refactor: extract shared atomic writePageThrough helper— lifts the v0.38put_pagedisk write-through out ofoperations.tsintosrc/core/write-through.ts, shared byput_pageand brainstorm save. Upgraded to atomic write (unique temp sibling +rename, cleanup on failure) so a crash or a concurrentgbrain synccan never read a half-written.md. This hardensput_page's own write-through as a side effect.fix(brainstorm/lsd): --save writes the advertised file via canonical ingestion—persistSavedIdearunsimportFromContent({noEmbed:true})(canonical chunked/tagged row, no embedding cost) thenwritePageThroughrenders the file from the saved row (sinks can't diverge). PureformatSaveOutcomereports exactly which sinks landed and exits nonzero only when nothing persisted, so a scripted--savecan't be mistaken for success.buildIdeaSluggets a random nonce to stop same-day slug clobber. NewbuildBrainstormFrontmatterObjectfeedsserializeMarkdown(the old string builder is left untouched).The synthesize.ts surrogate-slice change from #1634 was dropped — master already has the canonical
safeSplitIndex(v0.41.13) that supersedes it.Test Coverage
Two new test files:
test/write-through.test.ts(helper: written/skip/error branches + ENOTDIR atomicity, no.tmpleftover) andtest/brainstorm/save.test.ts(persistSavedIdea + formatSaveOutcome all branches + buildIdeaSlug collision). Includes 3 mandatory regression cases: DB import throws → exit 1 "NOT persisted"; repo set but file write fails → DB-saved + exit 0; thedbSaved && !fileSavedhonesty branch can no longer claim "no repo set" when the repo was set.Gate evidence on this diff's blast radius:
bun run typecheck— cleanbun run verify— 29/29 CI checks greentest/brainstorm/full dir — 112 passNote: the full ~780-file
bun run testsuite was killed by SIGTERM at ~23% on this machine (PGLite WASM cold-starts × 4 shards under load; empty failure log = infrastructure, not test failures). The behavioral change is tightly localized to theput_pagewrite-through block + the new helper + brainstorm save, and the curated suite plusverify/typecheck cover that surface. Recommend a full CI run on the PR to confirm.Pre-Landing Review
Reviewed via
/plan-eng-review(architecture/code/tests/perf) + a Codex outside-voice pass. Codex caught that rawputPageproduces a non-canonical row (sync churn + unsearchable) and pointed at the existingput_pagewrite-through; the plan pivoted to reuse it viaimportFromContent({noEmbed}). All findings resolved before implementation. No open issues.Plan Completion
All 7 planned tasks DONE: shared helper extraction,
put_pagerewire,buildBrainstormFrontmatterObject,persistSavedIdea/formatSaveOutcome+ CLI wiring, regression tests,buildIdeaSlugnonce, TODOS source-awareness follow-up.Documentation
CLAUDE.md "Key files" updated with
src/core/write-through.ts (v0.41.30.0, NEW)plus v0.41.30.0 notes on the brainstorm and operations entries;llms-full.txtregenerated (bun run build:llms, CI gate verified). CHANGELOG v0.41.30.0 entry with how-to + "To take advantage of" block.Test plan
bun run typecheckcleanbun run verify(29 checks) green🤖 Generated with Claude Code