diff --git a/.claude/skills/titan-gauntlet/SKILL.md b/.claude/skills/titan-gauntlet/SKILL.md index 00f976d58..49d2a3736 100644 --- a/.claude/skills/titan-gauntlet/SKILL.md +++ b/.claude/skills/titan-gauntlet/SKILL.md @@ -240,7 +240,9 @@ codegraph co-change -T --json ``` Find semantically similar functions. If `codegraph search` fails (no embeddings), use grep for function signature patterns. **Warn:** similar patterns. **Fail:** near-verbatim copy. -> Note: requires embeddings from `/titan-recon`. If `titan-state.json → embeddingsAvailable` is false, skip semantic search and note it. +> **Don't trust `embeddingsAvailable` blindly — verify it against the current worktree.** `.codegraph/` is gitignored, so `graph.db` and its embeddings are local, per-worktree filesystem state; they are never carried over by a branch merge or a "switch to that worktree's state" step in Step 0. A `titan-state.json` merged in from a different worktree/session can say `embeddingsAvailable: true` while the graph.db actually open right now has none — `codegraph search` will then run without erroring and silently return empty results, so Rule 11 looks clean when it never actually checked anything. +> +> Before relying on `embeddingsAvailable`, do a deterministic identity check first: compare `git rev-parse --show-toplevel` (this worktree) against `titan-state.json → embeddingsWorktreePath` (the worktree RECON actually ran `codegraph embed` in). Any mismatch — or a missing `embeddingsWorktreePath` from an older state file — means `embeddingsAvailable` cannot be trusted as-is; treat it as `false` until re-verified. Then, at the start of Step 2 (not per-file), run a one-time smoke-test: `codegraph search "test query" --json`. Treat only an explicit error or `ENGINE_UNAVAILABLE` as failure — the same concrete criterion RECON uses — not a subjective "no hit where one seemed likely" judgment call, since a generic query legitimately returning zero results is not itself proof of a broken engine. If either check fails, regenerate for **this** worktree — `codegraph embed -m minilm` — and update both `titan-state.json → embeddingsAvailable` and `embeddingsWorktreePath` before trusting it for any Rule 11 check this run. If regeneration also fails, fall back to grep-only DRY checks and log it to `issues.ndjson` rather than proceeding on a false green. #### Rule 12 — Naming symmetry ```bash diff --git a/.claude/skills/titan-recon/SKILL.md b/.claude/skills/titan-recon/SKILL.md index 2544c611a..f4cea12c5 100644 --- a/.claude/skills/titan-recon/SKILL.md +++ b/.claude/skills/titan-recon/SKILL.md @@ -55,6 +55,14 @@ codegraph embed -m minilm This enables `codegraph search` for duplicate code detection in downstream phases. If it fails (e.g., missing model), note it and continue — DRY checks will be grep-only. +**Verify, don't assume.** `.codegraph/` is gitignored — `graph.db` (and its embeddings) is local filesystem state, per worktree. It is never carried over by `git merge`, a branch switch, or a snapshot restore. Before setting `embeddingsAvailable` in `titan-state.json`, smoke-test the current worktree's DB directly: + +```bash +codegraph search "test query" --json +``` + +Only set `embeddingsAvailable: true` if this returns results (or a valid empty match, not an error/`ENGINE_UNAVAILABLE`). Alongside the flag, record `embeddingsWorktreePath` in `titan-state.json` as the output of `git rev-parse --show-toplevel` — this gives downstream phases a deterministic identity to compare against instead of having to re-derive trust from a smoke test alone. If a downstream phase (e.g. GAUNTLET) ends up operating in a **different worktree** than the one RECON ran `codegraph embed` in — including via "merge the other worktree's branch into mine" — its `graph.db` will not have embeddings even though a stale `titan-state.json` from elsewhere claims `embeddingsAvailable: true`; a mismatch between `embeddingsWorktreePath` and that worktree's own `git rev-parse --show-toplevel` is the unambiguous signal for this. Re-run `codegraph embed -m minilm` for the worktree actually being used, update both `embeddingsAvailable` and `embeddingsWorktreePath`, and re-verify with the smoke-test above, whenever the operating worktree changes. + --- ## Step 3 — Collect baseline metrics @@ -236,6 +244,7 @@ Include the preserved `phaseTimestamps` in the state file below. "lastBatch": null }, "embeddingsAvailable": true, + "embeddingsWorktreePath": "", "stats": { "totalFiles": 0, "totalNodes": 0,