Section 01: Design Pre-Read
Status: Not Started Goal: Establish a fully-resolved design surface so that §03 (the rewrite) becomes a mechanical edit. Every Agent() call site is identified by line number with a concrete Bash replacement shape; every open design question carries a written, justified answer; the load-bearing reviewer-set SSOT invariant I28 is named so the rewrite cannot drift past it.
Success Criteria:
- Audit table in §01.1 enumerates every
Agent({...})site intpr-review/SKILL.mdwith line numbers + replacement shape - §01.2 carries a written resolution for Q1, Q2, Q3, Q4 from
00-overview.md - I28 (reviewer-set SSOT) is named as a preserved invariant with one concrete code-shape constraint
- Connects upward to mission criteria: “no Agent({subagent_type:…, model:‘sonnet’}) calls” + “wall-clock parity” + “convergence behavior preserved”
Context: Plan was filed 2026-04-25 immediately after extract-report.py SSOT’d Tier 0–5 extraction out of the sub-agent. The sub-agent’s remaining responsibilities (CLI invocation, retry, transport-failure surface) are bash- and orchestrator-tractable in main context. This section pins the design surface so §03 can be a localized rewrite rather than an exploratory edit.
Reference implementations:
.claude/skills/tpr-review/SKILL.md §5 Round loop— current orchestration loop body (lines ~211–547).claude/skills/tpr-review/SKILL.md §8 Parallel dispatch— current dispatch template (lines ~624–767).claude/skills/tpr-review/SKILL.md §9 Failure handling— current 3-shape sub-agent transport surface (lines ~769–793).claude/skills/tpr-review/tp_agent_prompt.md §Step 3.5— bounded one-retry gate that lifts into the orchestrator.claude/skills/tpr-review/extract-report.py— the Tier 0–5 SSOT that obsoletes the sub-agent layer
Depends on: None (Phase 0 prerequisite).
Intelligence Reconnaissance
Queries run 2026-04-25:
scripts/intel-query.sh status— graph is available (Neo4j 5.26.24; 191,312 Symbol nodes + 505,418 CALLS edges across 11 indexed repos includingoriat 32,446 symbols). Recorded as proof of protocol.- Surface-applicability note: the modified surface is
.claude/skills/tpr-review/(markdown + Python + bash). The Ori code-symbol index covers Rust crates only; this plan touches no Rust crate, so symbol-level queries (callers/callees/file-symbols/similar) return no actionable signal for the dispatch-shape rewrite. The graph IS available but NOT APPLICABLE to the surface — recording the unavailability-of-applicability as freeform prose per schema’s Recon-block contract. - Surrogate query (grep, run inside repo root):
grep -n "Agent(" .claude/skills/tpr-review/SKILL.md→ 4 hits (one description in §8c prose, threeAgent({...})examples in the canonical template at lines 688/696/704).
Results summary (≤500 chars) [repo:.claude/skills/tpr-review/SKILL.md]: TPR Agent dispatch is concentrated in §8c (3 call sites at lines 688/696/704) and described prosely in §5 (round loop) + §9 (3-shape transport contract); replacement surface bounded to ~80 lines of edits plus deletion of tp_agent_prompt.md [repo:.claude/skills/tpr-review/tp_agent_prompt.md]. extract-report.py already encapsulates the high-risk extraction logic [repo:.claude/skills/tpr-review/extract-report.py] — sub-agent removal is mechanical from this point. No [ori] graph-resident symbols touch this surface.
See .claude/skills/query-intel/compose-intel-summary.md for the full query protocol (SSOT — informational reference; this plan touches no Rust crate).
01.1 Audit existing dispatch path
File(s): .claude/skills/tpr-review/SKILL.md (read-only audit; no edits in this subsection)
The audit captures the exact replacement points so §03’s rewrite is a mechanical edit, not exploratory.
-
Build dispatch-site table. Audit completed against
tpr-review/SKILL.mdHEAD on 2026-04-25:| § | Line(s) | Reviewer | Replacement shape | |------|-----------|----------|------------------------------------------------------------------| | §8c | 688–694 | codex | Bash(bash invoke-codex.sh "$scratch", timeout: 2700000) | | | | | → Bash(python3 extract-report.py "$scratch" --reviewer codex) | | | | | → Read($scratch/codex-report.txt) | | §8c | 696–702 | gemini | Bash(bash invoke-gemini.sh "$scratch", timeout: 2700000) | | | | | → Bash(python3 extract-report.py "$scratch" --reviewer gemini) | | | | | → Read($scratch/gemini-report.txt) | | §8c | 704–710 | opencode | Bash(bash invoke-opencode.sh "$scratch", timeout: 2700000) | | | | | → Bash(python3 extract-report.py "$scratch" --reviewer opencode)| | | | | → Read($scratch/opencode-report.txt) |All three sites carry
subagent_type: "general-purpose"(lines 689 / 697 / 705) andmodel: "sonnet"(lines 690 / 698 / 706) — both fields drop in the rewrite (no sub-agent invocation remains). Theprompt: <contents of tp_agent_prompt.md ...>field on each (lines 692 / 700 / 708) becomes irrelevant oncetp_agent_prompt.mdis deleted in §04.1. -
§8c structural touchpoints (PRE-FLIGHT GATE + dispatch shape). Edits beyond the three Agent blocks:
| Line | Current text | Replacement | |-------|-------------------------------------------------------------------------|----------------------------------------------------------------------------| | 657 | "Dispatch ALL THREE reviewers as three `Agent()` tool calls in a SINGLE" | "Dispatch ALL THREE reviewers as `len(REVIEWERS)` foreground `Bash` tool calls in a SINGLE" | | 663 | "Before emitting §8c's Agent() calls, verify ALL Agent() calls" | "Before emitting §8c's Bash() dispatch calls, verify ALL Bash() dispatch calls" | | 665 | "Required Agent count in the dispatch message: EXACTLY `len(REVIEWERS)` Agent() calls" | "Required Bash count in the dispatch message: EXACTLY `len(REVIEWERS)` Bash() calls" | | 667 | "the §11.P pre-dispatch status text FIRST (≤2 lines, mandatory), then (2) EXACTLY `len(REVIEWERS)` Agent calls" | "...EXACTLY `len(REVIEWERS)` Bash dispatch calls" | | 671–675 | Diagram with `Agent({ ...reviewer[N-1]... })` | Diagram with `Bash({ command: 'bash invoke-${REVIEWERS[N-1]}.sh "$scratch"', timeout: 2700000 })` | | 681 | "re-dispatches the SAME Agent set" | "re-dispatches the SAME Bash set" | | 683–685 | "Sub-agents are thin CLI transports with split concerns: ... CLI invocation is NOT in the sub-agent prompt ... Stream-json extraction + retry DOES live in the sub-agent" | Replaced by the §03.1 paragraph: "Each Bash call invokes the per-reviewer wrapper `invoke-{R}.sh` which runs the CLI and tees stdout to `$scratch/{R}-stdout.txt`. Wall-clock per round is `max({R0}, {R1}, {RN-1})` — the harness runs parallel tool calls concurrently. After all Bash calls return, see step 8c.1 for extraction." | | 713 | "the sub-agent prompt carries ONLY `{REVIEWER}`, `{SCRATCH_DIR}`, and `{MODE}` placeholders" | DELETE — no sub-agent prompt; placeholders no longer exist | -
§5 round-loop touchpoints. Five lines mention sub-agent transport:
| Line | Current | Replacement | |-------|-------------------------------------------------------------------------|----------------------------------------------------------------------------| | 143 | "→ §8c Agent sub-agent dispatch → §9 status triage → extraction" | "→ §8c Bash dispatch → §8c.1 extract → §9 status triage" | | 168 | "# §8c dispatch — SAME path as review mode: three Agent sub-agents in ONE message." | "# §8c dispatch — SAME path as review mode: `len(REVIEWERS)` foreground Bash calls in ONE message." | | 169 | `[codex_out, gemini_out, opencode_out] = dispatch_parallel_thin_transports($scratch)` | Inline expansion: `dispatch_parallel_bash($scratch)` → `extract_per_reviewer($scratch)` → `read_per_reviewer_report($scratch)` | | 272 | "# ── Parallel dispatch (thin-transport sub-agents, Sonnet) ──" | "# ── Parallel dispatch (foreground Bash, harness-concurrent) ──" | | 277 | "# no reinterpretation. See tp_agent_prompt.md." | DELETE — `tp_agent_prompt.md` is removed in §04.1 | | 278 | `[codex_out, gemini_out, opencode_out] = dispatch_parallel_thin_transports($scratch)` | Inline expansion same as line 169 | | 793 | "Mid-round retry is still permitted at the sub-agent level per `tp_agent_prompt.md §Step 3.5`" | "Mid-round retry is still permitted at the orchestrator level per §8c.2 (one retry per reviewer per round)" | -
§9 transport-shape touchpoints. Three rows preserved (lines 775–777:
ok/partial/failed); ONE row removed (line 778: “Sub-agent contract violation”); opener (line 771) and footer (line 793) edited:| Line | Current | Replacement | |-------|-------------------------------------------------------------------------|----------------------------------------------------------------------------| | 771 | "Each reviewer sub-agent returns EXACTLY ONE of three status shapes... The sub-agent owns internal retry, liveness, stdout flattening..." | "Each reviewer's `extract-report.py` invocation produces EXACTLY ONE of three status shapes... The orchestrator's §8c.2 retry gate handles transport failures inline." | | 775 | "(sub-agent Tier 1–4 extraction)" | "(extract-report.py Tier 1–4 extraction)" | | 776 | "(sub-agent Tier 4.5 after 2 attempts)" | "(extract-report.py Tier 4.5 after orchestrator's §8c.2 retry)" | | 777 | "Two sub-agent attempts produced no extractable content (Tier 5 twice)" | "Two extract-report.py attempts produced no extractable content (Tier 5 twice)" | | 778 | "**Sub-agent contract violation** (defensive default — NOT a valid return shape)" row | **DELETE** — no sub-agent → no I22 vector. Replaced by a short paragraph above the table: "Bash-layer transport failures: a reviewer's foreground Bash call may exit non-zero; `extract-report.py` may exit 2 (invocation error). Both surface as `status: failed`; survivor matrix below applies unchanged." | -
§11.P pre-dispatch banner touchpoints. The wall-clock envelope text is preserved verbatim; only the tool-name swaps:
| Line | Current | Replacement | |-------|-------------------------------------------------------------------------|----------------------------------------------------------------------------| | 874 | "Status text MUST precede the Agent tool calls in the same assistant message" | "Status text MUST precede the Bash dispatch calls in the same assistant message" | | 876 | "The orchestrator MUST NOT use the `Monitor` tool. The sub-agent three-status-shape return (§9) is the sole transport-failure surface." | "The orchestrator MUST NOT use the `Monitor` tool. The `extract-report.py` three-status-shape output (§9) is the sole transport-failure surface." | -
§1 frontmatter description + skill-body opening prose. Three lines mention sub-agents in the prelude:
| Line | Current | Replacement | |-------|-------------------------------------------------------------------------|----------------------------------------------------------------------------| | 14 | "Dispatches the **codex**, **gemini**, and **opencode** CLIs as parallel sub-agents per round" | "Dispatches the **codex**, **gemini**, and **opencode** CLIs as parallel foreground Bash calls per round, with `extract-report.py` extracting reports inline" | | 16 | "Sub-agents (Sonnet) are thin CLI transports: read the pre-composed prompt, invoke the CLI, run `extract-report.py` ... and return that block" | "The orchestrator (Opus, main context) dispatches per-reviewer wrappers via foreground Bash, runs `extract-report.py` inline, reads the small produced `report.txt`, and feeds the block to §9 status triage" | | 20 | "Opus owns all interpretation (prompt composition, finding verification, convergence judgment). Sonnet sub-agents own transport mechanics only" | "Opus owns all interpretation (prompt composition, finding verification, convergence judgment). Bash + extract-report.py own transport mechanics only" | | 89 | "Orchestrator-side grounding is MINIMAL — reviewer sub-agents self-ground" | "Orchestrator-side grounding is MINIMAL — reviewer CLIs self-ground per `compose-round-prompt.md`'s grounding block" | -
allowed-toolsfrontmatter (line 5). Today:Read, Write, Edit, Bash, Glob, Grep, Agent, Skill. Audit of remainingAgentuse post-rewrite: §5.5 tie-breaker invokes/independent-reviewviaSkill({skill: "independent-review", ...})(line 444), NOT via Agent. No other Agent call survives. Action in §03.4: dropAgentfromallowed-tools→Read, Write, Edit, Bash, Glob, Grep, Skill. -
Subsection close-out (01.1) — MANDATORY before starting 01.2:
- All audit tables produced and embedded above (six tables: dispatch sites, §8c structure, §5 round-loop, §9 transport-shape, §11.P banner, §1 frontmatter + skill-body, allowed-tools)
- Update this subsection’s
statusin section frontmatter tocomplete - Repo hygiene check —
compiler_repo/diagnostics/repo-hygiene.sh --checkreturnedrepo-hygiene: cleanon 2026-04-25
01.2 Resolve open design questions
File(s): This section file (resolutions filed inline below)
The four open questions in 00-overview.md §Open Design Questions each get a written, justified answer here. Resolutions are load-bearing inputs to §03’s rewrite.
Q1 — Retry contract
Question: Sub-agent currently does ONE bounded retry on Tier 4.5/5 (per tp_agent_prompt.md §Step 3.5). Should the orchestrator do the same, or is one shot sufficient given the script’s robustness?
Decision (recommended path): Keep ONE bounded retry, lifted into the orchestrator. ~10 lines of orchestrator logic. Same trigger (extract-report.py exit 1 with tier 4.5 or tier 5 on first attempt), same recovery (re-invoke bash invoke-{R}.sh "$scratch" + re-run extract-report.py), same disposition (use the better of two attempts).
Rationale: The retry covers a genuine failure class (wrapper exit 0 with insufficient output — cold-start timeout, deep-investigation overrun mid-emission) that the wrapper’s internal 429-retry loop does not catch. Removing retry would regress empirically-observed recovery on this class. The cost (~10 lines) is trivial and the logic is more inspectable in main context than buried in the sub-agent prompt.
Banned alternative: Doubling the retry budget “since it’s cheap now”. The sub-agent’s current 1-retry cap reflects the 2026-04-22 finding that persistent failures beyond one retry are infrastructure-level (auth expired, CLI outage) and not fixed by additional attempts.
Q2 — Wait mechanism for parallel dispatch
Question: How does the orchestrator detect the wrappers’ completion? wait builtin? Polling for stdout file growth stopping? run_in_background: true + Monitor?
Decision (recommended path): Use the harness’s native parallel-tool-call concurrency. Three foreground Bash tool uses in ONE assistant message — exactly mirroring today’s three foreground Agent calls in one message. No Monitor, no run_in_background, no wait builtin, no polling.
Rationale: The Claude Code harness already runs parallel tool calls concurrently when emitted in a single assistant message — this is the same mechanism that gives today’s Agent dispatch its max(codex, gemini, opencode) wall-clock. Foreground Bash calls inherit this property. Wall-clock parity is automatic. No new wait infrastructure is introduced.
Concrete shape (used by §03’s rewrite):
<assistant message begin>
<§11.P status text — ≤2 lines>
Bash({ command: 'bash .claude/skills/tpr-review/invoke-codex.sh "$scratch"', timeout: 2700000 })
Bash({ command: 'bash .claude/skills/tpr-review/invoke-gemini.sh "$scratch"', timeout: 2700000 })
Bash({ command: 'bash .claude/skills/tpr-review/invoke-opencode.sh "$scratch"', timeout: 2700000 })
<assistant message end>
The harness does not return control until all three Bash calls have terminated with concrete exit codes. After that single round-trip, the next assistant message issues the three extract-report.py Bash calls (also parallel, fast — they read disk files) and three Read calls (also parallel). Total: three turns per round of effective work, identical to today’s count (one for dispatch, one for extraction, one for Read).
Banned alternative: run_in_background: true. The user’s “foreground mandatory in sequential review pipelines” rule (incident 2026-04-15) is stated for Agent dispatches but the spirit applies — backgrounded waits surface as cache-busting notification turns instead of clean parallel completion. The harness’s native concurrency is the right primitive.
Q3 — Skill() invocation chain compatibility
Question: /review-plan Step 6, /fix-bug Phase 1.75, /tp-help, and /create-plan Step 6B/8B currently invoke /tpr-review as a Skill() call. Does that still work when /tpr-review no longer dispatches sub-agents?
Decision (recommended path): Yes, unchanged. Skill() runs the orchestrator’s body inline in the parent’s context regardless of whether that body internally dispatches sub-agents or runs Bash directly. No caller-side change.
Rationale: A Skill() call’s contract is “execute this skill’s protocol; return its terminal state”. The skill’s internal transport choices (Agent vs. Bash vs. inline computation) are encapsulated below the Skill boundary. Today’s parent already absorbs the per-reviewer 16 KB report block when the orchestrator’s §11 round summary surfaces. Tomorrow’s parent absorbs the same 16 KB-per-reviewer reports via inline Read rather than via Agent return — same content, same bound, lower scaffolding overhead.
Verification approach (filed as §04.3 corpus replay): Run a representative /review-plan Step 6 invocation through the rewritten skill against an existing plan section. Confirm the returned exit_reason, rounds_completed, last_round_commit, last_round_findings, ever_verified_findings structured-exit fields match what callers expect per review-plan/SKILL.md §Step 1d.
Q4 — Monitor contract simplification
Question: Does removing sub-agents simplify or complicate the §11.P Monitor contract?
Decision: No change required — Monitor was already excised in the 2026-04-24 entry of tpr-review-design.md §6. The current §11.P carries a pre-dispatch chat status message only; there is no Monitor invocation to remove or refactor. The wall-clock envelope (“~20–45 min wall-clock, worst-case ~45 min with gemini 429 retries”) is preserved verbatim — wrappers run unchanged.
Side note: The §11.P prose currently says “main chat stays quiet until Agents return”. After the rewrite this becomes “main chat stays quiet until Bash calls return”. One-word swap, captured in §03.4.
Reviewer-set SSOT (I28) — preserved invariant
The rewrite MUST preserve I28: only /tpr-review internals + invoke-{REVIEWER}.sh wrappers + design-log §4 Lessons may name specific reviewers (codex / gemini / opencode). Every other consumer uses “third-party reviewer set” / “each reviewer” / sentinel-by-name parsing.
Concrete code-shape constraint for §03: The orchestrator’s dispatch loop MUST iterate a REVIEWERS variable (or the equivalent SSOT in SKILL.md’s pseudocode) and emit len(REVIEWERS) Bash tool calls per round — never a hardcoded 3-call template per reviewer name. The Per-FLIGHT GATE in §8c stays SSOT-driven: “Required Bash count in the dispatch message: EXACTLY len(REVIEWERS) Bash() calls (one per reviewer in the current reviewer set).”
This mirrors today’s Agent-call SSOT shape and inherits the same property — adding/removing a reviewer is a one-file change in /tpr-review.
- Subsection close-out (01.2) — MANDATORY before starting 01.N:
- All four resolutions (Q1–Q4) are written above with recommended path + rationale
- I28 preservation constraint named with concrete code-shape rule (orchestrator iterates
REVIEWERS; PRE-FLIGHT GATE countslen(REVIEWERS)Bash calls) - Update this subsection’s
statusin section frontmatter tocomplete - Repo hygiene check — clean (same probe as §01.1 close-out)
01.N Completion Checklist
- §01.1 audit table embedded with line numbers + replacement shapes for every
Agent({...})site (six tables — dispatch sites, §8c structure, §5 round-loop, §9 transport-shape, §11.P banner, §1 frontmatter, allowed-tools) - §01.2 resolutions for Q1, Q2, Q3, Q4 are written and named (recommended path called out for each)
- I28 preservation constraint named with one concrete code-shape rule for §03 (loop over
REVIEWERS; never hardcode 3 calls) - Both subsections marked
status: completein section frontmatter -
python -m scripts.plan_corpus check plans/inline-tpr-transport/section-01-design-pre-read.mdreturns exit 0 (verified 2026-04-25) -
./test-all.shgreen — regression canary (deferred to §04.N — no source files touched in §01; running test-all.sh per-section is wasteful for an audit-only section) - Plan sync — update plan metadata:
- This section’s frontmatter
status→complete, all subsection statuses →complete -
00-overview.mdQuick Reference: §01 status →Complete -
00-overview.mdmission success criteria: no §01-derived criteria satisfied yet (criteria fire on §03 / §04 work) -
index.md§01 status →Complete
- This section’s frontmatter
- Repo hygiene check — clean
Exit Criteria: §01.1 produced a complete dispatch-site audit table; §01.2 records four written resolutions plus the I28 constraint; python -m scripts.plan_corpus check plans/inline-tpr-transport/section-01-design-pre-read.md exits 0. MET 2026-04-25.