Skip to content

Commit 24337b3

Browse files
committed
docs(plans): settle Q-6 — read + flag stale snippets
Agent-first: gives data + structured warning; preserves agent autonomy (e.g. 'I want stale to compare with what changed'). Refuse + auto-reindex both rejected — refuse forces 3 round-trips for content already on disk; auto-reindex hides side-effects from a read tool and breaks the read/write separation we kept clean across PRs #33 / #35 / #37. All 6 grill questions now settled — ready for tracer 1.
1 parent 267d973 commit 24337b3

1 file changed

Lines changed: 2 additions & 1 deletion

File tree

docs/plans/targeted-read-cli.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,11 @@ Estimated total: ~1 day across 6 commits.
127127
- **Q-3. Exact match or substring/regex?****Exact (`name = ?`) only.** Agents have the exact name in 95% of cases (read from stack traces, import statements, prior `query` results, code citations); "half-remembering" is a human pattern. Fuzzy under `show` would silently over-match on typos and inflate the disambiguation envelope. Exact-only fails fast with a recipe-aware error pointing at the escape hatch: `{"error": "no symbol named 'foo'. Try query with LIKE '%foo%' for fuzzy lookup."}` — agent immediately knows whether to fix the name or switch tools. Rejected (b) substring default — useful-when-correct vs noisy-when-typo is the wrong trade. Rejected (c) two-flag (`--like` opt-in) — every flag is cognitive load on the agent's tool-call planning; `query` already covers fuzzy with one MCP call; we don't need two ways to do the same thing. Keeps the `show` mental model sharp: "I know the name → I want to know where it lives."
128128
- **Q-4. File-scope filter (`--in <path>`)?** ✅ **Ship `--in`.** Closes the loop with the disambiguation envelope (Q-2): the envelope already lists candidate files, so the agent's natural next move is "narrow by path" — that next move should be a flag add, not a tool switch to `query`. `--kind` solves "function vs const" but doesn't solve "this folder vs that folder" (the common ambiguity case). Cost is ~5 LOC. Match rule: if `<path>` ends with `/` or names a directory, treat as prefix (`AND file_path LIKE 'src/cli/%'`); else exact file match (`AND file_path = 'src/cli/cmd-query.ts'`). No glob characters — power users use `query`. **Path normalization via existing `toProjectRelative(projectRoot, p)` from `src/cli/cmd-validate.ts`** (verified — already handles leading `./`, trailing `/`, Windows backslash → POSIX) so `--in ./src/cli/` and `--in src/cli` both resolve identically. Forward-compatible: future `--in-package` / `--in-owner` would be sibling flags. Rejected (b) skip — wastes the disambiguation envelope's groundwork; forces tool-switch to `query` for what should be a parameter add.
129129
- **Q-5. Snippet sibling — now or later?** ✅ **Ship `codemap snippet <name>` together with `show` in v1.** Architectural fact-check (verified against codebase): the lookup helper (`findSymbolsByName`) is shared with `show`; `readFileSync(abs, "utf8")` + `toProjectRelative` + `hashContent` (from `src/hash.ts`) + `files.content_hash` comparison is the literal pattern `cmd-validate.ts` already uses for stale detection — pure copy-paste reuse, no new architecture. Marginal cost: ~2-3 hours on top of `show` (~15 LOC slice helper, ~40 LOC `cmd-snippet.ts`, ~25 LOC MCP tool, tests). Splitting into a follow-up PR would duplicate the docs / changeset / Rule-10 mirror overhead — not a real saving. Snippet output: `{matches: [{...metadata, source: "...", stale?: true}]}` — additive field on Q-2's envelope, no shape divergence. Rejected (c) `--with-source` flag — Q-2's lesson against polymorphic envelopes applies; sibling verb is cleaner. Rejected (a) defer — duplicate-PR overhead exceeds the marginal-feature cost.
130+
- **Q-6. Stale-file behavior for `snippet`?** ✅ **(1) Read + flag.** When `hashContent(readFileSync(abs))` differs from `files.content_hash`, return the source content from disk with `stale: true` on the match; agent decides whether to act on possibly-shifted line ranges. Agent-first reasoning: gives the agent data + warning, preserves their autonomy (e.g. "I want stale to compare with what changed"). Bundled `templates/agents/skills/codemap/SKILL.md` teaches the next step ("if `stale: true`, the line range may have shifted — verify with `query` or re-index before acting"). Rejected (2) refuse — hostile; forces 3 round-trips (snippet → error → reindex → snippet) for content that's already on disk. Rejected (3) auto-reindex — hidden side-effect from a read tool violates the read/write separation we've kept clean across PRs #33 / #35 / #37; latency spike on every snippet call against a touched file; destroys the "I want stale" use case. Implementation: ~5 LOC (one hash compare + one boolean field).
130131

131132
### Still open
132133

133-
- **Q-6. Stale-file behavior for `snippet`.** When the index says `foo` is at `src/utils/foo.ts:5-15` but the file's `hashContent(readFileSync(abs))` differs from `files.content_hash`, three options: (1) Read anyway, flag staleness — `{matches: [{..., source: "...", stale: true}]}`; agent decides whether to act. (2) Refuse on staleness — error pointing at `codemap` (re-index). (3) Auto re-index that file under the hood (`runCodemapIndex` with `--files <path>` mode) before reading. Agent-first bias toward (1) — gives data + warning, lets the agent choose; (2) is hostile (forces an index round-trip the agent didn't ask for), (3) is hidden side-effect plus latency.
134+
_None — all 6 questions settled. Ready to start tracer 1._
134135

135136
## 8. Non-goals (v1)
136137

0 commit comments

Comments
 (0)