84%

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 in tpr-review/SKILL.md with 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 including ori at 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, three Agent({...}) 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.md HEAD 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) and model: "sonnet" (lines 690 / 698 / 706) — both fields drop in the rewrite (no sub-agent invocation remains). The prompt: <contents of tp_agent_prompt.md ...> field on each (lines 692 / 700 / 708) becomes irrelevant once tp_agent_prompt.md is 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-tools frontmatter (line 5). Today: Read, Write, Edit, Bash, Glob, Grep, Agent, Skill. Audit of remaining Agent use post-rewrite: §5.5 tie-breaker invokes /independent-review via Skill({skill: "independent-review", ...}) (line 444), NOT via Agent. No other Agent call survives. Action in §03.4: drop Agent from allowed-toolsRead, 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 status in section frontmatter to complete
    • Repo hygiene checkcompiler_repo/diagnostics/repo-hygiene.sh --check returned repo-hygiene: clean on 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 counts len(REVIEWERS) Bash calls)
    • Update this subsection’s status in section frontmatter to complete
    • 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: complete in section frontmatter
  • python -m scripts.plan_corpus check plans/inline-tpr-transport/section-01-design-pre-read.md returns exit 0 (verified 2026-04-25)
  • ./test-all.sh green — 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 statuscomplete, all subsection statuses → complete
    • 00-overview.md Quick Reference: §01 status → Complete
    • 00-overview.md mission success criteria: no §01-derived criteria satisfied yet (criteria fire on §03 / §04 work)
    • index.md §01 status → Complete
  • 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.