git-hook-cwd-namespace-not-found
Done. I diagnosed the problem, verified it with a faithful simulation, implemented and verified the fix, and wrote the solution to /tmp/hook-cwd-fix.md.
Root cause: Git fires hooks with cwd set to the event repo's top level, not the DuckBrain install root. The CLI resolves ./namespaces/<ns> relative to cwd, so when a hook fires from a namespace repo, the path doesn't resolve → Namespace not found at namespaces/<ns>. Since --detached surfaces no stderr, the rebuild dies silently with no rebuild.log. I reproduced this exactly (post-checkout fired with cwd = /tmp/nsrepo → NO rebuild.log).
Fix: Normalize to DUCKBRAIN_ROOT inside the generated hook before invoking the CLI — DUCKBRAIN_ROOT = dirname(dirname(readlink -f $DB_BIN)), then cd there. This keeps the hook self-contained (no reliance on external cwd/env) and also handles symlinked bins (e.g. node_modules/.bin).
Verification (live):
- Pre-fix from namespace-repo cwd: NO rebuild.log (silent death confirmed)
- Post-fix from namespace-repo cwd: rebuild.log written, git status clean
- Symlinked-bin case: realpath -> dirname dirname → /tmp/dbroot ✓
Note: The same guard must be applied to all generated hooks (post-checkout/post-merge/post-rewrite) and to src/embedding/hooks.ts (tracked as EMB-001), which has the identical latent bug. The solution document includes a TypeScript implementation note and acceptance criteria.
# Evidence - Problem class: git-hook-cwd-namespace-not-found - Model: openrouter/deepseek/deepseek-v4-flash-0731 - Solved: 2026-08-19T10:41:27.963Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "DuckBrain (git-backed persistent memory) installs git hooks (post-checkout/post-merge/post-rewrite) that fire `duckbrain search-index rebuild --namespace <ns> --detached --log <path>` (RETR-010, commit dc4ef03). Symptom: after firing post-checkout from a namespace repo cwd, the detached rebuild silently dies with 'Namespace not found at namespaces/<ns>' and no rebuild.log. Root cause: git fires hooks with cwd = the repo where the event happened (the namespace repo root, not the duckbrain installation root), so the CLI's cwd-relative ./namespaces config resolution fails. Fix: in the generated hook script, when the duckbrain bin path resolves absolute, step up to the duckbrain root (dirname dirname of bin) and cd there before invoking (DUCKBRAIN_ROOT normalization), keeping the hook self-contained. Verified live: post-checkout from namespace cwd -> detached rebuild ran -> fts.duckdb built, rebuild.log written, git status clean. Note: src/embedding/hooks.ts has the identical latent bug (embeddings parity follow-up filed as EMB-001).", "environment": "", "language": "typescript", "model": "openrouter/deepseek/deepseek-v4-flash-0731", "problem_class": "git-hook-cwd-namespace-not-found", "provider": "openrouter", "solved_at": "2026-08-19T10:41:27.963Z", "version": ""}