Skip to content

Commit 963dd00

Browse files
authored
FEAT-92: add revision summary feedback loop between Claude and Codex (#25)
* feat(code): add plan-with-codex debate loop for iterative plan refinement Introduces a Claude + Codex debate workflow where Claude drafts implementation plans and Codex reviews them in iterative rounds until approval or max rounds are reached. New components: - plan-agent: opus-model architect agent for plan creation/revision - plan-with-codex command: orchestrates the debate loop - codex-review skill: structured Codex review with verdict tokens - debate-loop.sh: standalone shell harness for the debate - plan-review.sh hook: triggers Codex review on ExitPlanMode * fix(code): refine plan-with-codex orchestration and agent resume - Add critical rule preventing orchestrator from editing plan directly - Switch agent resume to SendMessage with ToolSearch preload - Add explicit delegation for open question answers to plan-agent - Make Codex/Claude debate loop fully automated after user approval - Add mode=acceptEdits and run_in_background=false to Agent launches - Add AskUserQuestion, SendMessage, ToolSearch to allowed-tools * fix(code): improve codex review feedback formatting Structure each finding with a title, problem, and fix section instead of single long lines. * feat(code): add codex review logging and fix agent resume pattern - Add --log-id to run_codex_review.sh, raw JSON stream logged to ~/.closedloop-ai/plan-with-codex/<uuid>.jsonl across rounds - Switch from SendMessage to Agent(resume=) for plan-agent session continuity; add explicit rule to ignore SendMessage guidance - Add log cleanup prompt (30+ day old logs) at end of workflow - Fix dependency check ordering (before log setup) - Normalize LOG_ID:none and CODEX_SESSION:none sentinels to empty - Fix Step 1.5 stray code fence and SendMessage prose mismatch - Add self-check guardrails to plan-agent (goal alignment, scope, simplicity, reuse, tests) * fix(code): harden resume paths and fix codex review logging - Detect existing plan file without state and ask user to resume or start fresh; synthesize prompt sidecar from plan summary only when missing - Move prompt validation after existing-plan branch so resume path is reachable without a prompt argument - Normalize LOG_ID:none sentinel to empty in debate-loop.sh caller - Move dependency checks before log setup in run_codex_review.sh - Add LOG_ID to all SKILL.md output examples and usage snippet - Fix argument table: prompt optional when resuming existing plan * refactor(code): compress plan-with-codex prompt with extracted templates Apply context engineering principles to reduce token footprint ~35%: - Extract repeated agent-resume pattern into <templates> block (was 5x) - Extract state-write pattern into single template (was 4x) - Consolidate critical rules into <constraints> XML block - Merge vestigial Step 2e into 2d, renumber 2f to 2e - Fix stale-state STOP guard to allow fall-through on failed preconditions - Add explicit cross-session resume rule (no agent_id = launch fresh) - Preserve Codex session/log IDs in round-transition state writes * fix(code): skip redundant review gate when resuming existing plan When user chooses "resume with existing plan", go directly to the Codex debate loop after resolving open questions instead of stopping at the Step 1.5 user checkpoint. Update option text to match behavior. * feat(code): add revision summary feedback loop between Claude and Codex Plan-agent now verifies each Codex finding against the codebase before acting and writes a revision summary to a sidecar file with accepted changes and rejected findings with evidence. Codex reads this file on subsequent rounds so it does not re-raise findings that were validly rejected. * docs(code): update changelog and readme for v1.2.1 Add changelog entries for revision summary feedback loop, codex-review --revisions-file parameter, and plan-with-codex resume fix. Bump version to 1.2.1. Fix README hook description for plan-review.sh. * add github workflow to run tests * fix CI workflow: add missing deps and pyproject.toml config Install anthropic and mcp in CI so pyright/pytest can resolve all imports. Add pyproject.toml with ruff target-version and pyright pythonVersion set to py311. Run pull_request on all branches. * fix CI: add pytest to typecheck deps
1 parent 696c989 commit 963dd00

9 files changed

Lines changed: 96 additions & 14 deletions

File tree

.github/workflows/ci.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
8+
jobs:
9+
lint:
10+
name: Lint
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- uses: actions/setup-python@v5
15+
with:
16+
python-version: "3.13"
17+
- run: pip install ruff
18+
- run: ruff check .
19+
20+
typecheck:
21+
name: Type Check
22+
runs-on: ubuntu-latest
23+
steps:
24+
- uses: actions/checkout@v4
25+
- uses: actions/setup-python@v5
26+
with:
27+
python-version: "3.13"
28+
- run: pip install pyright pyyaml anthropic mcp pytest
29+
- run: pyright
30+
31+
test:
32+
name: Tests
33+
runs-on: ubuntu-latest
34+
steps:
35+
- uses: actions/checkout@v4
36+
- uses: actions/setup-python@v5
37+
with:
38+
python-version: "3.13"
39+
- run: pip install pytest pyyaml anthropic
40+
- run: pytest plugins/

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
66

77
## [Unreleased]
88

9+
### code v1.2.1
10+
11+
#### Changed
12+
- `plan-agent` now verifies Codex findings against the codebase before acting -- rejects findings that don't hold up with evidence, writes a revision summary for cross-round context
13+
- `codex-review` skill accepts `--revisions-file` parameter, injecting Claude's revision summary into Codex's prompt on rounds > 1 so rejected findings are not re-raised
14+
15+
#### Fixed
16+
- Fixed `plan-with-codex` resume path triggering a redundant user review checkpoint when the user had already confirmed by choosing "resume with existing plan"
17+
918
### code v1.2.0
1019

1120
#### Added

plugins/code/.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "code",
33
"description": "Code and planning framework plugin",
4-
"version": "1.2.0",
4+
"version": "1.2.1",
55
"author": {
66
"name": "ClosedLoop",
77
"email": "support@closedloop.ai"

plugins/code/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,9 @@ Implements the validation loop for agents registered in `loop-agents.json`. When
300300

301301
Injects tool-specific learnings just before tool execution. Filters `org-patterns.toon` by tool type (Bash patterns get build/test tags; Write/Edit patterns get language-specific tags based on file extension). Injects up to 10 matching patterns as `additionalContext`. Also auto-allows tool calls targeting `.closedloop-ai/` workspace paths without prompting.
302302

303-
### `plan-review.sh` (PostToolUse on ExitPlanMode)
303+
### `plan-review.sh` (not currently registered in `hooks.json`)
304304

305-
Triggers when Claude exits plan mode to get a second opinion via Codex. Extracts plan content from `tool_response.plan`, sends it to Codex (`gpt-5.3-codex-spark`) for review, and injects the feedback as `additionalContext` so Claude sees Codex's concerns inline. Exits silently if no plan content is present or Codex returns empty. Debug logs kept in `.closedloop-ai/plan-review-logs/` (max 15 files).
305+
Triggers when Claude exits plan mode to get a second opinion via Codex. Extracts plan content from `tool_response.plan`, sends it to Codex (`gpt-5.3-codex-spark`) for review, and injects the feedback as `additionalContext` so Claude sees Codex's concerns inline. Exits silently if no plan content is present or Codex returns empty. Debug logs kept in `.closedloop-ai/plan-review-logs/` (max 15 files). This script exists in `hooks/` but is not wired into `hooks.json` -- it would require a PostToolUse entry matching ExitPlanMode to activate.
306306

307307
### `validate-plan.sh` (validation script, not a hook directly)
308308

plugins/code/agents/plan-agent.md

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,21 @@ Structure plans with these sections:
8888
When given feedback to address:
8989

9090
1. Read the current plan file and the feedback file
91-
2. Address ALL concerns raised in the feedback
92-
3. If you disagree with a point, note your reasoning in the plan but still consider the underlying concern
93-
4. If the reviewer proposed a concrete fix, adopt it directly unless you have a strong reason not to
91+
2. **Verify each finding against the codebase before acting on it.** Use `Grep`, `Glob`, and `Read` to check whether the reviewer's claims are accurate (e.g., does the file/function they reference actually exist? Is the behavior they describe real?). Reviewers can hallucinate or misunderstand the codebase.
92+
3. For verified findings: address the concern. If the reviewer proposed a concrete fix, adopt it directly unless you have a strong reason not to.
93+
4. For findings that don't hold up: reject them with a brief explanation and evidence (e.g., "Finding 2 claims X is missing, but `path/to/file:42` already implements it").
9494
5. Write the updated plan back to the same file path using the `Write` tool
95+
6. **If a revisions file path was provided**, write a revision summary to it. Format:
96+
97+
```markdown
98+
## Round N Revisions
99+
100+
### Accepted
101+
- **Finding 1** (title): [what changed in the plan]
102+
- **Finding 3** (title): [what changed in the plan]
103+
104+
### Rejected
105+
- **Finding 2** (title): [why, with evidence -- e.g., "X already exists at `path/to/file:42`"]
106+
```
107+
108+
This file is read by the reviewer on the next round so they have full context on what was addressed and what was pushed back on.

plugins/code/commands/plan-with-codex.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ Arguments: $ARGUMENTS
6161

6262
Derive sidecar paths from the plan file stem (e.g., for `debate-plan.md`):
6363
- `{stem}.feedback` -- Codex feedback text
64+
- `{stem}.revisions` -- Claude's revision summary (changes made + pushback on rejected findings)
6465
- `{stem}.state` -- phase/round/session state
6566
- `{stem}.prompt` -- original prompt (plain text)
6667

@@ -185,6 +186,7 @@ Activate `code:codex-review` skill and run:
185186
bash <base_directory>/scripts/run_codex_review.sh \
186187
--plan-file {plan-file-abs} \
187188
--feedback-file {feedback-file-abs} \
189+
--revisions-file {revisions-file-abs} \
188190
--round {N} \
189191
--codex-model {codex-model} \
190192
[--session-id {codex_session_id}] \
@@ -213,7 +215,7 @@ Update TodoWrite: "Round {N}/{max}: Revising plan..."
213215

214216
Resume the plan-agent:
215217
- description: "Revise plan based on Codex feedback"
216-
- prompt: "Revise the plan at {plan-file-abs} based on feedback at {feedback-file-abs}. Address ALL concerns raised."
218+
- prompt: "Revise the plan at {plan-file-abs} based on feedback at {feedback-file-abs}. Verify each finding against the codebase before acting on it -- reject any that don't hold up. After updating the plan, write a revision summary to {revisions-file-abs}."
217219

218220
Verify plan was updated. Write state: `ROUND={N+1}, PHASE=codex_review`, preserve current `CODEX_SESSION_ID` and `LOG_ID`. Continue to next round.
219221

@@ -226,7 +228,7 @@ Report outcome:
226228

227229
Clean up ALL sidecar files (prompt sidecar deleted intentionally to prevent stale intent on future runs):
228230
```bash
229-
rm -f {state_file} {feedback_file} {prompt_file}
231+
rm -f {state_file} {feedback_file} {revisions_file} {prompt_file}
230232
```
231233

232234
Update TodoWrite: mark all remaining items completed.

plugins/code/skills/codex-review/SKILL.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ The `scripts/` directory is relative to this skill's base directory (shown above
2424
bash <base_directory>/scripts/run_codex_review.sh \
2525
--plan-file <path> \
2626
--feedback-file <path> \
27+
--revisions-file <path> \
2728
--round <N> \
2829
--codex-model <model> \
2930
[--session-id <thread_id>] \
@@ -34,6 +35,7 @@ bash <base_directory>/scripts/run_codex_review.sh \
3435
|----------|----------|---------|-------------|
3536
| `--plan-file` | Yes | -- | Absolute path to the plan file Codex should review |
3637
| `--feedback-file` | Yes | -- | Path where full feedback text will be written |
38+
| `--revisions-file` | No | -- | Path to Claude's revision summary (accepted/rejected findings). If present and round > 1, Codex reads it for context. |
3739
| `--round` | No | 1 | Current debate round (affects review prompt intro) |
3840
| `--codex-model` | No | gpt-5.4 | Codex model to use |
3941
| `--session-id` | No | -- | Thread ID from a previous round for session resume |

plugins/code/skills/codex-review/scripts/run_codex_review.sh

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,21 @@ set -euo pipefail
2424

2525
PLAN_FILE=""
2626
FEEDBACK_FILE=""
27+
REVISIONS_FILE=""
2728
ROUND=1
2829
CODEX_MODEL="gpt-5.4"
2930
SESSION_ID=""
3031
LOG_ID=""
3132

3233
while [[ $# -gt 0 ]]; do
3334
case $1 in
34-
--plan-file) PLAN_FILE="$2"; shift 2 ;;
35-
--feedback-file) FEEDBACK_FILE="$2"; shift 2 ;;
36-
--round) ROUND="$2"; shift 2 ;;
37-
--codex-model) CODEX_MODEL="$2"; shift 2 ;;
38-
--session-id) SESSION_ID="$2"; shift 2 ;;
39-
--log-id) LOG_ID="$2"; shift 2 ;;
35+
--plan-file) PLAN_FILE="$2"; shift 2 ;;
36+
--feedback-file) FEEDBACK_FILE="$2"; shift 2 ;;
37+
--revisions-file) REVISIONS_FILE="$2"; shift 2 ;;
38+
--round) ROUND="$2"; shift 2 ;;
39+
--codex-model) CODEX_MODEL="$2"; shift 2 ;;
40+
--session-id) SESSION_ID="$2"; shift 2 ;;
41+
--log-id) LOG_ID="$2"; shift 2 ;;
4042
*)
4143
echo "Unknown option: $1" >&2
4244
exit 1
@@ -80,14 +82,22 @@ prompt_file="$tmp_dir/prompt.txt"
8082

8183
# ── Build the review prompt ──────────────────────────────────────────────────
8284

85+
REVISIONS_BLOCK=""
8386
if [[ "$ROUND" -eq 1 ]]; then
8487
REVIEW_INTRO="Claude has created an implementation plan. Review it and provide feedback."
8588
else
8689
REVIEW_INTRO="Claude has addressed your previous feedback and updated the plan. Re-review the plan for remaining issues."
90+
if [[ -n "$REVISIONS_FILE" ]] && [[ -s "$REVISIONS_FILE" ]]; then
91+
REVISIONS_BLOCK="
92+
93+
Claude's revision summary (including any findings that were rejected with evidence) is at: ${REVISIONS_FILE}
94+
Read it before reviewing the plan -- if Claude rejected a finding with valid evidence, do not re-raise it."
95+
fi
8796
fi
8897

8998
cat > "$prompt_file" <<PROMPT_EOF
9099
${REVIEW_INTRO}
100+
${REVISIONS_BLOCK}
91101
92102
Read the plan at: ${PLAN_FILE}
93103

pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[tool.ruff]
2+
target-version = "py311"
3+
4+
[tool.pyright]
5+
pythonVersion = "3.11"

0 commit comments

Comments
 (0)