fix(#475): make code-reading sub-agents MCP-first#477
Conversation
The "use MCP search before grep" rule only reached the main loop (via suggest-mcp-search.sh + feedback memory); spawned sub-agents read managed-project code with grep+Read instead. Confirmed 2026-06-01: the tech-lead sub-agent authored a curios-dog design with zero search_code calls in activity.jsonl. - Add mcp__apexyard-search__search_code + search_docs to the tools/allowed-tools of the 7 code-reading agents: tech-lead, backend/frontend/data/platform-engineer, qa-engineer, security-reviewer (code-reviewer already had search_docs; solution-architect already had both — the reference implementation) - Add a consistent "## MCP-first code search" block to each agent body: prefer search_code/search_docs over grep+Read; fall back to grep only when MCP returns nothing (project not indexed). Preserves graceful degradation. - AgDR-0056 records the decision + why the hook route (extend suggest-mcp-search into sub-agent contexts) was rejected for now (harness-level, can't see sub-agent tool calls). Prompt-level (self-discipline), mirroring how the main-loop rule already works. No agent-count change; site-counts unaffected. Closes #475 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
atlas-apex
left a comment
There was a problem hiding this comment.
Code Review: PR #477
Commit: 9ed71963a136a61c8a3b96e1583d6c1a8d277d8c
Summary
Makes the 7 code-reading sub-agents MCP-first (#475). Each agent definition gains mcp__apexyard-search__search_code + mcp__apexyard-search__search_docs on its tools/allowed-tools line, plus a consistent ## MCP-first code search prose block in its body. Adds docs/agdr/AgDR-0056-subagent-mcp-first.md recording the decision (prompt-level over hook-level, with the hook route explicitly rejected-for-now). No application code; docs/config only.
Checklist Results
- ✅ Architecture & Design: Pass — purely additive agent-metadata + prose; no layering concerns.
- ✅ Code Quality: Pass — no code; frontmatter well-formed.
- ✅ Testing: N/A — agent-definition docs; site-counts unaffected (no agent count change).
- ✅ Security: Pass —
security-reviewerkeepsdisallowedTools: Write, Edit; only read-class MCP tools added. - ✅ Performance: Pass — the change reduces token cost (semantic search over grep+Read).
- ✅ PR Description & Glossary: Pass — Summary, Testing, Glossary,
Closes #475, and AgDR marker all present. - ✅ Summary Bullet Narrative: Pass — every bullet is a bold-lead narrative sentence with verb + rationale.
- ✅ Technical Decisions (AgDR):Pass — AgDR-0056 included and referenced via
<!-- agdr: docs/agdr/AgDR-0056-subagent-mcp-first.md -->. - ✅ Adopter Handbooks: N/A — diff is
.md-only (agents + AgDR); no language handbooks load, and the always-load handbooks (clean-architecture, migration-safety, commit-quality) target application code, not framework docs.
Issues Found
None.
Verifications performed:
- Contamination check (model: lines):
grep -E '^[+-]\s*model:'against the full diff returns NOTHING. The unrelated local sonnet→opus overrides on backend/frontend-engineer were correctly excluded. ✅ Clean. - Frontmatter validity: each addition matches the file's existing key —
backend/frontend/data/platform/qaextendallowed-tools:;security-reviewerextendstools:(and keepsdisallowedTools: Write, Edituntouched). All remain valid comma-separated single-line lists; no YAML breakage. ✅ - MCP-first block consistency: identical wording across all 7, with two intentional role-specific tailorings —
tech-leadadds "(e.g. authoring a technical design against an existing service)" andsecurity-revieweradds "during a review". Both are appropriate, not drift. ✅ - Agent count: edits to existing agents only; no new/removed agent files →
test_site_counts.shunaffected. ✅ - AgDR-0056: follows the template (context / options / decision / consequences / artifacts), correctly documents why the hook route was rejected so a future maintainer doesn't re-investigate. ✅
CI Note (merge-time, not a code-review blocker)
lychee is currently red, but the failure is an unrelated external flake:
[500] https://claude.com/claude-codeindocs/getting-started.md— a file not touched by this PR, and a server-side 500 (transient), not a broken link introduced here.markdownlint-cli2✅ pass,Verify Ticket ID✅ pass.
This does NOT affect the code-review verdict. However, per .claude/rules/pr-quality.md § "No Red CI Before Merge", the merge gate will still block until CI is green. Before merge: re-run the lychee job (or wait for claude.com to recover) so all checks are green. Do not merge on red CI even though this failure is pre-existing and unrelated.
Verdict
APPROVED (code-review side). Re-run the flaky lychee check to green before merging.
🤖 Reviewed by Rex (Code Reviewer Agent)
📌 Reviewed commit: 9ed71963a136a61c8a3b96e1583d6c1a8d277d8c
The "use MCP search before grep" rule only reached the main loop (via suggest-mcp-search.sh + feedback memory); spawned sub-agents read managed-project code with grep+Read instead. Confirmed 2026-06-01: the tech-lead sub-agent authored a curios-dog design with zero search_code calls in activity.jsonl. - Add mcp__apexyard-search__search_code + search_docs to the tools/allowed-tools of the 7 code-reading agents: tech-lead, backend/frontend/data/platform-engineer, qa-engineer, security-reviewer (code-reviewer already had search_docs; solution-architect already had both — the reference implementation) - Add a consistent "## MCP-first code search" block to each agent body: prefer search_code/search_docs over grep+Read; fall back to grep only when MCP returns nothing (project not indexed). Preserves graceful degradation. - AgDR-0056 records the decision + why the hook route (extend suggest-mcp-search into sub-agent contexts) was rejected for now (harness-level, can't see sub-agent tool calls). Prompt-level (self-discipline), mirroring how the main-loop rule already works. No agent-count change; site-counts unaffected. Closes #475 Co-authored-by: me2resh <ahmed.abdelaliem@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
suggest-mcp-search.sh(which observes the main agent's Bash calls) + operator feedback memory. A spawned sub-agent runs its own loop with its own tools, so neither lever reached it. Confirmed 2026-06-01: thetech-leadsub-agent authored a curios-dog migration design entirely viagrep/Read— zerosearch_codecalls inactivity.jsonl.mcp__apexyard-search__search_code+search_docs) to thetools/allowed-toolsline oftech-lead,backend-engineer,frontend-engineer,data-engineer,platform-engineer,qa-engineer,security-reviewer. (code-revieweralready hadsearch_docs;solution-architectalready had both + the instruction — it's the reference implementation.)## MCP-first code searchblock to each agent body: prefersearch_code/search_docsovergrep+Read; fall back to grep only when MCP returns nothing (e.g. project not indexed). Graceful degradation preserved — adopters without MCP see unchanged behaviour.suggest-mcp-search.shinto sub-agent contexts needs harness-level tool-call interception the current PreToolUse plumbing can't do. Prompt-level (self-discipline) matches how the main-loop rule already works.devbefore editing); the diff is tools-line + MCP-block only.Testing
markdownlint-cli2(CI ruleset) — 0 errors on the 7 agents + AgDR-0056 (only MD060 from a newer-than-CI local linter, already firing repo-wide on pre-existing tables).model:line changes (contamination check) — onlyallowed-tools/toolsadditions + the MCP-first prose block.test_site_counts.shunaffected.search_codeentries inactivity.jsonl(companion staleness gap noted below).Note — companion gap (separate follow-up)
This PR fixes whether sub-agents use MCP. It does not address index staleness — nothing reindexes a workspace clone after
git pull/merge, sosearch_codecan returnnot_indexedor stale results even once agents prefer it. Filing a separate ticket for a post-pull reindex trigger; the two are companions (no point being MCP-first against a stale index).Glossary
mcp__apexyard-search__search_code/search_docsovergrep+Read, falling back to grep only when MCP returns nothing.search_codeentries for a code-reading run is the symptom this fixes.Closes #475