Summary
The Planner and Architect agents have zero tool access. When a user says "Fix issue #113", the Planner asks basic questions ("is this Svelte?", "what's the file path?") that it could answer by reading the workspace or fetching the GitHub issue. Both agents need read-only access to GitHub MCP and Filesystem MCP.
Problem
- Planner (
src/agents/planner.py) — bare ainvoke(), no tools. Asks the user for information it could look up.
- Architect (
architect_node in src/orchestrator.py) — single LLM call. Gets pre-fetched files from gather_context_node but can't explore further or fetch GitHub issues.
Solution
1. Tool filtering (src/tools/mcp_bridge.py)
Add tool_filter: set[str] | None to get_tools() with a READONLY_TOOLS constant (GitHub read + filesystem read tools). Prevents Planner/Architect from accessing write tools.
2. GitHub issue/PR pre-fetch (src/orchestrator.py — gather_context_node)
Detect issue/PR references in task descriptions using patterns:
- Issues:
(?:issue|fixes?|closes?|resolves?|refs?|see|review|address|gh)\s*#(\d+) (case-insensitive)
- PRs:
(?:pr|pull\s*request|pull)\s*#(\d+) (case-insensitive)
- Bare
#N intentionally excluded to avoid false matches (markdown headings, CSS colors)
Pre-fetch via GitHub issues API (covers both issues and PRs), inject full body into gathered_context — no arbitrary truncation.
3. Planner GitHub-context flow (src/agents/planner.py)
The implementation diverged from the originally-proposed conditional tool binding. PR #195 took a deterministic pre-fetch approach instead:
- On every turn, scan the user message for issue/PR refs (same regex family as gather_context).
- Pre-fetch matched refs via the GitHub REST API; store summaries on
TaskSpec.github_context.
- Inject summaries into a
=== PRE-FETCHED GITHUB CONTEXT === block in the Planner's system messages.
- The Planner LLM reads the block as ambient context — it never binds tools and never makes live API calls.
- Pass-through:
TaskSpec.github_context flows to the orchestrator on submit, preventing the Architect from re-fetching.
Subsequent PRs (#197, #198, #199) closed gaps discovered in manual smoke: system-prompt self-denial, anti-hallucination rules, repo-picker plumbing, git-remote auto-detection, and arbitrary body truncation.
4. Architect two-phase tool access (src/orchestrator.py)
- Phase 1 (no tools): Run as today with pre-fetched context (now includes GitHub issues + Planner pass-through)
- Phase 2 (tools, only if needed): If Blueprint is incomplete or references unknown files, re-invoke with
bind_tools(READONLY_TOOLS) + _run_tool_loop(max_turns=4)
Most tasks won't need Phase 2, avoiding tool schema tokens on every call.
5. MCP server lifecycle
- Planner providers closed after session submit
- Orchestrator spawns its own (shared across Architect/Dev/QA)
- Pass-through prevents redundant GitHub API calls
Acceptance Criteria
Shipped in
- #194 —
READONLY_TOOLS filter + GitHub issue/PR pre-fetch foundation
- #195 — Planner deterministic pre-fetch +
TaskSpec.github_context pass-through
- #196 — Architect two-phase read-only tool access
- #197 — Planner system-prompt reconciliation with pre-fetched context (fixed LLM self-denial)
- #198 —
github_repo plumbed end-to-end + git-remote auto-detect + anti-hallucination hardening
- #199 — Remove arbitrary issue-body truncation in pre-fetch (caps dropped context mid-AC)
Remaining work
All acceptance criteria green after #199 merges and the "Minimum height preserved (60px existing minimum is fine)" line reaches the Planner intact. Issue can close at that point.
Out of Scope
- Write tools for Planner/Architect
- Changing Architect output format (still JSON Blueprint)
- Streaming tool calls to dashboard
Depends On
Effort
Large (3+ sessions) — actual: 6 PRs across 2 sessions.
See comments for session-by-session progress notes and diagnostic details.
Summary
The Planner and Architect agents have zero tool access. When a user says "Fix issue #113", the Planner asks basic questions ("is this Svelte?", "what's the file path?") that it could answer by reading the workspace or fetching the GitHub issue. Both agents need read-only access to GitHub MCP and Filesystem MCP.
Problem
src/agents/planner.py) — bareainvoke(), no tools. Asks the user for information it could look up.architect_nodeinsrc/orchestrator.py) — single LLM call. Gets pre-fetched files fromgather_context_nodebut can't explore further or fetch GitHub issues.Solution
1. Tool filtering (
src/tools/mcp_bridge.py)Add
tool_filter: set[str] | Nonetoget_tools()with aREADONLY_TOOLSconstant (GitHub read + filesystem read tools). Prevents Planner/Architect from accessing write tools.2. GitHub issue/PR pre-fetch (
src/orchestrator.py—gather_context_node)Detect issue/PR references in task descriptions using patterns:
(?:issue|fixes?|closes?|resolves?|refs?|see|review|address|gh)\s*#(\d+)(case-insensitive)(?:pr|pull\s*request|pull)\s*#(\d+)(case-insensitive)#Nintentionally excluded to avoid false matches (markdown headings, CSS colors)Pre-fetch via GitHub issues API (covers both issues and PRs), inject full body into
gathered_context— no arbitrary truncation.3. Planner GitHub-context flow (
src/agents/planner.py)The implementation diverged from the originally-proposed conditional tool binding. PR #195 took a deterministic pre-fetch approach instead:
TaskSpec.github_context.=== PRE-FETCHED GITHUB CONTEXT ===block in the Planner's system messages.TaskSpec.github_contextflows to the orchestrator on submit, preventing the Architect from re-fetching.Subsequent PRs (#197, #198, #199) closed gaps discovered in manual smoke: system-prompt self-denial, anti-hallucination rules, repo-picker plumbing, git-remote auto-detection, and arbitrary body truncation.
4. Architect two-phase tool access (
src/orchestrator.py)bind_tools(READONLY_TOOLS)+_run_tool_loop(max_turns=4)Most tasks won't need Phase 2, avoiding tool schema tokens on every call.
5. MCP server lifecycle
Acceptance Criteria
get_tools()supportstool_filter;READONLY_TOOLSconstant defined (feat(tools): READONLY_TOOLS filter + GitHub issue/PR pre-fetch (#193 PR 1/3) #194)gather_context_nodedetects issue/PR refs and pre-fetches from GitHub API (feat(tools): READONLY_TOOLS filter + GitHub issue/PR pre-fetch (#193 PR 1/3) #194)PlannerStartRequestacceptsgithub_repo+workspace_type; dashboard sends both on start (fix(planner): plumb github_repo through API + auto-detect from git remote #198)PlannerSession.github_repo; pre-fetch uses it with env-var fallback (fix(planner): plumb github_repo through API + auto-detect from git remote #198)remote.origin.urlin.git/config(SSH + HTTPS) (fix(planner): plumb github_repo through API + auto-detect from git remote #198)#Nwarning (fix(planner): reconcile system prompt with pre-fetched GitHub context #197, fix(planner): plumb github_repo through API + auto-detect from git remote #198)max_chars=Noneis the default) (fix(tools): stop truncating GitHub issue bodies in pre-fetch #199)TaskSpec.github_contextpasses fetched data through to orchestrator (feat(planner): GitHub pre-fetch + pass-through to orchestrator (#193 PR 2) #195)READONLY_TOOLSonly) (feat(tools): READONLY_TOOLS filter + GitHub issue/PR pre-fetch (#193 PR 1/3) #194, feat(architect): two-phase read-only tool access (#193 PR 3) #196)Shipped in
READONLY_TOOLSfilter + GitHub issue/PR pre-fetch foundationTaskSpec.github_contextpass-throughgithub_repoplumbed end-to-end + git-remote auto-detect + anti-hallucination hardeningRemaining work
All acceptance criteria green after #199 merges and the "Minimum height preserved (60px existing minimum is fine)" line reaches the Planner intact. Issue can close at that point.
Out of Scope
Depends On
bind_tools()+_run_tool_loop()infra ✅Effort
Large (3+ sessions) — actual: 6 PRs across 2 sessions.
See comments for session-by-session progress notes and diagnostic details.