Making of - claude-mem-house¶
A living journal of how this repo came to be and how it changes over time.
Chapter 1: the org-migration tool-repo fan-out (2026-07-08)¶
This repo was built as one of eight tools shipped in parallel through the house's
standard tool-repo pipeline (pilot: house-council-client), ahead of a pending org
migration - every fan-out repo builds and commits locally only, no GitHub repo, no
push, until the migration lands.
Source material. Four PowerShell scripts Andrew had been hand-carrying between house
PCs from C:\Users\fives\OneDrive\: a client-setup script that points a house PC's
Claude Code at the shared claude-mem server, a warm-standby setup + prereqs pair that
turns a second PC into an hourly-synced disaster-recovery mirror, and a switch-server
script for failover/failback. These already managed real house infrastructure - the
ANDYGREATROOMPC:37877 server-beta stack (Postgres 17 + Valkey 8 + claude-mem-server) -
so the goal was packaging, not redesign.
What changed vs. the OneDrive originals. A manual read (the automated pre-scan
missed both, see docs/technical/SECURITY.md) turned up two embedded credentials: the
house claude-mem API key (cmem_...) in two scripts, and the standby's Postgres
password - the latter duplicated a second time inside a here-string that the standby
script writes out as a separate generated script file. Both scripts were rewritten to
read these from environment variables / matching parameters, defaulting the same way the
pilot's council connect scripts default their bearer tokens. The generated sync script
was changed to resolve the password at its own run time (env var, else the standby's
local .env) instead of carrying a baked-in literal.
Testing shape. These are full standalone installer/failover CLI scripts (Docker,
winget, scheduled tasks, DNS resolution, pg_dump) - a harder shape for coverage than
the pilot's two connect scripts, because their guard clauses call exit, and PowerShell's
exit kills the entire process even when the failing script was invoked via & from
inside another script. That rules out in-process test execution (which is how the pilot
achieved ~45% coverage) for anything that needs to prove an abort path works. The
resolution: behavioral guard tests spawn the real scripts as child processes (real
verification, invisible to Pester's in-process coverage instrumentation) alongside static
parse + secret-regression tests. Net measured coverage is an honest 0%, documented in
TESTING.md rather than silently accepted or gamed with a coverage-only rewrite. Full
happy-path E2E (mocking the claude-mem HTTP surface) is deferred - tracked as a board
ticket.
Codex security review. First pass came back "Not CLEAN": no active secrets, but real
findings - unpinned bun.sh/npx installer execution (accepted, documented inline as
the vendor's own install method), CI supply-chain items inherited verbatim from the
mandated house CI template (self-hosted PR runners, unpinned semgrep/Pester -
tracked at the fleet level, not this repo alone), a real shell-injection gap where the
generated standby sync script interpolated the Postgres password unescaped into
sh -c '...' strings (fixed - added POSIX single-quote escaping), and a test file that
kept the retired password's plaintext split across a string concatenation, still
reconstructable (fixed - the test now stores only a SHA-256 hash and hashes
password-shaped candidates for comparison, so the plaintext credential appears nowhere
in this repo's history from this point forward). Full disposition table:
docs/technical/SECURITY.md.
First ticket, closed at build time: package and harden the OneDrive scripts into this
repo, passing the house secret/security/testing gates. See docs/BOARD.md.