Environment
- gstack 1.60.1.0
- gbrain 0.42.66.0, Postgres engine, local stdio MCP (
mcpServers.gbrain = {"type":"stdio","command":"gbrain","args":["serve"]})
- Linux
What happens
memory-ingest already renders every session to markdown and stages it on disk, then behaves differently based only on the MCP transport:
// bin/gstack-memory-ingest.ts:1567-1571
const stagingDir = resuming
? resumeDir!
: remoteHttpMode
? makePersistentTranscriptDir() // ~/.gstack/transcripts/run-<pid>-<ts>/ — kept, import skipped
: makeStagingDir(); // ~/.gstack/.staging-ingest-<pid>-<ts>/ — imported, then deleted
with remoteHttpMode = isRemoteHttpMcpMode() (:1256), and cleanup at :1832 (if (!remoteHttpMode && !preserveStaging) cleanupStagingDir(stagingDir)).
--no-write (:1472) is not an escape hatch — it returns before the staging dir is created (:1567), so it skips writing the files, not the import.
Net effect on a local brain: the rendered markdown exists for milliseconds and is deleted, and the raw dialogue is imported as searchable pages instead.
What I expected
A supported way — flag or env var — to say "render to a stable directory and don't import", independent of transport.
Minimal repro
# ~/.claude.json has mcpServers.gbrain = {"type":"stdio", ...}
gstack-memory-ingest.ts # → pages imported; ~/.gstack/transcripts/ never created
gstack-memory-ingest.ts --no-write # → nothing written anywhere
ls ~/.gstack/transcripts # → does not exist
Why it matters
gbrain's own dream synthesizer consumes a directory of .txt/.md files:
// gbrain src/core/cycle/transcript-discovery.ts:190
} else if (st.isFile() && (name.endsWith('.txt') || name.endsWith('.md'))) {
fed by dream.synthesize.session_corpus_dir. So gstack already produces exactly the artifact gbrain's synthesizer is built to consume — but only users on a remote-http brain can reach it.
Local users get the opposite of what gbrain's own schema guidance recommends: raw dialogue as searchable pages, competing with (and outranking) curated notes at retrieval time. On one brain this accumulated ~900 transcript pages that agents then retrieved as current fact, including descriptions of components that had since been deleted; agents repeatedly discarded the hits as "pilot-era transcripts" in their own logs.
The persistent-dir code path already exists and is exercised in remote-http mode — this is a switch, not a feature build.
Suggested fix
Make the mode selectable rather than transport-derived — two lines:
const forcePersist = process.env.GSTACK_TRANSCRIPTS_PERSIST === "1" || args.persistTranscripts;
const remoteHttpMode = isRemoteHttpMcpMode() || forcePersist;
Everything downstream (skip import at :1668, skip cleanup at :1832, skip _activeStagingDir registration at :1577) already keys off remoteHttpMode.
Related nicety: gbrain import accepts --source-id, but the memory stage never passes it (:1419), so imported pages land in default regardless of how many sources the brain has.
Environment
mcpServers.gbrain = {"type":"stdio","command":"gbrain","args":["serve"]})What happens
memory-ingestalready renders every session to markdown and stages it on disk, then behaves differently based only on the MCP transport:with
remoteHttpMode = isRemoteHttpMcpMode()(:1256), and cleanup at:1832(if (!remoteHttpMode && !preserveStaging) cleanupStagingDir(stagingDir)).--no-write(:1472) is not an escape hatch — it returns before the staging dir is created (:1567), so it skips writing the files, not the import.Net effect on a local brain: the rendered markdown exists for milliseconds and is deleted, and the raw dialogue is imported as searchable pages instead.
What I expected
A supported way — flag or env var — to say "render to a stable directory and don't import", independent of transport.
Minimal repro
Why it matters
gbrain's own dream synthesizer consumes a directory of
.txt/.mdfiles:fed by
dream.synthesize.session_corpus_dir. So gstack already produces exactly the artifact gbrain's synthesizer is built to consume — but only users on a remote-http brain can reach it.Local users get the opposite of what gbrain's own schema guidance recommends: raw dialogue as searchable pages, competing with (and outranking) curated notes at retrieval time. On one brain this accumulated ~900 transcript pages that agents then retrieved as current fact, including descriptions of components that had since been deleted; agents repeatedly discarded the hits as "pilot-era transcripts" in their own logs.
The persistent-dir code path already exists and is exercised in remote-http mode — this is a switch, not a feature build.
Suggested fix
Make the mode selectable rather than transport-derived — two lines:
Everything downstream (skip import at
:1668, skip cleanup at:1832, skip_activeStagingDirregistration at:1577) already keys offremoteHttpMode.Related nicety:
gbrain importaccepts--source-id, but the memory stage never passes it (:1419), so imported pages land indefaultregardless of how many sources the brain has.