v1.13.6-prefix-stability
Recon during planning disproved the original v1.13.7 (DB-cache) premise: buildSystemPrompt already runs over inputs mtime-cached at the file layer (BOOCHAT.md in system-prompt.ts:25, AGENTS.md global+per-project in agents.ts:245), and DB scalars are byte-stable until edited. The output is microsecond pure-string concat with no I/O. Skills aren't in the prefix; tools live in a separate request body field alpha-sorted by v1.13.3. This batch closes the verification gap with instrumentation, not implementation: - system-prompt.ts: buildSystemPromptWithFingerprint canonical impl computes SHA-256 over the assembled prefix, runs a per-session Map<sessionId, lastHash> observer, emits PrefixFingerprint per call and PrefixDrift (with field-level changed_inputs) on hash change. buildSystemPrompt is now a thin shim returning .prompt. - agents.ts: getAgentsMtimes accessor — cache-read only, no I/O. - payload.ts: buildMessagesPayload takes optional log argument; when passed, emits prefix-fingerprint (info) + prefix-drift (warn). - turn.ts + sentinel-summaries.ts: pass ctx.log at 3 production call sites; sentinel summaries log too so any drift across cap-hit / doom-loop paths surfaces. - system-prompt.test.ts: 4 new tests (byte-identical, no-drift-on- stable, drift-fires-with-changed-inputs, cross-session-no-drift). 194/194 tests pass (was 190). Smoke: 5 messages in a fresh session produced 7 prefix-fingerprint logs (extras from buildMessagesPayload being called from sentinel summary paths), all with identical prefix_hash and prefix_length=2907, zero prefix-drift. Prefix is byte-stable in steady-state. Decision: original system_prompt_cache DB table from the roadmap is permanently dropped. The v1.12.0 mtime caches at the input layer plus alpha tool ordering at the request body (v1.13.3) already address the load-bearing cache-stability surfaces. Instrumentation stays so the claim can be re-verified at any time.
boocode
Self-hosted single-user developer chat app. v1: chat only.
Stack
- Node 20, Fastify, postgres (porsager/postgres), ws, zod
- React 18, Vite, TypeScript, Tailwind v4, shadcn/ui
- Postgres 16
- pnpm workspaces
Layout
apps/server— Fastify API + WebSocket + inference loop + file-read toolsapps/web— React frontend; served by Fastify in production, Vite in dev
Local dev
Requires Node 20, pnpm, Docker (for Postgres), and ripgrep.
# install
pnpm install
# bring up postgres only
cp .env.example .env
# edit POSTGRES_PASSWORD if you like; default DATABASE_URL points at the container
docker compose up -d boocode_db
# run server (port 3000) and web (port 5173) in two shells
DATABASE_URL=postgres://boocode:devpass@127.0.0.1:5500/boocode \
LLAMA_SWAP_URL=http://100.101.41.16:8401 \
pnpm dev:server
pnpm dev:web
The Vite dev server proxies /api and /api/ws/* to the Fastify backend with a
synthetic Remote-User: sam header so the Authelia auth layer can be skipped
during development.
Production
cd /opt/boocode
docker compose up --build -d
Binds to 100.114.205.53:9500 (Tailscale). Authelia is expected to gate the
upstream and inject Remote-User. Postgres binds loopback only.
What v1 has
Project sidebar, sessions per project, chat with streaming responses over
WebSocket, four file-read tools scoped to the project root (view_file,
list_dir, grep, find_files), and a model picker driven by llama-swap's
/v1/models.
What v1 does not have lives in v2 (terminal pane) and v3 (Coder pane).
Languages
TypeScript
94.1%
CSS
1.9%
JavaScript
1.2%
Shell
0.8%
Go
0.6%
Other
1.4%