typescript-duckbrain-temp-scratch-db-files
All recipe commands validated (simulated 15/15 hash matches; "pid dead" is expected in the simulation since the simulated pid is a throwaway subshell — on a live host it resolves against /proc/<daemonpid>).
Wrote the complete diagnosis to ~/duckbrain-temp-scratch-db-files.md, after verifying every claim against the actual source in wojons/duckbrain (cloned to /tmp/duckbrain-repo).
Findings confirmed in code:
- src/duckdb/connection.ts:40 — CONNECTION_MAX_AGE_MS = 1h recycle window
- connection.ts:133-146 — singletonDbPath(): duckbrain-<pid>-<sha1(ns)[0..12]>-<counter++.db, monotonic per-process counter
- connection.ts:148-156 — closeEntry() unlinks on close (fire-and-forget)
- connection.ts:176-195 — recycle allocates a new scratch file each time
- src/duckdb/connection-gap001.test.ts — GAP-001 regression suite confirms the scratch-file design is deliberate (avoids cross-process single-writer lock on <ns>/duckdb.db)
Verdict: benign steady-state working set, NOT a leak. 150 opens → 67 live files proves unlink works on recycle; on-disk count ≈ namespaces touched in the last hour. The real crash-era leak was already fixed (DOGFOOD-016, dead-pid-only startup sweep; pid-reuse files like pid 2157 = sd-pam stay by design).
Document contents: root-cause analysis, the three discriminating signatures (pid liveness, sha1↔namespace match, counter-vs-disk ratio), a "fix" section stating no code change required (with optional clean-shutdown hardening and a counter-vs-disk leak alarm), and a fully re-runnable 5-step verification recipe with acceptance criteria — all commands syntax-validated against a simulated scratch-file set.
# Evidence - Problem class: typescript-duckbrain-temp-scratch-db-files - Model: openrouter/deepseek/deepseek-v4-flash-0731 - Solved: 2026-08-17T20:33:00.544Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "DuckBrain daemon leaves /tmp/duckbrain-<pid>-<hash>-<n>.db files; 67 accumulated in ~21h of uptime. VERDICT: benign steady state, NOT a leak. Root cause: GAP-001 per-process scratch design in src/duckdb/connection.ts \u2014 one cached singleton connection per namespace (getSingletonConnection), CONNECTION_MAX_AGE_MS=1h recycle creates a NEW scratch file per recycle (singletonDbPath counter++), unlink fires on close (closeEntry). On-disk count = distinct namespaces touched within the last hour, not leaked files. Verification recipe: (1) all files share the live daemon pid; (2) sha1(namespacePath) slice(0,12) of the hash matches relative path form 'namespaces/<ns>' (daemon cwd via /proc/<pid>/cwd); 64/67 matched real fleet namespaces; (3) counter (highest -n suffix) counts opens since start (150 opens, 67 live = unlink works on recycle); (4) crash-era dead-pid files are swept once at startup by sweepOrphanScratchFiles (dead-pid only; files whose pid was REUSED by a live unrelated process stay by design \u2014 e.g. pid 2157 = sd-pam). DOGFOOD-016 fixed the real crash-era leak (2514->32 files). No repair needed; do not flag.", "environment": "", "language": "typescript", "model": "openrouter/deepseek/deepseek-v4-flash-0731", "problem_class": "typescript-duckbrain-temp-scratch-db-files", "provider": "openrouter", "solved_at": "2026-08-17T20:33:00.544Z", "version": ""}All recipe commands validated (simulated 15/15 hash matches; "pid dead" is expected in the simulation since the simulated pid is a throwaway subshell — on a live host it resolves against /proc/<daemonpid>).
Wrote the complete diagnosis to ~/duckbrain-temp-scratch-db-files.md, after verifying every claim against the actual source in wojons/duckbrain (cloned to /tmp/duckbrain-repo).
Findings confirmed in code:
- src/duckdb/connection.ts:40 — CONNECTION_MAX_AGE_MS = 1h recycle window
- connection.ts:133-146 — singletonDbPath(): duckbrain-<pid>-<sha1(ns)[0..12]>-<counter++.db, monotonic per-process counter
- connection.ts:148-156 — closeEntry() unlinks on close (fire-and-forget)
- connection.ts:176-195 — recycle allocates a new scratch file each time
- src/duckdb/connection-gap001.test.ts — GAP-001 regression suite confirms the scratch-file design is deliberate (avoids cross-process single-writer lock on <ns>/duckdb.db)
Verdict: benign steady-state working set, NOT a leak. 150 opens → 67 live files proves unlink works on recycle; on-disk count ≈ namespaces touched in the last hour. The real crash-era leak was already fixed (DOGFOOD-016, dead-pid-only startup sweep; pid-reuse files like pid 2157 = sd-pam stay by design).
Document contents: root-cause analysis, the three discriminating signatures (pid liveness, sha1↔namespace match, counter-vs-disk ratio), a "fix" section stating no code change required (with optional clean-shutdown hardening and a counter-vs-disk leak alarm), and a fully re-runnable 5-step verification recipe with acceptance criteria — all commands syntax-validated against a simulated scratch-file set.
# Evidence - Problem class: typescript-duckbrain-temp-scratch-db-files - Model: openrouter/deepseek/deepseek-v4-flash-0731 - Solved: 2026-08-17T20:33:00.544Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "DuckBrain daemon leaves /tmp/duckbrain-<pid>-<hash>-<n>.db files; 67 accumulated in ~21h of uptime. VERDICT: benign steady state, NOT a leak. Root cause: GAP-001 per-process scratch design in src/duckdb/connection.ts \u2014 one cached singleton connection per namespace (getSingletonConnection), CONNECTION_MAX_AGE_MS=1h recycle creates a NEW scratch file per recycle (singletonDbPath counter++), unlink fires on close (closeEntry). On-disk count = distinct namespaces touched within the last hour, not leaked files. Verification recipe: (1) all files share the live daemon pid; (2) sha1(namespacePath) slice(0,12) of the hash matches relative path form 'namespaces/<ns>' (daemon cwd via /proc/<pid>/cwd); 64/67 matched real fleet namespaces; (3) counter (highest -n suffix) counts opens since start (150 opens, 67 live = unlink works on recycle); (4) crash-era dead-pid files are swept once at startup by sweepOrphanScratchFiles (dead-pid only; files whose pid was REUSED by a live unrelated process stay by design \u2014 e.g. pid 2157 = sd-pam). DOGFOOD-016 fixed the real crash-era leak (2514->32 files). No repair needed; do not flag.", "environment": "", "language": "typescript", "model": "openrouter/deepseek/deepseek-v4-flash-0731", "problem_class": "typescript-duckbrain-temp-scratch-db-files", "provider": "openrouter", "solved_at": "2026-08-17T20:33:00.544Z", "version": ""}