prizmkit 1.1.9 → 1.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled/VERSION.json +3 -3
- package/bundled/dev-pipeline/README.md +10 -46
- package/bundled/dev-pipeline/reset-bug.sh +84 -10
- package/bundled/dev-pipeline/reset-feature.sh +86 -10
- package/bundled/dev-pipeline/reset-refactor.sh +68 -4
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +47 -46
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +7 -12
- package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +124 -20
- package/bundled/dev-pipeline/scripts/utils.py +20 -0
- package/bundled/dev-pipeline/templates/agent-prompts/dev-implement.md +13 -7
- package/bundled/dev-pipeline/templates/bootstrap-tier1.md +62 -66
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +37 -40
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +35 -48
- package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +135 -182
- package/bundled/dev-pipeline/templates/feature-list-schema.json +6 -21
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +9 -9
- package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +1 -1
- package/bundled/dev-pipeline/templates/sections/feature-context.md +4 -0
- package/bundled/dev-pipeline/templates/sections/phase-browser-verification.md +41 -24
- package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +4 -12
- package/bundled/dev-pipeline/templates/sections/phase-deploy-verification.md +9 -17
- package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-plan-agent.md +3 -2
- package/bundled/dev-pipeline/templates/sections/phase-plan-lite.md +4 -2
- package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +0 -18
- package/bundled/dev-pipeline/templates/sections/session-context.md +1 -2
- package/bundled/dev-pipeline/templates/sections/test-failure-recovery-agent.md +75 -0
- package/bundled/dev-pipeline/templates/sections/test-failure-recovery-lite.md +66 -0
- package/bundled/skills/_metadata.json +1 -1
- package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +3 -8
- package/bundled/skills/feature-pipeline-launcher/SKILL.md +4 -16
- package/bundled/skills/feature-planner/SKILL.md +9 -5
- package/bundled/skills/feature-planner/assets/planning-guide.md +16 -11
- package/bundled/skills/feature-planner/references/browser-interaction.md +9 -8
- package/bundled/skills/feature-planner/references/completeness-review.md +1 -1
- package/bundled/skills/feature-planner/references/error-recovery.md +1 -1
- package/bundled/skills/feature-planner/references/incremental-feature-planning.md +1 -1
- package/bundled/skills/feature-planner/scripts/validate-and-generate.py +10 -7
- package/bundled/skills/recovery-workflow/SKILL.md +3 -3
- package/bundled/skills/refactor-pipeline-launcher/SKILL.md +4 -15
- package/package.json +1 -1
- package/bundled/dev-pipeline/retry-bugfix.sh +0 -429
- package/bundled/dev-pipeline/retry-feature.sh +0 -445
- package/bundled/dev-pipeline/retry-refactor.sh +0 -441
- package/bundled/dev-pipeline/templates/sections/failure-log-check.md +0 -9
- package/bundled/dev-pipeline/templates/sections/resume-header.md +0 -5
- package/bundled/dev-pipeline/templates/sections/test-failure-recovery.md +0 -75
|
@@ -1,441 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
set -euo pipefail
|
|
3
|
-
|
|
4
|
-
# ============================================================
|
|
5
|
-
# dev-pipeline/retry-refactor.sh - Retry a single failed refactor
|
|
6
|
-
#
|
|
7
|
-
# Runs exactly ONE AI CLI session for the specified refactor, then exits.
|
|
8
|
-
# Use this to manually retry a failed refactor without restarting
|
|
9
|
-
# the full refactor pipeline.
|
|
10
|
-
#
|
|
11
|
-
# Usage:
|
|
12
|
-
# ./retry-refactor.sh <refactor-id> [.prizmkit/plans/refactor-list.json]
|
|
13
|
-
#
|
|
14
|
-
# Examples:
|
|
15
|
-
# ./retry-refactor.sh R-001
|
|
16
|
-
# ./retry-refactor.sh R-001 .prizmkit/plans/refactor-list.json
|
|
17
|
-
# SESSION_TIMEOUT=3600 ./retry-refactor.sh R-001
|
|
18
|
-
# ============================================================
|
|
19
|
-
|
|
20
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
21
|
-
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
22
|
-
STATE_DIR="${PROJECT_ROOT}/.prizmkit/state/refactor"
|
|
23
|
-
SCRIPTS_DIR="$SCRIPT_DIR/scripts"
|
|
24
|
-
|
|
25
|
-
SESSION_TIMEOUT=${SESSION_TIMEOUT:-0}
|
|
26
|
-
HEARTBEAT_INTERVAL=${HEARTBEAT_INTERVAL:-30}
|
|
27
|
-
AUTO_PUSH=${AUTO_PUSH:-0}
|
|
28
|
-
DEV_BRANCH=${DEV_BRANCH:-""}
|
|
29
|
-
|
|
30
|
-
# Source shared common helpers (CLI/platform detection + logs + deps)
|
|
31
|
-
source "$SCRIPT_DIR/lib/common.sh"
|
|
32
|
-
prizm_detect_cli_and_platform
|
|
33
|
-
|
|
34
|
-
# Source shared heartbeat library
|
|
35
|
-
source "$SCRIPT_DIR/lib/heartbeat.sh"
|
|
36
|
-
|
|
37
|
-
# Source shared branch library
|
|
38
|
-
source "$SCRIPT_DIR/lib/branch.sh"
|
|
39
|
-
|
|
40
|
-
# Detect stream-json support
|
|
41
|
-
detect_stream_json_support "$CLI_CMD"
|
|
42
|
-
|
|
43
|
-
# ============================================================
|
|
44
|
-
# Args
|
|
45
|
-
# ============================================================
|
|
46
|
-
|
|
47
|
-
if [[ $# -lt 1 ]]; then
|
|
48
|
-
echo "Usage: $0 <refactor-id> [.prizmkit/plans/refactor-list.json]"
|
|
49
|
-
echo ""
|
|
50
|
-
echo " refactor-id Refactor to retry (e.g. R-001)"
|
|
51
|
-
echo " refactor-list.json Path to refactor list (default: .prizmkit/plans/refactor-list.json)"
|
|
52
|
-
echo ""
|
|
53
|
-
echo "Environment Variables:"
|
|
54
|
-
echo " SESSION_TIMEOUT Timeout in seconds (default: 0 = no limit)"
|
|
55
|
-
echo " HEARTBEAT_INTERVAL Heartbeat interval in seconds (default: 30)"
|
|
56
|
-
exit 1
|
|
57
|
-
fi
|
|
58
|
-
|
|
59
|
-
REFACTOR_ID="$1"
|
|
60
|
-
REFACTOR_LIST="${2:-.prizmkit/plans/refactor-list.json}"
|
|
61
|
-
|
|
62
|
-
if [[ ! "$REFACTOR_LIST" = /* ]]; then
|
|
63
|
-
REFACTOR_LIST="$(pwd)/$REFACTOR_LIST"
|
|
64
|
-
fi
|
|
65
|
-
|
|
66
|
-
# ============================================================
|
|
67
|
-
# Validation
|
|
68
|
-
# ============================================================
|
|
69
|
-
|
|
70
|
-
if [[ ! -f "$REFACTOR_LIST" ]]; then
|
|
71
|
-
log_error "Refactor list not found: $REFACTOR_LIST"
|
|
72
|
-
exit 1
|
|
73
|
-
fi
|
|
74
|
-
|
|
75
|
-
if ! command -v jq &>/dev/null; then
|
|
76
|
-
log_error "jq is required. Install with: brew install jq"
|
|
77
|
-
exit 1
|
|
78
|
-
fi
|
|
79
|
-
|
|
80
|
-
# Initialize state if needed
|
|
81
|
-
if [[ ! -f "$STATE_DIR/pipeline.json" ]]; then
|
|
82
|
-
log_info "Initializing refactor pipeline state..."
|
|
83
|
-
python3 "$SCRIPTS_DIR/init-refactor-pipeline.py" \
|
|
84
|
-
--refactor-list "$REFACTOR_LIST" \
|
|
85
|
-
--state-dir "$STATE_DIR" >/dev/null 2>&1 || {
|
|
86
|
-
log_error "Failed to initialize refactor pipeline state"
|
|
87
|
-
exit 1
|
|
88
|
-
}
|
|
89
|
-
fi
|
|
90
|
-
|
|
91
|
-
# Verify refactor exists
|
|
92
|
-
REFACTOR_TITLE=$(python3 -c "
|
|
93
|
-
import json, sys
|
|
94
|
-
with open('$REFACTOR_LIST') as f:
|
|
95
|
-
data = json.load(f)
|
|
96
|
-
for item in data.get('refactors', []):
|
|
97
|
-
if item.get('id') == '$REFACTOR_ID':
|
|
98
|
-
print(item.get('title', ''))
|
|
99
|
-
sys.exit(0)
|
|
100
|
-
sys.exit(1)
|
|
101
|
-
" 2>/dev/null) || {
|
|
102
|
-
log_error "Refactor $REFACTOR_ID not found in $REFACTOR_LIST"
|
|
103
|
-
exit 1
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
REFACTOR_COMPLEXITY=$(python3 -c "
|
|
107
|
-
import json, sys
|
|
108
|
-
with open('$REFACTOR_LIST') as f:
|
|
109
|
-
data = json.load(f)
|
|
110
|
-
for item in data.get('refactors', []):
|
|
111
|
-
if item.get('id') == '$REFACTOR_ID':
|
|
112
|
-
print(item.get('complexity', 'medium'))
|
|
113
|
-
sys.exit(0)
|
|
114
|
-
sys.exit(1)
|
|
115
|
-
" 2>/dev/null) || REFACTOR_COMPLEXITY="medium"
|
|
116
|
-
|
|
117
|
-
# ============================================================
|
|
118
|
-
# Clean refactor artifacts + reset status for a full restart
|
|
119
|
-
# ============================================================
|
|
120
|
-
|
|
121
|
-
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
122
|
-
ORIGINAL_BRANCH=$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
|
|
123
|
-
|
|
124
|
-
# Branch tracking (for cleanup on interrupt)
|
|
125
|
-
_DEV_BRANCH_NAME=""
|
|
126
|
-
|
|
127
|
-
log_info "Reading retry state for $REFACTOR_ID..."
|
|
128
|
-
RETRY_COUNT=$(python3 -c "
|
|
129
|
-
import json, os
|
|
130
|
-
status_path = os.path.join('$STATE_DIR', 'refactors', '$REFACTOR_ID', 'status.json')
|
|
131
|
-
if os.path.isfile(status_path):
|
|
132
|
-
with open(status_path) as f:
|
|
133
|
-
d = json.load(f)
|
|
134
|
-
print(d.get('retry_count', 0))
|
|
135
|
-
else:
|
|
136
|
-
print(0)
|
|
137
|
-
" 2>/dev/null || echo "0")
|
|
138
|
-
RESUME_PHASE=$(python3 -c "
|
|
139
|
-
import json, os
|
|
140
|
-
status_path = os.path.join('$STATE_DIR', 'refactors', '$REFACTOR_ID', 'status.json')
|
|
141
|
-
if os.path.isfile(status_path):
|
|
142
|
-
with open(status_path) as f:
|
|
143
|
-
d = json.load(f)
|
|
144
|
-
print(d.get('resume_from_phase') or 'null')
|
|
145
|
-
else:
|
|
146
|
-
print('null')
|
|
147
|
-
" 2>/dev/null || echo "null")
|
|
148
|
-
log_info "Retry count: $RETRY_COUNT, Resume phase: $RESUME_PHASE"
|
|
149
|
-
|
|
150
|
-
# ============================================================
|
|
151
|
-
# Generate bootstrap prompt
|
|
152
|
-
# ============================================================
|
|
153
|
-
|
|
154
|
-
RUN_ID=$(jq -r '.run_id' "$STATE_DIR/pipeline.json")
|
|
155
|
-
SESSION_ID="${REFACTOR_ID}-$(date +%Y%m%d%H%M%S)"
|
|
156
|
-
SESSION_DIR="$STATE_DIR/refactors/$REFACTOR_ID/sessions/$SESSION_ID"
|
|
157
|
-
mkdir -p "$SESSION_DIR/logs"
|
|
158
|
-
|
|
159
|
-
BOOTSTRAP_PROMPT="$SESSION_DIR/bootstrap-prompt.md"
|
|
160
|
-
|
|
161
|
-
log_info "Generating refactor bootstrap prompt..."
|
|
162
|
-
GEN_ARGS=(
|
|
163
|
-
--refactor-list "$REFACTOR_LIST"
|
|
164
|
-
--refactor-id "$REFACTOR_ID"
|
|
165
|
-
--session-id "$SESSION_ID"
|
|
166
|
-
--run-id "$RUN_ID"
|
|
167
|
-
--retry-count "$RETRY_COUNT"
|
|
168
|
-
--resume-phase "$RESUME_PHASE"
|
|
169
|
-
--state-dir "$STATE_DIR"
|
|
170
|
-
--output "$BOOTSTRAP_PROMPT"
|
|
171
|
-
)
|
|
172
|
-
|
|
173
|
-
# Support PIPELINE_MODE env var
|
|
174
|
-
if [[ -n "${PIPELINE_MODE:-}" ]]; then
|
|
175
|
-
GEN_ARGS+=(--mode "$PIPELINE_MODE")
|
|
176
|
-
fi
|
|
177
|
-
|
|
178
|
-
# Support ENABLE_CRITIC env var
|
|
179
|
-
if [[ "${ENABLE_CRITIC:-}" == "true" || "${ENABLE_CRITIC:-}" == "1" ]]; then
|
|
180
|
-
GEN_ARGS+=(--critic "true")
|
|
181
|
-
elif [[ "${ENABLE_CRITIC:-}" == "false" || "${ENABLE_CRITIC:-}" == "0" ]]; then
|
|
182
|
-
GEN_ARGS+=(--critic "false")
|
|
183
|
-
fi
|
|
184
|
-
|
|
185
|
-
GEN_OUTPUT=$(python3 "$SCRIPTS_DIR/generate-refactor-prompt.py" "${GEN_ARGS[@]}" 2>/dev/null) || {
|
|
186
|
-
log_error "Failed to generate bootstrap prompt"
|
|
187
|
-
exit 1
|
|
188
|
-
}
|
|
189
|
-
REFACTOR_MODEL=$(echo "$GEN_OUTPUT" | python3 -c "import json,sys; print(json.load(sys.stdin).get('model',''))" 2>/dev/null || echo "")
|
|
190
|
-
|
|
191
|
-
# ============================================================
|
|
192
|
-
# Run single AI CLI session
|
|
193
|
-
# ============================================================
|
|
194
|
-
|
|
195
|
-
# Branch lifecycle: create and checkout refactor branch
|
|
196
|
-
_branch_name="${DEV_BRANCH:-refactor/${REFACTOR_ID}-$(date +%s)}"
|
|
197
|
-
if branch_create "$PROJECT_ROOT" "$_branch_name" "$ORIGINAL_BRANCH"; then
|
|
198
|
-
_DEV_BRANCH_NAME="$_branch_name"
|
|
199
|
-
log_info "Dev branch: $_branch_name"
|
|
200
|
-
else
|
|
201
|
-
log_warn "Failed to create branch; running session on current branch"
|
|
202
|
-
fi
|
|
203
|
-
|
|
204
|
-
echo ""
|
|
205
|
-
echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
|
|
206
|
-
echo -e "${BOLD} Retry Refactor: $REFACTOR_ID — $REFACTOR_TITLE${NC}"
|
|
207
|
-
echo -e "${BOLD} Complexity: $REFACTOR_COMPLEXITY${NC}"
|
|
208
|
-
echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
|
|
209
|
-
log_info "CLI: $CLI_CMD (platform: $PLATFORM)"
|
|
210
|
-
EFFECTIVE_MODEL="${REFACTOR_MODEL:-${MODEL:-}}"
|
|
211
|
-
if [[ -n "$EFFECTIVE_MODEL" ]]; then
|
|
212
|
-
log_info "Model: $EFFECTIVE_MODEL"
|
|
213
|
-
else
|
|
214
|
-
log_info "Model: (CLI default)"
|
|
215
|
-
fi
|
|
216
|
-
if [[ $SESSION_TIMEOUT -gt 0 ]]; then
|
|
217
|
-
log_info "Session timeout: ${SESSION_TIMEOUT}s"
|
|
218
|
-
else
|
|
219
|
-
log_info "Session timeout: none"
|
|
220
|
-
fi
|
|
221
|
-
log_info "Prompt: $BOOTSTRAP_PROMPT"
|
|
222
|
-
log_info "Log: $SESSION_DIR/logs/session.log"
|
|
223
|
-
echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
|
|
224
|
-
echo ""
|
|
225
|
-
|
|
226
|
-
SESSION_LOG="$SESSION_DIR/logs/session.log"
|
|
227
|
-
PROGRESS_JSON="$SESSION_DIR/logs/progress.json"
|
|
228
|
-
|
|
229
|
-
# Build stream-json flag
|
|
230
|
-
STREAM_JSON_FLAG=""
|
|
231
|
-
if [[ "$USE_STREAM_JSON" == "true" ]]; then
|
|
232
|
-
STREAM_JSON_FLAG="--output-format stream-json"
|
|
233
|
-
fi
|
|
234
|
-
|
|
235
|
-
# claude-internal requires --verbose when using stream-json with -p/--print
|
|
236
|
-
VERBOSE_FLAG=""
|
|
237
|
-
if [[ "$USE_STREAM_JSON" == "true" ]]; then
|
|
238
|
-
VERBOSE_FLAG="--verbose"
|
|
239
|
-
fi
|
|
240
|
-
|
|
241
|
-
# Spawn AI CLI session — model priority: refactor.model > $MODEL env > none
|
|
242
|
-
EFFECTIVE_MODEL="${REFACTOR_MODEL:-${MODEL:-}}"
|
|
243
|
-
MODEL_FLAG=""
|
|
244
|
-
if [[ -n "$EFFECTIVE_MODEL" ]]; then
|
|
245
|
-
MODEL_FLAG="--model $EFFECTIVE_MODEL"
|
|
246
|
-
fi
|
|
247
|
-
|
|
248
|
-
unset CLAUDECODE 2>/dev/null || true
|
|
249
|
-
|
|
250
|
-
# Log bootstrap prompt in test mode
|
|
251
|
-
prizm_log_bootstrap_prompt "$BOOTSTRAP_PROMPT" "$REFACTOR_ID"
|
|
252
|
-
|
|
253
|
-
case "$CLI_CMD" in
|
|
254
|
-
*claude*)
|
|
255
|
-
# Claude Code: prompt via -p argument, --dangerously-skip-permissions for auto-accept
|
|
256
|
-
"$CLI_CMD" \
|
|
257
|
-
-p "$(cat "$BOOTSTRAP_PROMPT")" \
|
|
258
|
-
--dangerously-skip-permissions \
|
|
259
|
-
$VERBOSE_FLAG \
|
|
260
|
-
$STREAM_JSON_FLAG \
|
|
261
|
-
$MODEL_FLAG \
|
|
262
|
-
> "$SESSION_LOG" 2>&1 &
|
|
263
|
-
;;
|
|
264
|
-
*)
|
|
265
|
-
# CodeBuddy (cbc) and others: prompt via stdin
|
|
266
|
-
"$CLI_CMD" \
|
|
267
|
-
--print \
|
|
268
|
-
-y \
|
|
269
|
-
$STREAM_JSON_FLAG \
|
|
270
|
-
$MODEL_FLAG \
|
|
271
|
-
< "$BOOTSTRAP_PROMPT" \
|
|
272
|
-
> "$SESSION_LOG" 2>&1 &
|
|
273
|
-
;;
|
|
274
|
-
esac
|
|
275
|
-
CLI_PID=$!
|
|
276
|
-
|
|
277
|
-
# Start progress parser (no-op if stream-json not supported)
|
|
278
|
-
start_progress_parser "$SESSION_LOG" "$PROGRESS_JSON" "$SCRIPTS_DIR"
|
|
279
|
-
PARSER_PID="${_PARSER_PID:-}"
|
|
280
|
-
|
|
281
|
-
# Timeout watchdog
|
|
282
|
-
WATCHER_PID=""
|
|
283
|
-
if [[ $SESSION_TIMEOUT -gt 0 ]]; then
|
|
284
|
-
( sleep "$SESSION_TIMEOUT" && kill -TERM "$CLI_PID" 2>/dev/null ) &
|
|
285
|
-
WATCHER_PID=$!
|
|
286
|
-
fi
|
|
287
|
-
|
|
288
|
-
# Heartbeat
|
|
289
|
-
start_heartbeat "$CLI_PID" "$SESSION_LOG" "$PROGRESS_JSON" "$HEARTBEAT_INTERVAL"
|
|
290
|
-
HEARTBEAT_PID="${_HEARTBEAT_PID:-}"
|
|
291
|
-
|
|
292
|
-
# Ctrl+C cleanup
|
|
293
|
-
cleanup() {
|
|
294
|
-
echo ""
|
|
295
|
-
log_warn "Interrupted. Killing session..."
|
|
296
|
-
kill "$CLI_PID" 2>/dev/null || true
|
|
297
|
-
[[ -n "$WATCHER_PID" ]] && kill "$WATCHER_PID" 2>/dev/null || true
|
|
298
|
-
stop_heartbeat "$HEARTBEAT_PID"
|
|
299
|
-
stop_progress_parser "$PARSER_PID"
|
|
300
|
-
wait "$CLI_PID" 2>/dev/null || true
|
|
301
|
-
[[ -n "$WATCHER_PID" ]] && wait "$WATCHER_PID" 2>/dev/null || true
|
|
302
|
-
if [[ -n "$_DEV_BRANCH_NAME" ]]; then
|
|
303
|
-
log_info "Development was on branch: $_DEV_BRANCH_NAME"
|
|
304
|
-
log_info "Original branch was: $ORIGINAL_BRANCH"
|
|
305
|
-
fi
|
|
306
|
-
log_info "Session log: $SESSION_LOG"
|
|
307
|
-
exit 130
|
|
308
|
-
}
|
|
309
|
-
trap cleanup SIGINT SIGTERM
|
|
310
|
-
|
|
311
|
-
# Wait
|
|
312
|
-
EXIT_CODE=0
|
|
313
|
-
if wait "$CLI_PID" 2>/dev/null; then
|
|
314
|
-
EXIT_CODE=0
|
|
315
|
-
else
|
|
316
|
-
EXIT_CODE=$?
|
|
317
|
-
fi
|
|
318
|
-
|
|
319
|
-
# Cleanup background processes
|
|
320
|
-
[[ -n "$WATCHER_PID" ]] && kill "$WATCHER_PID" 2>/dev/null || true
|
|
321
|
-
stop_heartbeat "$HEARTBEAT_PID"
|
|
322
|
-
stop_progress_parser "$PARSER_PID"
|
|
323
|
-
[[ -n "$WATCHER_PID" ]] && wait "$WATCHER_PID" 2>/dev/null || true
|
|
324
|
-
|
|
325
|
-
[[ $EXIT_CODE -eq 143 ]] && EXIT_CODE=124
|
|
326
|
-
|
|
327
|
-
# ============================================================
|
|
328
|
-
# Check result
|
|
329
|
-
# ============================================================
|
|
330
|
-
|
|
331
|
-
echo ""
|
|
332
|
-
if [[ -f "$SESSION_LOG" ]]; then
|
|
333
|
-
FINAL_LINES=$(wc -l < "$SESSION_LOG" 2>/dev/null | tr -d ' ')
|
|
334
|
-
FINAL_SIZE=$(wc -c < "$SESSION_LOG" 2>/dev/null | tr -d ' ')
|
|
335
|
-
log_info "Session log: $FINAL_LINES lines, $((FINAL_SIZE / 1024))KB"
|
|
336
|
-
fi
|
|
337
|
-
log_info "exit_code=$EXIT_CODE"
|
|
338
|
-
|
|
339
|
-
# ── Determine session outcome from observable signals ──────────────
|
|
340
|
-
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
341
|
-
DEFAULT_BRANCH="$ORIGINAL_BRANCH"
|
|
342
|
-
|
|
343
|
-
if [[ $EXIT_CODE -eq 124 ]]; then
|
|
344
|
-
log_warn "Session timed out after ${SESSION_TIMEOUT}s"
|
|
345
|
-
SESSION_STATUS="timed_out"
|
|
346
|
-
elif [[ $EXIT_CODE -ne 0 ]]; then
|
|
347
|
-
log_warn "Session exited with code $EXIT_CODE"
|
|
348
|
-
SESSION_STATUS="crashed"
|
|
349
|
-
else
|
|
350
|
-
# Exit code 0 — check if the session produced commits
|
|
351
|
-
HAS_COMMITS=""
|
|
352
|
-
if git -C "$PROJECT_ROOT" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
353
|
-
HAS_COMMITS=$(git -C "$PROJECT_ROOT" log "${DEFAULT_BRANCH}..HEAD" --oneline 2>/dev/null | head -1)
|
|
354
|
-
fi
|
|
355
|
-
|
|
356
|
-
if [[ -n "$HAS_COMMITS" ]]; then
|
|
357
|
-
SESSION_STATUS="success"
|
|
358
|
-
else
|
|
359
|
-
UNCOMMITTED=$(git -C "$PROJECT_ROOT" status --porcelain 2>/dev/null | head -1 || true)
|
|
360
|
-
if [[ -n "$UNCOMMITTED" ]]; then
|
|
361
|
-
log_warn "Session exited cleanly but produced no commits (uncommitted changes found) — auto-committing..."
|
|
362
|
-
git -C "$PROJECT_ROOT" add -A 2>/dev/null || true
|
|
363
|
-
if git -C "$PROJECT_ROOT" commit --no-verify -m "chore($REFACTOR_ID): auto-commit session work" 2>/dev/null; then
|
|
364
|
-
log_info "Auto-commit succeeded"
|
|
365
|
-
SESSION_STATUS="success"
|
|
366
|
-
else
|
|
367
|
-
log_warn "Auto-commit failed — no changes to commit"
|
|
368
|
-
SESSION_STATUS="crashed"
|
|
369
|
-
fi
|
|
370
|
-
else
|
|
371
|
-
log_warn "Session exited cleanly but produced no commits and no changes"
|
|
372
|
-
SESSION_STATUS="crashed"
|
|
373
|
-
fi
|
|
374
|
-
fi
|
|
375
|
-
fi
|
|
376
|
-
|
|
377
|
-
# ── Post-success validation ──────────────────────────────────────────
|
|
378
|
-
if [[ "$SESSION_STATUS" == "success" ]]; then
|
|
379
|
-
if git -C "$PROJECT_ROOT" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
380
|
-
DIRTY_FILES=$(git -C "$PROJECT_ROOT" status --porcelain 2>/dev/null || true)
|
|
381
|
-
if [[ -n "$DIRTY_FILES" ]]; then
|
|
382
|
-
log_info "Auto-committing remaining session artifacts..."
|
|
383
|
-
git -C "$PROJECT_ROOT" add -A 2>/dev/null || true
|
|
384
|
-
git -C "$PROJECT_ROOT" commit --no-verify --amend --no-edit -a 2>/dev/null \
|
|
385
|
-
|| git -C "$PROJECT_ROOT" commit --no-verify -m "chore($REFACTOR_ID): include remaining session artifacts" 2>/dev/null \
|
|
386
|
-
|| true
|
|
387
|
-
fi
|
|
388
|
-
fi
|
|
389
|
-
fi
|
|
390
|
-
|
|
391
|
-
# ── Propagate completion notes for dependency context ─────────────────
|
|
392
|
-
if [[ "$SESSION_STATUS" == "success" ]]; then
|
|
393
|
-
SUMMARY_PATH="$PROJECT_ROOT/.prizmkit/refactor/$REFACTOR_ID/completion-summary.json"
|
|
394
|
-
if [[ -f "$SUMMARY_PATH" ]]; then
|
|
395
|
-
python3 "$SCRIPTS_DIR/patch-completion-notes.py" \
|
|
396
|
-
--refactor-list "$REFACTOR_LIST" \
|
|
397
|
-
--refactor-id "$REFACTOR_ID" \
|
|
398
|
-
--summary "$SUMMARY_PATH" >/dev/null 2>&1 && {
|
|
399
|
-
log_info "Propagated completion notes for $REFACTOR_ID"
|
|
400
|
-
} || {
|
|
401
|
-
log_warn "Failed to propagate completion notes for $REFACTOR_ID"
|
|
402
|
-
}
|
|
403
|
-
fi
|
|
404
|
-
fi
|
|
405
|
-
|
|
406
|
-
# ── Merge dev branch back to original on success ────────────────────
|
|
407
|
-
if [[ "$SESSION_STATUS" == "success" && -n "$_DEV_BRANCH_NAME" ]]; then
|
|
408
|
-
if branch_merge "$PROJECT_ROOT" "$_DEV_BRANCH_NAME" "$ORIGINAL_BRANCH" "$AUTO_PUSH"; then
|
|
409
|
-
_DEV_BRANCH_NAME=""
|
|
410
|
-
else
|
|
411
|
-
log_warn "Auto-merge failed — dev branch preserved: $_DEV_BRANCH_NAME"
|
|
412
|
-
fi
|
|
413
|
-
fi
|
|
414
|
-
|
|
415
|
-
# Update refactor status
|
|
416
|
-
python3 "$SCRIPTS_DIR/update-refactor-status.py" \
|
|
417
|
-
--refactor-list "$REFACTOR_LIST" \
|
|
418
|
-
--state-dir "$STATE_DIR" \
|
|
419
|
-
--refactor-id "$REFACTOR_ID" \
|
|
420
|
-
--session-status "$SESSION_STATUS" \
|
|
421
|
-
--session-id "$SESSION_ID" \
|
|
422
|
-
--max-retries 999 \
|
|
423
|
-
--action update >/dev/null 2>&1 || true
|
|
424
|
-
|
|
425
|
-
# Commit refactor-list.json status update (pipeline management commit)
|
|
426
|
-
if ! git -C "$PROJECT_ROOT" diff --quiet "$REFACTOR_LIST" 2>/dev/null; then
|
|
427
|
-
git -C "$PROJECT_ROOT" add "$REFACTOR_LIST"
|
|
428
|
-
git -C "$PROJECT_ROOT" commit --no-verify -m "chore($REFACTOR_ID): update refactor status" 2>/dev/null || true
|
|
429
|
-
fi
|
|
430
|
-
|
|
431
|
-
echo ""
|
|
432
|
-
if [[ "$SESSION_STATUS" == "success" ]]; then
|
|
433
|
-
log_success "════════════════════════════════════════════════════"
|
|
434
|
-
log_success " $REFACTOR_ID completed successfully!"
|
|
435
|
-
log_success "════════════════════════════════════════════════════"
|
|
436
|
-
else
|
|
437
|
-
log_error "════════════════════════════════════════════════════"
|
|
438
|
-
log_error " $REFACTOR_ID result: $SESSION_STATUS"
|
|
439
|
-
log_error " Review log: $SESSION_LOG"
|
|
440
|
-
log_error "════════════════════════════════════════════════════"
|
|
441
|
-
fi
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
**Check for previous failure log** (diagnostic context only — do NOT use to determine resume point):
|
|
2
|
-
```bash
|
|
3
|
-
cat .prizmkit/specs/{{FEATURE_SLUG}}/failure-log.md 2>/dev/null || echo "NO_PREVIOUS_FAILURE"
|
|
4
|
-
```
|
|
5
|
-
If failure-log.md exists:
|
|
6
|
-
- Read ROOT_CAUSE and SUGGESTION — adjust your approach accordingly
|
|
7
|
-
- Read DISCOVERED_TRAPS — if any are genuine, inject into .prizm-docs/ during the commit phase retrospective
|
|
8
|
-
- Do NOT delete failure-log.md until this session completes all phases and commits successfully
|
|
9
|
-
- **Note**: The resume point is determined by `workflow-checkpoint.json`, not by failure-log.md
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
### Resume from Phase {{RESUME_PHASE}}
|
|
2
|
-
|
|
3
|
-
**Primary**: Read `{{CHECKPOINT_PATH}}` — find the first step with `"pending"` or `"in_progress"` status and resume from there. Steps already `"completed"` or `"skipped"` must NOT be re-executed.
|
|
4
|
-
|
|
5
|
-
**Fallback**: If `workflow-checkpoint.json` is missing or corrupted, check `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` — if it exists, skip context building and use it directly.
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
## Test Failure Recovery Protocol
|
|
2
|
-
|
|
3
|
-
When tests fail during implementation (Phase 3 / Phase 4):
|
|
4
|
-
|
|
5
|
-
### Immediate Action — Recovery Attempt (Max 2 Rounds)
|
|
6
|
-
|
|
7
|
-
1. **Analyze failure output**:
|
|
8
|
-
- Read the test failure message carefully
|
|
9
|
-
- Identify: root cause (code bug vs. test brittleness vs. environment issue)
|
|
10
|
-
- Check if baseline already recorded this failure (in BASELINE_FAILURES)
|
|
11
|
-
|
|
12
|
-
2. **Categorize failure**:
|
|
13
|
-
- **Pre-existing baseline failure** (expected): Record as acceptable, do NOT fix
|
|
14
|
-
- **New regression**: Code introduced a bug, fix the code
|
|
15
|
-
- **Brittle test**: Test passes/fails inconsistently, fix the test or environment
|
|
16
|
-
- **Environment issue**: Missing dependency, wrong config, fix setup
|
|
17
|
-
|
|
18
|
-
3. **Fix and re-run** (first round):
|
|
19
|
-
- Apply fix (code or test, not environment)
|
|
20
|
-
- Re-run `$TEST_CMD` to verify
|
|
21
|
-
- If now passing → continue to next task
|
|
22
|
-
- If still failing → **proceed to Round 2**
|
|
23
|
-
|
|
24
|
-
4. **Second fix attempt** (second round only):
|
|
25
|
-
- Re-analyze the failure with fresh perspective
|
|
26
|
-
- Try alternate fix approach
|
|
27
|
-
- Re-run `$TEST_CMD`
|
|
28
|
-
- If still failing after Round 2 → **escalate** (see below)
|
|
29
|
-
|
|
30
|
-
### Escalation Paths
|
|
31
|
-
|
|
32
|
-
**Tier 1 (Single Agent)**:
|
|
33
|
-
- After max 2 fix rounds with tests still failing
|
|
34
|
-
- Document failure in Implementation Log with root cause analysis
|
|
35
|
-
- Attempt one manual fix by re-reading related source code
|
|
36
|
-
- If unable to resolve: record PARTIAL status with known failure list
|
|
37
|
-
- **Do NOT block commit**; tests can fail during development (recovery may be deferred to next session)
|
|
38
|
-
|
|
39
|
-
**Tier 2/3 (Dev + Reviewer)**:
|
|
40
|
-
- After Dev completes max 2 fix rounds with tests still failing
|
|
41
|
-
- Dev appends failure details to Implementation Log
|
|
42
|
-
- Reviewer agent runs full test suite in Phase 5
|
|
43
|
-
- If Reviewer confirms NEW regressions (not in baseline): mark verdict as `NEEDS_FIXES`
|
|
44
|
-
- If Reviewer confirms only baseline failures remain: proceed with `PASS_WITH_WARNINGS`
|
|
45
|
-
|
|
46
|
-
### Context-Aware Test Re-run (Performance Optimization)
|
|
47
|
-
|
|
48
|
-
**Skip redundant re-runs**:
|
|
49
|
-
- If Implementation Log section in context-snapshot.md already confirms "all tests passing"
|
|
50
|
-
- → Skip Phase 5 test suite re-run (Reviewer will verify baseline log instead)
|
|
51
|
-
- This avoids rebuilding/re-running tests when already verified
|
|
52
|
-
|
|
53
|
-
**When to re-run**:
|
|
54
|
-
- If Implementation Log is missing or incomplete
|
|
55
|
-
- If any new code was added after the last test run
|
|
56
|
-
- If Reviewer suspects brittleness or environment drift
|
|
57
|
-
|
|
58
|
-
### Failure Capture Rules
|
|
59
|
-
|
|
60
|
-
If tests remain broken after recovery:
|
|
61
|
-
|
|
62
|
-
```
|
|
63
|
-
## Test Failures Encountered
|
|
64
|
-
|
|
65
|
-
- **Test**: [test name/path]
|
|
66
|
-
- Root Cause: [explanation]
|
|
67
|
-
- Category: [pre-existing baseline | new regression | brittle test | environment]
|
|
68
|
-
- Fix Attempted: [describe what was tried]
|
|
69
|
-
- Status: [still failing | requires next session | known limitation]
|
|
70
|
-
|
|
71
|
-
- **Impact on Feature**: [can AC be verified despite failure | blocks AC verification]
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
**Rule**: If any AC cannot be verified due to test failure, the feature is incomplete. Document in failure-log.md for next session.
|
|
75
|
-
|