fix(issue-25): reuse a promoted plan only with --plan-file; drop the implicit newest-plan load
Without --plan, Phase 1 resolved a planner session automatically and globbed <workspace_root>/.agents/reports/<planner>/plan-*.md for the newest file by mtime, handing it to the Creator as "the plan already agreed on". Both keys are wrong: the report directory belongs to a session, not to this task, so other issues' plans pile up in it, and right after a clone or checkout mtime is checkout order. 47 such plans are committed in this repository, so an ordinary run could silently implement against an unrelated design. Reuse is explicit now. --plan-file <path> is the only way to load an existing plan; it is resolved against the control root, checked before a single job exists, and refused if the file is missing, not a regular file, unreadable or empty (an empty file would quietly turn into a "no plan" prompt). It cannot be combined with --plan, and --review-only warns and ignores it because no implementation job is delegated there. The implementation prompt itself is unchanged, so the Creator's contract does not move. Phase 1 now says which plan it loaded and where from, or that it loaded none. The legacy shell loop (MAM_LOOP_PY=0) loses the same auto-load and rejects --plan-file rather than duplicating the check on a path that is on its way out. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6fc9194f89
commit
a28711cccf
2 files changed
+67
-18
No files matched your search
@@ -32,6 +32,7 @@ TARGET_AGENT=""
|
||||
TASK=""
|
||||
REVIEWER_LIST=""
|
||||
PLANNER_SESSION_OVERRIDE=""
|
||||
LOOP_PLAN_FILE=""
|
||||
LOOP_WORKTREE=""
|
||||
LOOP_BASE=""
|
||||
LOOP_REVIEW_ONLY=0
|
||||
@@ -46,6 +47,7 @@ usage() {
|
||||
echo " --plan Enable Planner agent intervention & design phase"
|
||||
echo " --planner <name> Planner session (requires --plan; default: auto-resolve)"
|
||||
echo " --plan-talk N Planner-Creator discussion limit turns (default: 1)"
|
||||
echo " --plan-file <path> Reuse an existing plan file, relative to the control root (not with --plan)"
|
||||
echo " --reviewer \"A,B\" Targeted reviewer session name list (comma-separated)"
|
||||
echo " --all-reviewer Enforce PASS verdict from all active reviewer sessions"
|
||||
echo " --max-loop N Max execution-review corrective loop runs (default: 3)"
|
||||
@@ -92,6 +94,7 @@ while [[ "$#" -gt 0 ]]; do
|
||||
exit 1
|
||||
;;
|
||||
--planner) PLANNER_SESSION_OVERRIDE="$2"; shift 2 ;;
|
||||
--plan-file) LOOP_PLAN_FILE="$2"; shift 2 ;;
|
||||
--task) TASK="$2"; shift 2 ;;
|
||||
--worktree) LOOP_WORKTREE="$2"; shift 2 ;;
|
||||
--base) LOOP_BASE="$2"; shift 2 ;;
|
||||
@@ -121,11 +124,14 @@ fi
|
||||
|
||||
# Issue #21 (D12): the legacy shell loop assumes a cwd-relative .mam/jobs and
|
||||
# diffs the checkout it runs in; the worktree/base options are Python-only.
|
||||
# Issue #25 (D9): --plan-file is too - its fail-closed check lives in the
|
||||
# runner and is not duplicated in a path that is on its way out.
|
||||
# Checked before the freeze and the loop lock (log_* are not defined yet).
|
||||
if [ "${MAM_LOOP_PY:-1}" = "0" ] && { [ -n "$LOOP_WORKTREE" ] || [ -n "$LOOP_BASE" ] \
|
||||
|| [ "$LOOP_REVIEW_ONLY" = "1" ] || [ -n "${MAM_LOOP_WORKTREE:-}" ] \
|
||||
|| [ -n "$LOOP_REVIEW_ISOLATION" ] || [ -n "$LOOP_REMOTE_REVIEW" ]; }; then
|
||||
echo "ERROR: --worktree/--base/--review-only/--review-isolation/--remote-review require the Python loop (MAM_LOOP_PY=1)" >&2
|
||||
|| [ -n "$LOOP_REVIEW_ISOLATION" ] || [ -n "$LOOP_REMOTE_REVIEW" ] \
|
||||
|| [ -n "$LOOP_PLAN_FILE" ]; }; then
|
||||
echo "ERROR: --worktree/--base/--review-only/--review-isolation/--remote-review/--plan-file require the Python loop (MAM_LOOP_PY=1)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -560,16 +566,11 @@ if [ "$PLAN_MODE" = true ]; then
|
||||
log_success "Interactive planning completed. Plan finalized."
|
||||
else
|
||||
log_info "=== Phase 1: Self-Planning Mode (Direct Execution) ==="
|
||||
EXISTING_PLAN_FILE=""
|
||||
if [ -n "$PLANNER_SESSION" ]; then
|
||||
# Promoted plans are saved as plan-<job-id>.md by the Phase 3 promotion
|
||||
# step below, not report-final.md; pick the most recently promoted one.
|
||||
EXISTING_PLAN_FILE=$(ls -t ".agents/reports/$PLANNER_SESSION"/plan-*.md 2>/dev/null | head -n 1 || true)
|
||||
fi
|
||||
if [ -n "$EXISTING_PLAN_FILE" ] && [ -f "$EXISTING_PLAN_FILE" ]; then
|
||||
log_info "Found existing promoted plan at '$EXISTING_PLAN_FILE'. Loading plan..."
|
||||
CURRENT_PLAN=$(cat "$EXISTING_PLAN_FILE")
|
||||
fi
|
||||
# Issue #25 (D1/D9): no plan is loaded here. This used to take the newest
|
||||
# promoted plan of the auto-resolved planner, keyed on mtime and on a session
|
||||
# that says nothing about this task. Reuse is explicit and Python-only now
|
||||
# (--plan-file), and this path rejects that option above.
|
||||
log_info "No plan loaded; the Creator plans by itself."
|
||||
fi
|
||||
|
||||
# ===========================================================================
|
||||
|
||||
Reference in new issue
Block a user