prizmkit 1.1.98 → 1.1.100
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 +5 -5
- package/bundled/dev-pipeline/launch-bugfix-daemon.sh +1 -1
- package/bundled/dev-pipeline/launch-feature-daemon.sh +1 -1
- package/bundled/dev-pipeline/launch-refactor-daemon.sh +1 -1
- package/bundled/dev-pipeline/lib/common.sh +244 -25
- package/bundled/dev-pipeline/reset-bug.sh +32 -2
- package/bundled/dev-pipeline/reset-feature.sh +32 -2
- package/bundled/dev-pipeline/reset-refactor.sh +32 -2
- package/bundled/dev-pipeline/run-bugfix.sh +133 -18
- package/bundled/dev-pipeline/run-feature.sh +134 -18
- package/bundled/dev-pipeline/run-refactor.sh +133 -18
- package/bundled/dev-pipeline/scripts/check-session-status.py +74 -1
- package/bundled/dev-pipeline/scripts/continuation.py +374 -0
- package/bundled/dev-pipeline/scripts/detect-stuck.py +5 -5
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +29 -35
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +19 -25
- package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +19 -25
- package/bundled/dev-pipeline/scripts/init-bugfix-pipeline.py +1 -1
- package/bundled/dev-pipeline/scripts/init-pipeline.py +1 -1
- package/bundled/dev-pipeline/scripts/init-refactor-pipeline.py +1 -1
- package/bundled/dev-pipeline/scripts/parse-stream-progress.py +146 -16
- package/bundled/dev-pipeline/scripts/update-bug-status.py +220 -13
- package/bundled/dev-pipeline/scripts/update-feature-status.py +244 -18
- package/bundled/dev-pipeline/scripts/update-refactor-status.py +220 -13
- package/bundled/dev-pipeline/templates/agent-prompts/dev-implement.md +1 -1
- package/bundled/dev-pipeline/templates/bootstrap-tier1.md +2 -2
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +3 -3
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +3 -3
- package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +1 -1
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +3 -3
- package/bundled/dev-pipeline/templates/sections/log-size-awareness.md +31 -66
- package/bundled/dev-pipeline/templates/session-status-schema.json +1 -1
- package/bundled/dev-pipeline/tests/conftest.py +1 -0
- package/bundled/dev-pipeline/tests/test_auto_skip.py +518 -8
- package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +103 -0
- package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +60 -0
- package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +43 -0
- package/bundled/dev-pipeline-windows/lib/common.ps1 +172 -10
- package/bundled/dev-pipeline-windows/lib/pipeline.ps1 +95 -11
- package/bundled/dev-pipeline-windows/lib/reset.ps1 +34 -0
- package/bundled/dev-pipeline-windows/reset-bug.ps1 +1 -0
- package/bundled/dev-pipeline-windows/reset-feature.ps1 +1 -0
- package/bundled/dev-pipeline-windows/reset-refactor.ps1 +1 -0
- package/bundled/dev-pipeline-windows/scripts/check-session-status.py +74 -1
- package/bundled/dev-pipeline-windows/scripts/continuation.py +374 -0
- package/bundled/dev-pipeline-windows/scripts/detect-stuck.py +5 -5
- package/bundled/dev-pipeline-windows/scripts/generate-bootstrap-prompt.py +29 -35
- package/bundled/dev-pipeline-windows/scripts/generate-bugfix-prompt.py +20 -25
- package/bundled/dev-pipeline-windows/scripts/generate-refactor-prompt.py +20 -25
- package/bundled/dev-pipeline-windows/scripts/init-bugfix-pipeline.py +1 -1
- package/bundled/dev-pipeline-windows/scripts/init-pipeline.py +1 -1
- package/bundled/dev-pipeline-windows/scripts/init-refactor-pipeline.py +1 -1
- package/bundled/dev-pipeline-windows/scripts/parse-stream-progress.py +146 -16
- package/bundled/dev-pipeline-windows/scripts/update-bug-status.py +220 -13
- package/bundled/dev-pipeline-windows/scripts/update-feature-status.py +244 -18
- package/bundled/dev-pipeline-windows/scripts/update-refactor-status.py +220 -13
- package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-implement.md +1 -1
- package/bundled/dev-pipeline-windows/templates/bootstrap-tier1.md +2 -2
- package/bundled/dev-pipeline-windows/templates/bootstrap-tier2.md +3 -3
- package/bundled/dev-pipeline-windows/templates/bootstrap-tier3.md +3 -3
- package/bundled/dev-pipeline-windows/templates/bugfix-bootstrap-prompt.md +1 -1
- package/bundled/dev-pipeline-windows/templates/refactor-bootstrap-prompt.md +3 -3
- package/bundled/dev-pipeline-windows/templates/sections/log-size-awareness.md +31 -68
- package/bundled/dev-pipeline-windows/templates/session-status-schema.json +1 -1
- package/bundled/skills/_metadata.json +1 -1
- package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +2 -2
- package/bundled/skills/feature-pipeline-launcher/SKILL.md +2 -2
- package/bundled/skills/recovery-workflow/SKILL.md +2 -2
- package/bundled/skills/recovery-workflow/evals/evals.json +2 -2
- package/bundled/skills/refactor-pipeline-launcher/SKILL.md +2 -2
- package/bundled/skills-windows/bugfix-pipeline-launcher/SKILL.md +2 -2
- package/bundled/skills-windows/feature-pipeline-launcher/SKILL.md +2 -2
- package/bundled/skills-windows/recovery-workflow/SKILL.md +2 -2
- package/bundled/skills-windows/recovery-workflow/evals/evals.json +2 -2
- package/bundled/skills-windows/refactor-pipeline-launcher/SKILL.md +2 -2
- package/package.json +1 -1
- package/bundled/dev-pipeline/scripts/monitor-log.sh +0 -104
- package/bundled/dev-pipeline-windows/scripts/monitor-log.ps1 +0 -102
|
@@ -23,8 +23,7 @@ set -euo pipefail
|
|
|
23
23
|
# HEARTBEAT_INTERVAL Heartbeat log interval in seconds (default: 30)
|
|
24
24
|
# STALE_KILL_THRESHOLD Auto-kill session after N seconds of no progress (default: 900)
|
|
25
25
|
# HEARTBEAT_STALE_THRESHOLD Heartbeat stale threshold in seconds (default: 600)
|
|
26
|
-
# MAX_LOG_SIZE
|
|
27
|
-
# LOG_MONITOR_POLL_INTERVAL Log monitor poll interval in seconds (default: 30)
|
|
26
|
+
# MAX_LOG_SIZE Include passive log-size checkpoint guidance above this threshold (default: 2097152 = 2MB, set 0 to disable)
|
|
28
27
|
# DEV_BRANCH Custom dev branch name (default: auto-generated refactor/pipeline-{run_id})
|
|
29
28
|
# AUTO_PUSH Auto-push to remote after successful refactor (default: 0). Set to 1 to enable.
|
|
30
29
|
# STOP_ON_FAILURE Stop pipeline after a task exhausts all retries (default: 0). Set to 1 to stop.
|
|
@@ -140,6 +139,16 @@ spawn_and_wait_session() {
|
|
|
140
139
|
log_warn "Session was stale-killed by heartbeat monitor (no progress for too long)"
|
|
141
140
|
fi
|
|
142
141
|
|
|
142
|
+
local was_context_overflow=false
|
|
143
|
+
if prizm_detect_context_overflow_error "$session_log" "$progress_json"; then
|
|
144
|
+
was_context_overflow=true
|
|
145
|
+
fi
|
|
146
|
+
|
|
147
|
+
local was_ai_runtime_error=false
|
|
148
|
+
if prizm_detect_ai_runtime_error "$session_log" "$progress_json"; then
|
|
149
|
+
was_ai_runtime_error=true
|
|
150
|
+
fi
|
|
151
|
+
|
|
143
152
|
local was_infra_error=false
|
|
144
153
|
if [[ $exit_code -ne 0 ]] && prizm_detect_infra_error "$session_log" "$progress_json"; then
|
|
145
154
|
was_infra_error=true
|
|
@@ -163,7 +172,22 @@ spawn_and_wait_session() {
|
|
|
163
172
|
project_root="$PROJECT_ROOT"
|
|
164
173
|
local default_branch="$base_branch"
|
|
165
174
|
|
|
166
|
-
|
|
175
|
+
local has_commits=""
|
|
176
|
+
if git -C "$project_root" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
177
|
+
has_commits=$(git -C "$project_root" log "${default_branch}..HEAD" --oneline 2>/dev/null | head -1)
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
if [[ -n "$has_commits" ]]; then
|
|
181
|
+
session_status="success"
|
|
182
|
+
elif [[ "$was_context_overflow" == true ]]; then
|
|
183
|
+
log_warn "Session failed because the AI CLI exceeded the model context window"
|
|
184
|
+
log_warn "Context overflow is retried without consuming code retry budget"
|
|
185
|
+
session_status="context_overflow"
|
|
186
|
+
elif [[ "$was_ai_runtime_error" == true ]]; then
|
|
187
|
+
log_warn "Session failed due to structured AI runtime error"
|
|
188
|
+
log_warn "AI runtime errors are retried without consuming code retry budget"
|
|
189
|
+
session_status="infra_error"
|
|
190
|
+
elif [[ "$was_infra_error" == true ]]; then
|
|
167
191
|
log_warn "Session failed due to AI CLI/provider infrastructure error"
|
|
168
192
|
log_warn "Infrastructure errors are retried without consuming code retry budget"
|
|
169
193
|
session_status="infra_error"
|
|
@@ -299,6 +323,12 @@ finalize_refactor_status_after_branch_return() {
|
|
|
299
323
|
local session_status="$4"
|
|
300
324
|
local max_retries="$5"
|
|
301
325
|
local max_infra_retries="$6"
|
|
326
|
+
local base_branch="${7:-main}"
|
|
327
|
+
local active_dev_branch="${8:-}"
|
|
328
|
+
local fatal_error_code="${9:-}"
|
|
329
|
+
local continuation_summary_path="${10:-}"
|
|
330
|
+
local no_progress_count="${11:-0}"
|
|
331
|
+
local progress_fingerprint="${12:-}"
|
|
302
332
|
|
|
303
333
|
# Update refactor status on the original branch. The caller commits the
|
|
304
334
|
# resulting refactor-list diff immediately after this helper returns.
|
|
@@ -311,6 +341,12 @@ finalize_refactor_status_after_branch_return() {
|
|
|
311
341
|
--session-id "$session_id" \
|
|
312
342
|
--max-retries "$max_retries" \
|
|
313
343
|
--max-infra-retries "$max_infra_retries" \
|
|
344
|
+
--active-dev-branch "$active_dev_branch" \
|
|
345
|
+
--base-branch "$base_branch" \
|
|
346
|
+
--last-fatal-error-code "$fatal_error_code" \
|
|
347
|
+
--continuation-summary-path "$continuation_summary_path" \
|
|
348
|
+
--no-progress-count "$no_progress_count" \
|
|
349
|
+
--progress-fingerprint "$progress_fingerprint" \
|
|
314
350
|
--action update) || {
|
|
315
351
|
log_error "Failed to update refactor status: $update_output"
|
|
316
352
|
update_output=""
|
|
@@ -544,7 +580,7 @@ sys.exit(1)
|
|
|
544
580
|
log_info "Removed $dev_team_dir"
|
|
545
581
|
fi
|
|
546
582
|
|
|
547
|
-
local refactor_state_dir="$STATE_DIR
|
|
583
|
+
local refactor_state_dir="$STATE_DIR/$refactor_id"
|
|
548
584
|
if [[ -d "$refactor_state_dir" ]]; then
|
|
549
585
|
rm -rf "$refactor_state_dir"
|
|
550
586
|
log_info "Removed $refactor_state_dir"
|
|
@@ -569,7 +605,7 @@ sys.exit(1)
|
|
|
569
605
|
local run_id session_id session_dir bootstrap_prompt
|
|
570
606
|
run_id=$(jq -r '.run_id' "$STATE_DIR/pipeline.json")
|
|
571
607
|
session_id="${refactor_id}-$(date +%Y%m%d%H%M%S)"
|
|
572
|
-
session_dir="$STATE_DIR
|
|
608
|
+
session_dir="$STATE_DIR/$refactor_id/sessions/$session_id"
|
|
573
609
|
mkdir -p "$session_dir/logs"
|
|
574
610
|
|
|
575
611
|
bootstrap_prompt="$session_dir/bootstrap-prompt.md"
|
|
@@ -578,7 +614,7 @@ sys.exit(1)
|
|
|
578
614
|
local retry_count
|
|
579
615
|
retry_count=$(python3 -c "
|
|
580
616
|
import json, os
|
|
581
|
-
status_path = os.path.join('$STATE_DIR', '
|
|
617
|
+
status_path = os.path.join('$STATE_DIR', '$refactor_id', 'status.json')
|
|
582
618
|
if os.path.isfile(status_path):
|
|
583
619
|
with open(status_path) as f:
|
|
584
620
|
d = json.load(f)
|
|
@@ -589,7 +625,7 @@ else:
|
|
|
589
625
|
local resume_phase
|
|
590
626
|
resume_phase=$(python3 -c "
|
|
591
627
|
import json, os
|
|
592
|
-
status_path = os.path.join('$STATE_DIR', '
|
|
628
|
+
status_path = os.path.join('$STATE_DIR', '$refactor_id', 'status.json')
|
|
593
629
|
if os.path.isfile(status_path):
|
|
594
630
|
with open(status_path) as f:
|
|
595
631
|
d = json.load(f)
|
|
@@ -751,6 +787,11 @@ else:
|
|
|
751
787
|
"$bootstrap_prompt" "$session_dir" "$MAX_RETRIES" "$MAX_INFRA_RETRIES" "$refactor_model" "$_ORIGINAL_BRANCH"
|
|
752
788
|
local session_status="$_SPAWN_RESULT"
|
|
753
789
|
|
|
790
|
+
local active_dev_branch_for_status="$_DEV_BRANCH_NAME"
|
|
791
|
+
local continuation_summary_path=""
|
|
792
|
+
local no_progress_count=0
|
|
793
|
+
local progress_after=""
|
|
794
|
+
|
|
754
795
|
# Merge dev branch back to original on success
|
|
755
796
|
if [[ "$session_status" == "success" && -n "$_DEV_BRANCH_NAME" ]]; then
|
|
756
797
|
if branch_merge "$_proj_root" "$_DEV_BRANCH_NAME" "$_ORIGINAL_BRANCH" "$AUTO_PUSH"; then
|
|
@@ -770,7 +811,7 @@ else:
|
|
|
770
811
|
branch_ensure_return "$_proj_root" "$_ORIGINAL_BRANCH"
|
|
771
812
|
|
|
772
813
|
finalize_refactor_status_after_branch_return \
|
|
773
|
-
"$refactor_id" "$refactor_list" "$session_id" "$session_status" "$MAX_RETRIES" "$MAX_INFRA_RETRIES"
|
|
814
|
+
"$refactor_id" "$refactor_list" "$session_id" "$session_status" "$MAX_RETRIES" "$MAX_INFRA_RETRIES" "$_ORIGINAL_BRANCH" "$active_dev_branch_for_status" "context_overflow" "$continuation_summary_path" "$no_progress_count" "${progress_after:-}"
|
|
774
815
|
|
|
775
816
|
# Commit refactor status update on the original branch (after guaranteed return)
|
|
776
817
|
if ! git -C "$_proj_root" diff --quiet "$refactor_list" 2>/dev/null; then
|
|
@@ -1024,13 +1065,21 @@ DEPLOY_PROMPT_EOF
|
|
|
1024
1065
|
fi
|
|
1025
1066
|
|
|
1026
1067
|
# Parse refactor info
|
|
1027
|
-
local refactor_id refactor_title refactor_complexity retry_count infra_error_count resume_phase
|
|
1068
|
+
local refactor_id refactor_title refactor_complexity retry_count infra_error_count resume_phase active_dev_branch base_branch continuation_pending continuation_reason context_overflow_count continuation_count previous_session_id no_progress_count
|
|
1028
1069
|
refactor_id=$(echo "$next_refactor" | jq -r '.refactor_id')
|
|
1029
1070
|
refactor_title=$(echo "$next_refactor" | jq -r '.title')
|
|
1030
1071
|
refactor_complexity=$(echo "$next_refactor" | jq -r '.complexity')
|
|
1031
1072
|
retry_count=$(echo "$next_refactor" | jq -r '.retry_count // 0')
|
|
1032
1073
|
infra_error_count=$(echo "$next_refactor" | jq -r '.infra_error_count // 0')
|
|
1033
1074
|
resume_phase=$(echo "$next_refactor" | jq -r '.resume_from_phase // "null"')
|
|
1075
|
+
active_dev_branch=$(echo "$next_refactor" | jq -r '.active_dev_branch // ""')
|
|
1076
|
+
base_branch=$(echo "$next_refactor" | jq -r '.base_branch // ""')
|
|
1077
|
+
continuation_pending=$(echo "$next_refactor" | jq -r '.continuation_pending // false')
|
|
1078
|
+
continuation_reason=$(echo "$next_refactor" | jq -r '.continuation_reason // ""')
|
|
1079
|
+
context_overflow_count=$(echo "$next_refactor" | jq -r '.context_overflow_count // 0')
|
|
1080
|
+
continuation_count=$(echo "$next_refactor" | jq -r '.continuation_count // 0')
|
|
1081
|
+
previous_session_id=$(echo "$next_refactor" | jq -r '.last_context_overflow_session_id // ""')
|
|
1082
|
+
no_progress_count=$(echo "$next_refactor" | jq -r '.no_progress_count // 0')
|
|
1034
1083
|
|
|
1035
1084
|
echo ""
|
|
1036
1085
|
echo -e "${BOLD}────────────────────────────────────────────────────${NC}"
|
|
@@ -1041,6 +1090,10 @@ DEPLOY_PROMPT_EOF
|
|
|
1041
1090
|
if [[ "$resume_phase" != "null" ]]; then
|
|
1042
1091
|
log_info "Resuming from Phase $resume_phase"
|
|
1043
1092
|
fi
|
|
1093
|
+
if [[ "$continuation_pending" == "true" && -n "$active_dev_branch" ]]; then
|
|
1094
|
+
log_info "Continuation pending (${continuation_reason:-context_overflow}); reusing dev branch: $active_dev_branch"
|
|
1095
|
+
log_info "Continuation count: $continuation_count (context overflows: $context_overflow_count)"
|
|
1096
|
+
fi
|
|
1044
1097
|
echo -e "${BOLD}────────────────────────────────────────────────────${NC}"
|
|
1045
1098
|
|
|
1046
1099
|
# Auto-commit any uncommitted workspace changes before starting the pipeline.
|
|
@@ -1073,8 +1126,20 @@ DEPLOY_PROMPT_EOF
|
|
|
1073
1126
|
prizm_git_commit_paths "$_proj_root" "chore($refactor_id): mark in_progress" "$refactor_list"
|
|
1074
1127
|
fi
|
|
1075
1128
|
|
|
1076
|
-
#
|
|
1077
|
-
|
|
1129
|
+
# Continuation base branch from runtime state is authoritative for branch reuse.
|
|
1130
|
+
if [[ "$continuation_pending" == "true" && -n "$base_branch" ]]; then
|
|
1131
|
+
_ORIGINAL_BRANCH="$base_branch"
|
|
1132
|
+
fi
|
|
1133
|
+
|
|
1134
|
+
# Create or reuse per-refactor dev branch (from the now-updated original branch)
|
|
1135
|
+
local _refactor_branch
|
|
1136
|
+
if [[ -n "$DEV_BRANCH" ]]; then
|
|
1137
|
+
_refactor_branch="$DEV_BRANCH"
|
|
1138
|
+
elif [[ "$continuation_pending" == "true" && -n "$active_dev_branch" ]]; then
|
|
1139
|
+
_refactor_branch="$active_dev_branch"
|
|
1140
|
+
else
|
|
1141
|
+
_refactor_branch="refactor/${refactor_id}-$(date +%Y%m%d%H%M)"
|
|
1142
|
+
fi
|
|
1078
1143
|
if branch_create "$_proj_root" "$_refactor_branch" "$_ORIGINAL_BRANCH"; then
|
|
1079
1144
|
_DEV_BRANCH_NAME="$_refactor_branch"
|
|
1080
1145
|
log_info "Dev branch: $_refactor_branch"
|
|
@@ -1084,15 +1149,17 @@ DEPLOY_PROMPT_EOF
|
|
|
1084
1149
|
break
|
|
1085
1150
|
fi
|
|
1086
1151
|
|
|
1152
|
+
while true; do
|
|
1087
1153
|
# Generate session
|
|
1088
1154
|
local session_id run_id
|
|
1089
1155
|
run_id=$(jq -r '.run_id' "$STATE_DIR/pipeline.json")
|
|
1090
1156
|
session_id="${refactor_id}-$(date +%Y%m%d%H%M%S)"
|
|
1091
1157
|
|
|
1092
|
-
local session_dir="$STATE_DIR
|
|
1158
|
+
local session_dir="$STATE_DIR/$refactor_id/sessions/$session_id"
|
|
1093
1159
|
mkdir -p "$session_dir/logs"
|
|
1094
1160
|
|
|
1095
1161
|
local bootstrap_prompt="$session_dir/bootstrap-prompt.md"
|
|
1162
|
+
local continuation_summary_path=".prizmkit/refactor/${refactor_id}/continuation-summary.md"
|
|
1096
1163
|
|
|
1097
1164
|
local main_prompt_args=(
|
|
1098
1165
|
--refactor-list "$refactor_list"
|
|
@@ -1105,6 +1172,19 @@ DEPLOY_PROMPT_EOF
|
|
|
1105
1172
|
--output "$bootstrap_prompt"
|
|
1106
1173
|
)
|
|
1107
1174
|
|
|
1175
|
+
if [[ "$continuation_pending" == "true" ]]; then
|
|
1176
|
+
main_prompt_args+=(
|
|
1177
|
+
--continuation-mode "${continuation_reason:-context_overflow}"
|
|
1178
|
+
--previous-session-id "$previous_session_id"
|
|
1179
|
+
--continuation-count "$continuation_count"
|
|
1180
|
+
--context-overflow-count "$context_overflow_count"
|
|
1181
|
+
--task-type "refactor"
|
|
1182
|
+
--active-dev-branch "$active_dev_branch"
|
|
1183
|
+
--base-branch "$base_branch"
|
|
1184
|
+
--continuation-summary-path "$continuation_summary_path"
|
|
1185
|
+
)
|
|
1186
|
+
fi
|
|
1187
|
+
|
|
1108
1188
|
# Support PIPELINE_MODE env var (set by launch-refactor-daemon.sh --mode)
|
|
1109
1189
|
if [[ -n "${PIPELINE_MODE:-}" ]]; then
|
|
1110
1190
|
main_prompt_args+=(--mode "$PIPELINE_MODE")
|
|
@@ -1122,7 +1202,7 @@ DEPLOY_PROMPT_EOF
|
|
|
1122
1202
|
log_error "Failed to generate bootstrap prompt for $refactor_id"
|
|
1123
1203
|
branch_ensure_return "$_proj_root" "$_ORIGINAL_BRANCH"
|
|
1124
1204
|
_DEV_BRANCH_NAME=""
|
|
1125
|
-
continue
|
|
1205
|
+
continue 2
|
|
1126
1206
|
}
|
|
1127
1207
|
local refactor_model pipeline_mode agent_count critic_enabled
|
|
1128
1208
|
refactor_model=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('model',''))" 2>/dev/null || echo "")
|
|
@@ -1145,6 +1225,11 @@ DEPLOY_PROMPT_EOF
|
|
|
1145
1225
|
log_info "Refactor model: $refactor_model"
|
|
1146
1226
|
fi
|
|
1147
1227
|
|
|
1228
|
+
local continuation_artifact_dir=".prizmkit/refactor/${refactor_id}"
|
|
1229
|
+
local continuation_checkpoint_path="$continuation_artifact_dir/workflow-checkpoint.json"
|
|
1230
|
+
local progress_before progress_after
|
|
1231
|
+
progress_before=$(prizm_context_progress_fingerprint "$_proj_root" "refactor" "$refactor_id" "$continuation_artifact_dir" "$continuation_checkpoint_path")
|
|
1232
|
+
|
|
1148
1233
|
# Spawn session
|
|
1149
1234
|
log_info "Spawning AI CLI session: $session_id"
|
|
1150
1235
|
_SPAWN_RESULT=""
|
|
@@ -1167,7 +1252,37 @@ DEPLOY_PROMPT_EOF
|
|
|
1167
1252
|
local session_status="$_SPAWN_RESULT"
|
|
1168
1253
|
|
|
1169
1254
|
# Merge per-refactor dev branch back to original on success
|
|
1170
|
-
|
|
1255
|
+
local active_dev_branch_for_status="$_DEV_BRANCH_NAME"
|
|
1256
|
+
if [[ "$session_status" == "context_overflow" ]]; then
|
|
1257
|
+
progress_after=$(prizm_context_progress_fingerprint "$_proj_root" "refactor" "$refactor_id" "$continuation_artifact_dir" "$continuation_checkpoint_path")
|
|
1258
|
+
if prizm_context_progress_changed "$progress_before" "$progress_after"; then
|
|
1259
|
+
no_progress_count=0
|
|
1260
|
+
log_info "Context-overflow session made observable progress; continuing on $_DEV_BRANCH_NAME"
|
|
1261
|
+
else
|
|
1262
|
+
no_progress_count=$((no_progress_count + 1))
|
|
1263
|
+
log_warn "Context-overflow session made no observable progress ($no_progress_count consecutive)"
|
|
1264
|
+
fi
|
|
1265
|
+
if [[ "$no_progress_count" -ge 2 ]]; then
|
|
1266
|
+
log_warn "Pausing automatic continuation: context_overflow_without_git_checkpoint_or_artifact_progress"
|
|
1267
|
+
session_status="stalled_context_continuation"
|
|
1268
|
+
else
|
|
1269
|
+
finalize_refactor_status_after_branch_return \
|
|
1270
|
+
"$refactor_id" "$refactor_list" "$session_id" "$session_status" "$MAX_RETRIES" "$MAX_INFRA_RETRIES" "$_ORIGINAL_BRANCH" "$active_dev_branch_for_status" "context_overflow" "$continuation_summary_path" "$no_progress_count" "$progress_after"
|
|
1271
|
+
session_count=$((session_count + 1))
|
|
1272
|
+
total_subagent_calls=$((total_subagent_calls + _SUBAGENT_COUNT))
|
|
1273
|
+
continuation_pending="true"
|
|
1274
|
+
continuation_reason="context_overflow"
|
|
1275
|
+
previous_session_id="$session_id"
|
|
1276
|
+
active_dev_branch="$_DEV_BRANCH_NAME"
|
|
1277
|
+
base_branch="$_ORIGINAL_BRANCH"
|
|
1278
|
+
context_overflow_count=$((context_overflow_count + 1))
|
|
1279
|
+
continuation_count=$((continuation_count + 1))
|
|
1280
|
+
log_info "Launching automatic continuation for $refactor_id on same branch/worktree"
|
|
1281
|
+
continue
|
|
1282
|
+
fi
|
|
1283
|
+
fi
|
|
1284
|
+
|
|
1285
|
+
if [[ "$session_status" == "success" && -n "$_DEV_BRANCH_NAME" ]]; then
|
|
1171
1286
|
if branch_merge "$_proj_root" "$_DEV_BRANCH_NAME" "$_ORIGINAL_BRANCH" "$AUTO_PUSH"; then
|
|
1172
1287
|
_DEV_BRANCH_NAME=""
|
|
1173
1288
|
else
|
|
@@ -1178,14 +1293,13 @@ DEPLOY_PROMPT_EOF
|
|
|
1178
1293
|
elif [[ -n "$_DEV_BRANCH_NAME" ]]; then
|
|
1179
1294
|
# Session failed — preserve dev branch for inspection
|
|
1180
1295
|
log_warn "Session failed — dev branch preserved for inspection: $_DEV_BRANCH_NAME"
|
|
1181
|
-
_DEV_BRANCH_NAME=""
|
|
1182
1296
|
fi
|
|
1183
1297
|
|
|
1184
1298
|
# GUARANTEED: always return to original branch regardless of success/failure/merge outcome
|
|
1185
1299
|
branch_ensure_return "$_proj_root" "$_ORIGINAL_BRANCH"
|
|
1186
1300
|
|
|
1187
1301
|
finalize_refactor_status_after_branch_return \
|
|
1188
|
-
"$refactor_id" "$refactor_list" "$session_id" "$session_status" "$MAX_RETRIES" "$MAX_INFRA_RETRIES"
|
|
1302
|
+
"$refactor_id" "$refactor_list" "$session_id" "$session_status" "$MAX_RETRIES" "$MAX_INFRA_RETRIES" "$_ORIGINAL_BRANCH" "$active_dev_branch_for_status" "context_overflow" "$continuation_summary_path" "$no_progress_count" "${progress_after:-}"
|
|
1189
1303
|
local item_status_after_session="${_SPAWN_ITEM_STATUS:-}"
|
|
1190
1304
|
|
|
1191
1305
|
# Commit refactor status update on the original branch (after guaranteed return)
|
|
@@ -1205,6 +1319,8 @@ DEPLOY_PROMPT_EOF
|
|
|
1205
1319
|
|
|
1206
1320
|
session_count=$((session_count + 1))
|
|
1207
1321
|
total_subagent_calls=$((total_subagent_calls + _SUBAGENT_COUNT))
|
|
1322
|
+
break
|
|
1323
|
+
done
|
|
1208
1324
|
|
|
1209
1325
|
# Stop-on-failure: abort only after the task is actually marked failed.
|
|
1210
1326
|
# Pending retry outcomes, including infrastructure errors, keep running.
|
|
@@ -1263,8 +1379,7 @@ show_help() {
|
|
|
1263
1379
|
echo " STRICT_BEHAVIOR_CHECK Force full test suite after each refactor (default: 1)"
|
|
1264
1380
|
echo " HEARTBEAT_INTERVAL Heartbeat log interval in seconds (default: 30)"
|
|
1265
1381
|
echo " STALE_KILL_THRESHOLD Auto-kill session after N seconds of no progress (default: 900)"
|
|
1266
|
-
echo " MAX_LOG_SIZE
|
|
1267
|
-
echo " LOG_MONITOR_POLL_INTERVAL Log monitor poll interval in seconds (default: 30)"
|
|
1382
|
+
echo " MAX_LOG_SIZE Include passive log-size checkpoint guidance above this threshold (default: 2097152 = 2MB, set 0 to disable)"
|
|
1268
1383
|
echo " STOP_ON_FAILURE Stop pipeline when a task exhausts retries: 0|1 (default: 0)"
|
|
1269
1384
|
echo ""
|
|
1270
1385
|
echo "Examples:"
|
|
@@ -22,6 +22,77 @@ ID_FIELDS = ["feature_id", "bug_id", "refactor_id"]
|
|
|
22
22
|
|
|
23
23
|
LOGGER = setup_logging("check-session-status")
|
|
24
24
|
|
|
25
|
+
CONTEXT_OVERFLOW_CODE = "context_overflow"
|
|
26
|
+
CONTEXT_CODE_VALUES = {
|
|
27
|
+
"context_overflow",
|
|
28
|
+
"context_too_large",
|
|
29
|
+
"context_length_exceeded",
|
|
30
|
+
"model_context_window_exceeded",
|
|
31
|
+
}
|
|
32
|
+
CONTEXT_TEXT_PATTERNS = (
|
|
33
|
+
"input exceeds the context window",
|
|
34
|
+
"context window of this model",
|
|
35
|
+
"context window exceeded",
|
|
36
|
+
"maximum context length exceeded",
|
|
37
|
+
"prompt is too long",
|
|
38
|
+
"too many tokens",
|
|
39
|
+
"input token count exceeds",
|
|
40
|
+
)
|
|
41
|
+
REQUEST_TOO_LARGE_TEXT = "request too large"
|
|
42
|
+
REQUEST_TOO_LARGE_SEMANTICS = ("context", "token", "tokens", "prompt", "input", "model")
|
|
43
|
+
ERROR_LIKE_STATUSES = {"failed", "crashed", "timed_out", "context_overflow"}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _flatten_values(value):
|
|
47
|
+
if isinstance(value, dict):
|
|
48
|
+
values = []
|
|
49
|
+
for child in value.values():
|
|
50
|
+
values.extend(_flatten_values(child))
|
|
51
|
+
return values
|
|
52
|
+
if isinstance(value, list):
|
|
53
|
+
values = []
|
|
54
|
+
for child in value:
|
|
55
|
+
values.extend(_flatten_values(child))
|
|
56
|
+
return values
|
|
57
|
+
if value is None:
|
|
58
|
+
return []
|
|
59
|
+
return [str(value)]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _is_error_like_status(data):
|
|
63
|
+
status = str(data.get("status", "")).lower()
|
|
64
|
+
if status in ERROR_LIKE_STATUSES:
|
|
65
|
+
return True
|
|
66
|
+
if data.get("last_result_is_error") is True or data.get("is_error") is True:
|
|
67
|
+
return True
|
|
68
|
+
if data.get("api_error_status") not in (None, ""):
|
|
69
|
+
return True
|
|
70
|
+
errors = data.get("errors")
|
|
71
|
+
return isinstance(errors, list) and len(errors) > 0
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def has_context_overflow_signal(data):
|
|
75
|
+
"""Return true when session-status data carries a context overflow signal.
|
|
76
|
+
|
|
77
|
+
Success remains success: direct status handling happens before this helper.
|
|
78
|
+
Exact machine codes are accepted only from structured code fields. Natural
|
|
79
|
+
language context/token phrases require a failed/error-like status or an
|
|
80
|
+
explicit error field to avoid prompt/documentation false positives.
|
|
81
|
+
"""
|
|
82
|
+
if not isinstance(data, dict):
|
|
83
|
+
return False
|
|
84
|
+
for field in ("fatal_error_code", "api_error_code", "error_code", "stop_reason"):
|
|
85
|
+
value = data.get(field)
|
|
86
|
+
if isinstance(value, str) and value.lower() in CONTEXT_CODE_VALUES:
|
|
87
|
+
return True
|
|
88
|
+
if not _is_error_like_status(data):
|
|
89
|
+
return False
|
|
90
|
+
text = " ".join(_flatten_values(data)).lower()
|
|
91
|
+
if any(pattern in text for pattern in CONTEXT_TEXT_PATTERNS):
|
|
92
|
+
return True
|
|
93
|
+
return REQUEST_TOO_LARGE_TEXT in text and any(
|
|
94
|
+
semantic in text for semantic in REQUEST_TOO_LARGE_SEMANTICS
|
|
95
|
+
)
|
|
25
96
|
|
|
26
97
|
def parse_args():
|
|
27
98
|
parser = argparse.ArgumentParser(
|
|
@@ -79,12 +150,14 @@ def determine_status(data):
|
|
|
79
150
|
"""Determine the single-line status string from the parsed data.
|
|
80
151
|
|
|
81
152
|
Returns one of: success, partial_resumable, partial_not_resumable,
|
|
82
|
-
failed, commit_missing, docs_missing, merge_conflict.
|
|
153
|
+
failed, commit_missing, docs_missing, merge_conflict, context_overflow.
|
|
83
154
|
"""
|
|
84
155
|
status = data.get("status", "")
|
|
85
156
|
|
|
86
157
|
if status == "success":
|
|
87
158
|
return "success"
|
|
159
|
+
if status == "context_overflow" or has_context_overflow_signal(data):
|
|
160
|
+
return "context_overflow"
|
|
88
161
|
elif status == "partial":
|
|
89
162
|
can_resume = data.get("can_resume", False)
|
|
90
163
|
if can_resume:
|