Skip to content
ƒtsforgev0.52.0
19

Decision memory (BYO)

4 min read

When you build a fullstack app over multiple days, tsforge can remember product and architecture decisions (FK UX, naming, what already shipped) by talking to a memory backend you run. No vendor is bundled. Fresh tsforge in the same project loads the brief — you do not need --continue.

This is separate from Learning from past runs (Phase 1 failure→fix → TTSR). That channel stays local and automatic. Decision memory is opt-in context only: it never changes the gate.

  1. Run a Hindsight-compatible API (example):
Terminal window
docker run -it --pull always --name hindsight -p 8888:8888 -p 9999:9999 \
-e HINDSIGHT_API_LLM_API_KEY=$OPENAI_API_KEY \
-v hindsight-data:/home/hindsight/.pg0 \
ghcr.io/vectorize-io/hindsight:latest
  1. Add to tsforge.config.json at the project root:
{
"providers": {
"memory": {
"kind": "http",
"baseUrl": "http://localhost:8888"
}
}
}

Optional: set "bankId": "tsforge:github.com/acme/crm" to pin the bank. Otherwise tsforge derives it (see below).

  1. Session A: build a feature with a non-obvious decision (“company FK is a native <select>”). When the gate goes green — or a greenfield feature verifies — tsforge retains it. You should see a tool line decision memory: retained to bank … (or retain failed … if the backend rejected the write).

  2. Session B (new terminal, same repo): tsforge again. On start you should see either decision memory: loaded brief for bank … or decision memory: bank … ready (empty). An empty bank is still wired for retains — the write path is not dropped just because recall had nothing.

  3. Stop the backend and run again — the session still starts; there is simply no brief. The same holds for a backend that hangs rather than refusing: every memory call carries a 3s deadline and start-up is capped, so a sick backend cannot block the CLI. A slow recall times out the brief only; the provider stays attached so later green sends can still retain.

Three curated channels (never the raw user prompt):

  • Post-green extraction (default on) — after an interactive send goes green, tsforge asks the session model for durable product/architecture decisions from that turn and retains 0..N of them. Plan approvals, harness chatter, debugging, and one-off tasks yield nothing.
  • /remember <decision> — you explicitly park a decision in the bank.
  • Greenfield feature verifiedFeature verified: <id> — <description>.

Before anything is sent, a redaction pass drops lines that look like secrets (API_KEY=…, password: …, authorization: …) and rewrites every sk-… token.

To disable automatic post-green extraction (and rely on /remember + greenfield only):

{
"providers": {
"memory": {
"kind": "http",
"baseUrl": "http://localhost:8888",
"autoRetain": false
}
}
}

Legacy retainPrompts: false still opts out. Raw prompt retain is gone — retainPrompts: true is obsolete and ignored.

Whatever recall returns is injected into the agent’s context inside a <project-decisions> block that marks it as reference data, never instructions. Bank contents are model-extracted and unreviewed, so anyone able to write to the bank — a teammate, another project sharing a bank id, a poisoned memory — would otherwise be writing straight into the highest-trust part of the prompt.

{
"providers": {
"memory": {
"kind": "mcp",
"server": "hindsight",
"retainTool": "retain",
"recallTool": "recall",
"forgetTool": "forget"
}
},
"mcpServers": {
"hindsight": {
"command": "npx",
"args": ["-y", "your-hindsight-mcp"]
}
}
}

Tool names default to retain / recall / forget. They are invoked as mcp__<server>__<tool> with bank_id and content / query.

Computed each session — not read from .tsforge/:

  1. providers.memory.bankId if set
  2. Else normalized git remote get-url origintsforge:github.com/acme/crm
  3. Else tsforge:path: + SHA-256 of the project root (directory that owns .git or tsforge.config.json)

Same remote on two machines shares one bank. /memory prints the resolved bank when configured.

Curated decision text only (e.g. “Contact.companyId required; company FK is native select”). Not full chat, not file dumps. Obvious secrets (API_KEY=…, sk-…) are redacted before retain. HTTP retains use context tag tsforge-decision.

In an interactive session:

  • /memory — coding lessons (Phase 1 TTSR ledger) + project decisions from the external provider
  • /remember <decision> — retain one durable product/architecture decision now
  • /memory forget — clear the local ledger and ask the provider to clear that bank

/memory prints the resolved bank id when configured.

Backend down, bad config, or unknown kind → warn or skip; session and gate continue. Omit providers.memory → today’s behavior (Phase 1 only).

tsforge.config.json · MCP servers · Learning from past runs · Interactive CLI