prizmkit 1.1.99 → 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.
Files changed (57) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/dev-pipeline/lib/common.sh +244 -25
  3. package/bundled/dev-pipeline/reset-bug.sh +30 -0
  4. package/bundled/dev-pipeline/reset-feature.sh +30 -0
  5. package/bundled/dev-pipeline/reset-refactor.sh +30 -0
  6. package/bundled/dev-pipeline/run-bugfix.sh +128 -13
  7. package/bundled/dev-pipeline/run-feature.sh +130 -14
  8. package/bundled/dev-pipeline/run-refactor.sh +128 -13
  9. package/bundled/dev-pipeline/scripts/check-session-status.py +74 -1
  10. package/bundled/dev-pipeline/scripts/continuation.py +374 -0
  11. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +27 -30
  12. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +15 -20
  13. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +15 -20
  14. package/bundled/dev-pipeline/scripts/parse-stream-progress.py +146 -16
  15. package/bundled/dev-pipeline/scripts/update-bug-status.py +214 -6
  16. package/bundled/dev-pipeline/scripts/update-feature-status.py +237 -6
  17. package/bundled/dev-pipeline/scripts/update-refactor-status.py +214 -6
  18. package/bundled/dev-pipeline/templates/agent-prompts/dev-implement.md +1 -1
  19. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +2 -2
  20. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +3 -3
  21. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +3 -3
  22. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +1 -1
  23. package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +3 -3
  24. package/bundled/dev-pipeline/templates/sections/log-size-awareness.md +31 -66
  25. package/bundled/dev-pipeline/templates/session-status-schema.json +1 -1
  26. package/bundled/dev-pipeline/tests/conftest.py +1 -0
  27. package/bundled/dev-pipeline/tests/test_auto_skip.py +510 -0
  28. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +103 -0
  29. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +60 -0
  30. package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +43 -0
  31. package/bundled/dev-pipeline-windows/lib/common.ps1 +172 -10
  32. package/bundled/dev-pipeline-windows/lib/pipeline.ps1 +93 -9
  33. package/bundled/dev-pipeline-windows/lib/reset.ps1 +34 -0
  34. package/bundled/dev-pipeline-windows/reset-bug.ps1 +1 -0
  35. package/bundled/dev-pipeline-windows/reset-feature.ps1 +1 -0
  36. package/bundled/dev-pipeline-windows/reset-refactor.ps1 +1 -0
  37. package/bundled/dev-pipeline-windows/scripts/check-session-status.py +74 -1
  38. package/bundled/dev-pipeline-windows/scripts/continuation.py +374 -0
  39. package/bundled/dev-pipeline-windows/scripts/generate-bootstrap-prompt.py +27 -30
  40. package/bundled/dev-pipeline-windows/scripts/generate-bugfix-prompt.py +16 -20
  41. package/bundled/dev-pipeline-windows/scripts/generate-refactor-prompt.py +16 -20
  42. package/bundled/dev-pipeline-windows/scripts/parse-stream-progress.py +146 -16
  43. package/bundled/dev-pipeline-windows/scripts/update-bug-status.py +214 -6
  44. package/bundled/dev-pipeline-windows/scripts/update-feature-status.py +237 -6
  45. package/bundled/dev-pipeline-windows/scripts/update-refactor-status.py +214 -6
  46. package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-implement.md +1 -1
  47. package/bundled/dev-pipeline-windows/templates/bootstrap-tier1.md +2 -2
  48. package/bundled/dev-pipeline-windows/templates/bootstrap-tier2.md +3 -3
  49. package/bundled/dev-pipeline-windows/templates/bootstrap-tier3.md +3 -3
  50. package/bundled/dev-pipeline-windows/templates/bugfix-bootstrap-prompt.md +1 -1
  51. package/bundled/dev-pipeline-windows/templates/refactor-bootstrap-prompt.md +3 -3
  52. package/bundled/dev-pipeline-windows/templates/sections/log-size-awareness.md +31 -68
  53. package/bundled/dev-pipeline-windows/templates/session-status-schema.json +1 -1
  54. package/bundled/skills/_metadata.json +1 -1
  55. package/package.json +1 -1
  56. package/bundled/dev-pipeline/scripts/monitor-log.sh +0 -104
  57. 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 Session log size threshold for compact warning (default: 2097152 = 2MB, set 0 to disable)
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 bugfix/pipeline-{run_id})
29
28
  # AUTO_PUSH Auto-push to remote after successful bug fix (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.
@@ -139,6 +138,16 @@ spawn_and_wait_session() {
139
138
  log_warn "Session was stale-killed by heartbeat monitor (no progress for too long)"
140
139
  fi
141
140
 
141
+ local was_context_overflow=false
142
+ if prizm_detect_context_overflow_error "$session_log" "$progress_json"; then
143
+ was_context_overflow=true
144
+ fi
145
+
146
+ local was_ai_runtime_error=false
147
+ if prizm_detect_ai_runtime_error "$session_log" "$progress_json"; then
148
+ was_ai_runtime_error=true
149
+ fi
150
+
142
151
  local was_infra_error=false
143
152
  if [[ $exit_code -ne 0 ]] && prizm_detect_infra_error "$session_log" "$progress_json"; then
144
153
  was_infra_error=true
@@ -162,7 +171,22 @@ spawn_and_wait_session() {
162
171
  project_root="$PROJECT_ROOT"
163
172
  local default_branch="$base_branch"
164
173
 
165
- if [[ "$was_infra_error" == true ]]; then
174
+ local has_commits=""
175
+ if git -C "$project_root" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
176
+ has_commits=$(git -C "$project_root" log "${default_branch}..HEAD" --oneline 2>/dev/null | head -1)
177
+ fi
178
+
179
+ if [[ -n "$has_commits" ]]; then
180
+ session_status="success"
181
+ elif [[ "$was_context_overflow" == true ]]; then
182
+ log_warn "Session failed because the AI CLI exceeded the model context window"
183
+ log_warn "Context overflow is retried without consuming code retry budget"
184
+ session_status="context_overflow"
185
+ elif [[ "$was_ai_runtime_error" == true ]]; then
186
+ log_warn "Session failed due to structured AI runtime error"
187
+ log_warn "AI runtime errors are retried without consuming code retry budget"
188
+ session_status="infra_error"
189
+ elif [[ "$was_infra_error" == true ]]; then
166
190
  log_warn "Session failed due to AI CLI/provider infrastructure error"
167
191
  log_warn "Infrastructure errors are retried without consuming code retry budget"
168
192
  session_status="infra_error"
@@ -273,6 +297,12 @@ finalize_bug_status_after_branch_return() {
273
297
  local session_status="$4"
274
298
  local max_retries="$5"
275
299
  local max_infra_retries="$6"
300
+ local base_branch="${7:-main}"
301
+ local active_dev_branch="${8:-}"
302
+ local fatal_error_code="${9:-}"
303
+ local continuation_summary_path="${10:-}"
304
+ local no_progress_count="${11:-0}"
305
+ local progress_fingerprint="${12:-}"
276
306
 
277
307
  # Update bug status on the original branch. The caller commits the resulting
278
308
  # bug-list diff immediately after this helper returns.
@@ -285,6 +315,12 @@ finalize_bug_status_after_branch_return() {
285
315
  --session-id "$session_id" \
286
316
  --max-retries "$max_retries" \
287
317
  --max-infra-retries "$max_infra_retries" \
318
+ --active-dev-branch "$active_dev_branch" \
319
+ --base-branch "$base_branch" \
320
+ --last-fatal-error-code "$fatal_error_code" \
321
+ --continuation-summary-path "$continuation_summary_path" \
322
+ --no-progress-count "$no_progress_count" \
323
+ --progress-fingerprint "$progress_fingerprint" \
288
324
  --action update) || {
289
325
  log_error "Failed to update bug status: $update_output"
290
326
  update_output=""
@@ -723,6 +759,11 @@ else:
723
759
  "$bootstrap_prompt" "$session_dir" "$MAX_RETRIES" "$MAX_INFRA_RETRIES" "$bug_model" "$_ORIGINAL_BRANCH"
724
760
  local session_status="$_SPAWN_RESULT"
725
761
 
762
+ local active_dev_branch_for_status="$_DEV_BRANCH_NAME"
763
+ local continuation_summary_path=""
764
+ local no_progress_count=0
765
+ local progress_after=""
766
+
726
767
  # Merge dev branch back to original on success
727
768
  if [[ "$session_status" == "success" && -n "$_DEV_BRANCH_NAME" ]]; then
728
769
  if branch_merge "$_proj_root" "$_DEV_BRANCH_NAME" "$_ORIGINAL_BRANCH" "$AUTO_PUSH"; then
@@ -742,7 +783,7 @@ else:
742
783
  branch_ensure_return "$_proj_root" "$_ORIGINAL_BRANCH"
743
784
 
744
785
  finalize_bug_status_after_branch_return \
745
- "$bug_id" "$bug_list" "$session_id" "$session_status" "$MAX_RETRIES" "$MAX_INFRA_RETRIES"
786
+ "$bug_id" "$bug_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:-}"
746
787
 
747
788
  # Commit bug status update on the original branch (after guaranteed return)
748
789
  if ! git -C "$_proj_root" diff --quiet "$bug_list" 2>/dev/null; then
@@ -991,13 +1032,21 @@ DEPLOY_PROMPT_EOF
991
1032
  fi
992
1033
 
993
1034
  # Parse bug info
994
- local bug_id bug_title bug_severity retry_count infra_error_count resume_phase
1035
+ local bug_id bug_title bug_severity 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
995
1036
  bug_id=$(echo "$next_bug" | jq -r '.bug_id')
996
1037
  bug_title=$(echo "$next_bug" | jq -r '.title')
997
1038
  bug_severity=$(echo "$next_bug" | jq -r '.severity')
998
1039
  retry_count=$(echo "$next_bug" | jq -r '.retry_count // 0')
999
1040
  infra_error_count=$(echo "$next_bug" | jq -r '.infra_error_count // 0')
1000
1041
  resume_phase=$(echo "$next_bug" | jq -r '.resume_from_phase // "null"')
1042
+ active_dev_branch=$(echo "$next_bug" | jq -r '.active_dev_branch // ""')
1043
+ base_branch=$(echo "$next_bug" | jq -r '.base_branch // ""')
1044
+ continuation_pending=$(echo "$next_bug" | jq -r '.continuation_pending // false')
1045
+ continuation_reason=$(echo "$next_bug" | jq -r '.continuation_reason // ""')
1046
+ context_overflow_count=$(echo "$next_bug" | jq -r '.context_overflow_count // 0')
1047
+ continuation_count=$(echo "$next_bug" | jq -r '.continuation_count // 0')
1048
+ previous_session_id=$(echo "$next_bug" | jq -r '.last_context_overflow_session_id // ""')
1049
+ no_progress_count=$(echo "$next_bug" | jq -r '.no_progress_count // 0')
1001
1050
 
1002
1051
  echo ""
1003
1052
  echo -e "${BOLD}────────────────────────────────────────────────────${NC}"
@@ -1008,6 +1057,10 @@ DEPLOY_PROMPT_EOF
1008
1057
  if [[ "$resume_phase" != "null" ]]; then
1009
1058
  log_info "Resuming from Phase $resume_phase"
1010
1059
  fi
1060
+ if [[ "$continuation_pending" == "true" && -n "$active_dev_branch" ]]; then
1061
+ log_info "Continuation pending (${continuation_reason:-context_overflow}); reusing dev branch: $active_dev_branch"
1062
+ log_info "Continuation count: $continuation_count (context overflows: $context_overflow_count)"
1063
+ fi
1011
1064
  echo -e "${BOLD}────────────────────────────────────────────────────${NC}"
1012
1065
 
1013
1066
  # Auto-commit any uncommitted workspace changes before starting the pipeline.
@@ -1040,8 +1093,20 @@ DEPLOY_PROMPT_EOF
1040
1093
  prizm_git_commit_paths "$_proj_root" "chore($bug_id): mark in_progress" "$bug_list"
1041
1094
  fi
1042
1095
 
1043
- # Create per-bug dev branch (from the now-updated original branch)
1044
- local _bug_branch="${DEV_BRANCH:-bugfix/${bug_id}-$(date +%Y%m%d%H%M)}"
1096
+ # Continuation base branch from runtime state is authoritative for branch reuse.
1097
+ if [[ "$continuation_pending" == "true" && -n "$base_branch" ]]; then
1098
+ _ORIGINAL_BRANCH="$base_branch"
1099
+ fi
1100
+
1101
+ # Create or reuse per-bug dev branch (from the now-updated original branch)
1102
+ local _bug_branch
1103
+ if [[ -n "$DEV_BRANCH" ]]; then
1104
+ _bug_branch="$DEV_BRANCH"
1105
+ elif [[ "$continuation_pending" == "true" && -n "$active_dev_branch" ]]; then
1106
+ _bug_branch="$active_dev_branch"
1107
+ else
1108
+ _bug_branch="bugfix/${bug_id}-$(date +%Y%m%d%H%M)"
1109
+ fi
1045
1110
  if branch_create "$_proj_root" "$_bug_branch" "$_ORIGINAL_BRANCH"; then
1046
1111
  _DEV_BRANCH_NAME="$_bug_branch"
1047
1112
  log_info "Dev branch: $_bug_branch"
@@ -1051,6 +1116,7 @@ DEPLOY_PROMPT_EOF
1051
1116
  break
1052
1117
  fi
1053
1118
 
1119
+ while true; do
1054
1120
  # Generate session
1055
1121
  local session_id run_id
1056
1122
  run_id=$(jq -r '.run_id' "$STATE_DIR/pipeline.json")
@@ -1060,6 +1126,7 @@ DEPLOY_PROMPT_EOF
1060
1126
  mkdir -p "$session_dir/logs"
1061
1127
 
1062
1128
  local bootstrap_prompt="$session_dir/bootstrap-prompt.md"
1129
+ local continuation_summary_path=".prizmkit/bugfix/${bug_id}/continuation-summary.md"
1063
1130
 
1064
1131
  local main_prompt_args=(
1065
1132
  --bug-list "$bug_list"
@@ -1072,6 +1139,19 @@ DEPLOY_PROMPT_EOF
1072
1139
  --output "$bootstrap_prompt"
1073
1140
  )
1074
1141
 
1142
+ if [[ "$continuation_pending" == "true" ]]; then
1143
+ main_prompt_args+=(
1144
+ --continuation-mode "${continuation_reason:-context_overflow}"
1145
+ --previous-session-id "$previous_session_id"
1146
+ --continuation-count "$continuation_count"
1147
+ --context-overflow-count "$context_overflow_count"
1148
+ --task-type "bugfix"
1149
+ --active-dev-branch "$active_dev_branch"
1150
+ --base-branch "$base_branch"
1151
+ --continuation-summary-path "$continuation_summary_path"
1152
+ )
1153
+ fi
1154
+
1075
1155
  # Support PIPELINE_MODE env var (set by launch-bugfix-daemon.sh --mode)
1076
1156
  if [[ -n "${PIPELINE_MODE:-}" ]]; then
1077
1157
  main_prompt_args+=(--mode "$PIPELINE_MODE")
@@ -1089,7 +1169,7 @@ DEPLOY_PROMPT_EOF
1089
1169
  log_error "Failed to generate bootstrap prompt for $bug_id"
1090
1170
  branch_ensure_return "$_proj_root" "$_ORIGINAL_BRANCH"
1091
1171
  _DEV_BRANCH_NAME=""
1092
- continue
1172
+ continue 2
1093
1173
  }
1094
1174
  local bug_model pipeline_mode agent_count critic_enabled
1095
1175
  bug_model=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('model',''))" 2>/dev/null || echo "")
@@ -1111,6 +1191,11 @@ DEPLOY_PROMPT_EOF
1111
1191
  log_info "Bug model: $bug_model"
1112
1192
  fi
1113
1193
 
1194
+ local continuation_artifact_dir=".prizmkit/bugfix/${bug_id}"
1195
+ local continuation_checkpoint_path="$continuation_artifact_dir/workflow-checkpoint.json"
1196
+ local progress_before progress_after
1197
+ progress_before=$(prizm_context_progress_fingerprint "$_proj_root" "bugfix" "$bug_id" "$continuation_artifact_dir" "$continuation_checkpoint_path")
1198
+
1114
1199
  # Spawn session
1115
1200
  log_info "Spawning AI CLI session: $session_id"
1116
1201
  _SPAWN_RESULT=""
@@ -1123,7 +1208,37 @@ DEPLOY_PROMPT_EOF
1123
1208
  local session_status="$_SPAWN_RESULT"
1124
1209
 
1125
1210
  # Merge per-bug dev branch back to original on success
1126
- if [[ "$session_status" == "success" && -n "$_DEV_BRANCH_NAME" ]]; then
1211
+ local active_dev_branch_for_status="$_DEV_BRANCH_NAME"
1212
+ if [[ "$session_status" == "context_overflow" ]]; then
1213
+ progress_after=$(prizm_context_progress_fingerprint "$_proj_root" "bugfix" "$bug_id" "$continuation_artifact_dir" "$continuation_checkpoint_path")
1214
+ if prizm_context_progress_changed "$progress_before" "$progress_after"; then
1215
+ no_progress_count=0
1216
+ log_info "Context-overflow session made observable progress; continuing on $_DEV_BRANCH_NAME"
1217
+ else
1218
+ no_progress_count=$((no_progress_count + 1))
1219
+ log_warn "Context-overflow session made no observable progress ($no_progress_count consecutive)"
1220
+ fi
1221
+ if [[ "$no_progress_count" -ge 2 ]]; then
1222
+ log_warn "Pausing automatic continuation: context_overflow_without_git_checkpoint_or_artifact_progress"
1223
+ session_status="stalled_context_continuation"
1224
+ else
1225
+ finalize_bug_status_after_branch_return \
1226
+ "$bug_id" "$bug_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"
1227
+ session_count=$((session_count + 1))
1228
+ total_subagent_calls=$((total_subagent_calls + _SUBAGENT_COUNT))
1229
+ continuation_pending="true"
1230
+ continuation_reason="context_overflow"
1231
+ previous_session_id="$session_id"
1232
+ active_dev_branch="$_DEV_BRANCH_NAME"
1233
+ base_branch="$_ORIGINAL_BRANCH"
1234
+ context_overflow_count=$((context_overflow_count + 1))
1235
+ continuation_count=$((continuation_count + 1))
1236
+ log_info "Launching automatic continuation for $bug_id on same branch/worktree"
1237
+ continue
1238
+ fi
1239
+ fi
1240
+
1241
+ if [[ "$session_status" == "success" && -n "$_DEV_BRANCH_NAME" ]]; then
1127
1242
  if branch_merge "$_proj_root" "$_DEV_BRANCH_NAME" "$_ORIGINAL_BRANCH" "$AUTO_PUSH"; then
1128
1243
  _DEV_BRANCH_NAME=""
1129
1244
  else
@@ -1134,14 +1249,13 @@ DEPLOY_PROMPT_EOF
1134
1249
  elif [[ -n "$_DEV_BRANCH_NAME" ]]; then
1135
1250
  # Session failed — preserve dev branch for inspection
1136
1251
  log_warn "Session failed — dev branch preserved for inspection: $_DEV_BRANCH_NAME"
1137
- _DEV_BRANCH_NAME=""
1138
1252
  fi
1139
1253
 
1140
1254
  # GUARANTEED: always return to original branch regardless of success/failure/merge outcome
1141
1255
  branch_ensure_return "$_proj_root" "$_ORIGINAL_BRANCH"
1142
1256
 
1143
1257
  finalize_bug_status_after_branch_return \
1144
- "$bug_id" "$bug_list" "$session_id" "$session_status" "$MAX_RETRIES" "$MAX_INFRA_RETRIES"
1258
+ "$bug_id" "$bug_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:-}"
1145
1259
  local item_status_after_session="${_SPAWN_ITEM_STATUS:-}"
1146
1260
 
1147
1261
  # Commit bug status update on the original branch (after guaranteed return)
@@ -1151,6 +1265,8 @@ DEPLOY_PROMPT_EOF
1151
1265
 
1152
1266
  session_count=$((session_count + 1))
1153
1267
  total_subagent_calls=$((total_subagent_calls + _SUBAGENT_COUNT))
1268
+ break
1269
+ done
1154
1270
 
1155
1271
  # Stop-on-failure: abort only after the task is actually marked failed.
1156
1272
  # Pending retry outcomes, including infrastructure errors, keep running.
@@ -1229,8 +1345,7 @@ show_help() {
1229
1345
  echo " VERBOSE Set to 1 for verbose AI CLI output"
1230
1346
  echo " HEARTBEAT_INTERVAL Heartbeat log interval in seconds (default: 30)"
1231
1347
  echo " STALE_KILL_THRESHOLD Auto-kill session after N seconds of no progress (default: 900)"
1232
- echo " MAX_LOG_SIZE Session log size threshold for compact warning (default: 2097152 = 2MB, set 0 to disable)"
1233
- echo " LOG_MONITOR_POLL_INTERVAL Log monitor poll interval in seconds (default: 30)"
1348
+ echo " MAX_LOG_SIZE Include passive log-size checkpoint guidance above this threshold (default: 2097152 = 2MB, set 0 to disable)"
1234
1349
  echo " STOP_ON_FAILURE Stop pipeline when a task exhausts retries: 0|1 (default: 0)"
1235
1350
  echo ""
1236
1351
  echo "Examples:"
@@ -25,8 +25,7 @@ set -euo pipefail
25
25
  # HEARTBEAT_INTERVAL Heartbeat log interval in seconds (default: 30)
26
26
  # STALE_KILL_THRESHOLD Auto-kill session after N seconds of no progress (default: 900)
27
27
  # HEARTBEAT_STALE_THRESHOLD Heartbeat stale threshold in seconds (default: 600)
28
- # MAX_LOG_SIZE Session log size threshold for compact warning (default: 2097152 = 2MB, set 0 to disable)
29
- # LOG_MONITOR_POLL_INTERVAL Log monitor poll interval in seconds (default: 30)
28
+ # MAX_LOG_SIZE Include passive log-size checkpoint guidance above this threshold (default: 2097152 = 2MB, set 0 to disable)
30
29
  # PIPELINE_MODE Override mode for all features: lite|standard|full (used by daemon)
31
30
  # DEV_BRANCH Custom dev branch name (default: auto-generated dev/{feature_id}-YYYYMMDDHHmm)
32
31
  # AUTO_PUSH Auto-push to remote after successful feature (default: 0). Set to 1 to enable.
@@ -150,6 +149,11 @@ spawn_and_wait_session() {
150
149
  log_warn "Session was stale-killed by heartbeat monitor (no progress for too long)"
151
150
  fi
152
151
 
152
+ local was_context_overflow=false
153
+ if prizm_detect_context_overflow_error "$session_log" "$progress_json"; then
154
+ was_context_overflow=true
155
+ fi
156
+
153
157
  local was_infra_error=false
154
158
  if [[ $exit_code -ne 0 ]] && prizm_detect_infra_error "$session_log" "$progress_json"; then
155
159
  was_infra_error=true
@@ -187,13 +191,17 @@ spawn_and_wait_session() {
187
191
  semantic_finalized=true
188
192
  semantic_feature_slug="$PRIZM_SEMANTIC_FEATURE_SLUG"
189
193
  semantic_commit_sha="$PRIZM_SEMANTIC_COMMIT_SHA"
190
- if [[ $exit_code -ne 0 || "$was_stale_killed" == true || "$was_ai_runtime_error" == true ]]; then
194
+ if [[ $exit_code -ne 0 || "$was_stale_killed" == true || "$was_context_overflow" == true || "$was_ai_runtime_error" == true ]]; then
191
195
  log_warn "Session ended with a failure signal after semantic completion; treating as finalized success"
192
196
  log_warn "Semantic completion commit: ${semantic_commit_sha:-unknown}"
193
197
  fi
194
198
  session_status="success"
199
+ elif [[ "$was_context_overflow" == true ]]; then
200
+ log_warn "Session failed because the AI CLI exceeded the model context window"
201
+ log_warn "Context overflow is retried without consuming code retry budget"
202
+ session_status="context_overflow"
195
203
  elif [[ "$was_ai_runtime_error" == true ]]; then
196
- log_warn "Session failed due to structured AI runtime/context error"
204
+ log_warn "Session failed due to structured AI runtime error"
197
205
  log_warn "AI runtime errors are retried without consuming code retry budget"
198
206
  session_status="infra_error"
199
207
  elif [[ "$was_infra_error" == true ]]; then
@@ -368,6 +376,11 @@ finalize_feature_status_after_branch_return() {
368
376
  local max_infra_retries="$6"
369
377
  local session_dir="$7"
370
378
  local base_branch="${8:-main}"
379
+ local active_dev_branch="${9:-}"
380
+ local fatal_error_code="${10:-}"
381
+ local continuation_summary_path="${11:-}"
382
+ local no_progress_count="${12:-0}"
383
+ local progress_fingerprint="${13:-}"
371
384
 
372
385
  local feature_slug="${_SPAWN_FEATURE_SLUG:-}"
373
386
  local progress_json="$session_dir/logs/progress.json"
@@ -404,6 +417,12 @@ finalize_feature_status_after_branch_return() {
404
417
  --session-id "$session_id" \
405
418
  --max-retries "$max_retries" \
406
419
  --max-infra-retries "$max_infra_retries" \
420
+ --active-dev-branch "$active_dev_branch" \
421
+ --base-branch "$base_branch" \
422
+ --last-fatal-error-code "$fatal_error_code" \
423
+ --continuation-summary-path "$continuation_summary_path" \
424
+ --no-progress-count "$no_progress_count" \
425
+ --progress-fingerprint "$progress_fingerprint" \
407
426
  --action update) || {
408
427
  log_error "Failed to update feature status: $update_output"
409
428
  log_error ".prizmkit/plans/feature-list.json may be out of sync. Manual intervention needed."
@@ -916,6 +935,11 @@ else:
916
935
  "$bootstrap_prompt" "$session_dir" "$MAX_RETRIES" "$feature_model" "$_ORIGINAL_BRANCH"
917
936
  local session_status="$_SPAWN_RESULT"
918
937
 
938
+ local active_dev_branch_for_status="$_DEV_BRANCH_NAME"
939
+ local continuation_summary_path=""
940
+ local no_progress_count=0
941
+ local progress_after=""
942
+
919
943
  # Merge dev branch back to original on success
920
944
  if [[ "$session_status" == "success" && -n "$_DEV_BRANCH_NAME" ]]; then
921
945
  if branch_merge "$_proj_root" "$_DEV_BRANCH_NAME" "$_ORIGINAL_BRANCH" "$AUTO_PUSH"; then
@@ -935,7 +959,7 @@ else:
935
959
  branch_ensure_return "$_proj_root" "$_ORIGINAL_BRANCH"
936
960
 
937
961
  finalize_feature_status_after_branch_return \
938
- "$feature_id" "$feature_list" "$session_id" "$session_status" "$MAX_RETRIES" "$MAX_INFRA_RETRIES" "$session_dir" "$_ORIGINAL_BRANCH"
962
+ "$feature_id" "$feature_list" "$session_id" "$session_status" "$MAX_RETRIES" "$MAX_INFRA_RETRIES" "$session_dir" "$_ORIGINAL_BRANCH" "$active_dev_branch_for_status" "context_overflow" "$continuation_summary_path" "$no_progress_count" "${progress_after:-}"
939
963
 
940
964
  # Commit feature status update on the original branch (after guaranteed return)
941
965
  if ! git -C "$_proj_root" diff --quiet "$feature_list" 2>/dev/null; then
@@ -1212,12 +1236,20 @@ DEPLOY_PROMPT_EOF
1212
1236
  fi
1213
1237
 
1214
1238
  # Parse feature info
1215
- local feature_id feature_title retry_count infra_error_count resume_phase
1239
+ local feature_id feature_title 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
1216
1240
  feature_id=$(echo "$next_feature" | jq -r '.feature_id')
1217
1241
  feature_title=$(echo "$next_feature" | jq -r '.title')
1218
1242
  retry_count=$(echo "$next_feature" | jq -r '.retry_count // 0')
1219
1243
  infra_error_count=$(echo "$next_feature" | jq -r '.infra_error_count // 0')
1220
1244
  resume_phase=$(echo "$next_feature" | jq -r '.resume_from_phase // "null"')
1245
+ active_dev_branch=$(echo "$next_feature" | jq -r '.active_dev_branch // ""')
1246
+ base_branch=$(echo "$next_feature" | jq -r '.base_branch // ""')
1247
+ continuation_pending=$(echo "$next_feature" | jq -r '.continuation_pending // false')
1248
+ continuation_reason=$(echo "$next_feature" | jq -r '.continuation_reason // ""')
1249
+ context_overflow_count=$(echo "$next_feature" | jq -r '.context_overflow_count // 0')
1250
+ continuation_count=$(echo "$next_feature" | jq -r '.continuation_count // 0')
1251
+ previous_session_id=$(echo "$next_feature" | jq -r '.last_context_overflow_session_id // ""')
1252
+ no_progress_count=$(echo "$next_feature" | jq -r '.no_progress_count // 0')
1221
1253
 
1222
1254
  echo ""
1223
1255
  echo -e "${BOLD}────────────────────────────────────────────────────${NC}"
@@ -1227,6 +1259,10 @@ DEPLOY_PROMPT_EOF
1227
1259
  if [[ "$resume_phase" != "null" ]]; then
1228
1260
  log_info "Resuming from Phase $resume_phase"
1229
1261
  fi
1262
+ if [[ "$continuation_pending" == "true" && -n "$active_dev_branch" ]]; then
1263
+ log_info "Continuation pending (${continuation_reason:-context_overflow}); reusing dev branch: $active_dev_branch"
1264
+ log_info "Continuation count: $continuation_count (context overflows: $context_overflow_count)"
1265
+ fi
1230
1266
  echo -e "${BOLD}────────────────────────────────────────────────────${NC}"
1231
1267
 
1232
1268
  # Auto-commit any uncommitted workspace changes before starting the pipeline.
@@ -1259,8 +1295,20 @@ DEPLOY_PROMPT_EOF
1259
1295
  prizm_git_commit_paths "$_proj_root" "chore($feature_id): mark in_progress" "$feature_list"
1260
1296
  fi
1261
1297
 
1262
- # Create per-feature dev branch (from the now-updated original branch)
1263
- local _feature_branch="${DEV_BRANCH:-dev/${feature_id}-$(date +%Y%m%d%H%M)}"
1298
+ # Continuation base branch from runtime state is authoritative for branch reuse.
1299
+ if [[ "$continuation_pending" == "true" && -n "$base_branch" ]]; then
1300
+ _ORIGINAL_BRANCH="$base_branch"
1301
+ fi
1302
+
1303
+ # Create or reuse per-feature dev branch (from the now-updated original branch)
1304
+ local _feature_branch
1305
+ if [[ -n "$DEV_BRANCH" ]]; then
1306
+ _feature_branch="$DEV_BRANCH"
1307
+ elif [[ "$continuation_pending" == "true" && -n "$active_dev_branch" ]]; then
1308
+ _feature_branch="$active_dev_branch"
1309
+ else
1310
+ _feature_branch="dev/${feature_id}-$(date +%Y%m%d%H%M)"
1311
+ fi
1264
1312
  if branch_create "$_proj_root" "$_feature_branch" "$_ORIGINAL_BRANCH"; then
1265
1313
  _DEV_BRANCH_NAME="$_feature_branch"
1266
1314
  log_info "Dev branch: $_feature_branch"
@@ -1270,6 +1318,7 @@ DEPLOY_PROMPT_EOF
1270
1318
  break
1271
1319
  fi
1272
1320
 
1321
+ while true; do
1273
1322
  # Generate session ID and bootstrap prompt
1274
1323
  local session_id run_id
1275
1324
  run_id=$(jq -r '.run_id' "$STATE_DIR/pipeline.json")
@@ -1279,6 +1328,23 @@ DEPLOY_PROMPT_EOF
1279
1328
  mkdir -p "$session_dir/logs"
1280
1329
 
1281
1330
  local bootstrap_prompt="$session_dir/bootstrap-prompt.md"
1331
+ local continuation_summary_path
1332
+ continuation_summary_path=$(python3 -c "
1333
+ import json, re, sys
1334
+ feature_list, feature_id = sys.argv[1], sys.argv[2]
1335
+ with open(feature_list) as f:
1336
+ data = json.load(f)
1337
+ for feature in data.get('features', []):
1338
+ if feature.get('id') == feature_id:
1339
+ numeric = feature_id.replace('F-', '').replace('f-', '').zfill(3)
1340
+ title = feature.get('title', '').lower()
1341
+ title = re.sub(r'[^a-z0-9\s-]', '', title)
1342
+ title = re.sub(r'[\s]+', '-', title.strip())
1343
+ title = re.sub(r'-+', '-', title).strip('-')
1344
+ print(f'.prizmkit/specs/{numeric}-{title}/continuation-summary.md')
1345
+ sys.exit(0)
1346
+ sys.exit(1)
1347
+ " "$feature_list" "$feature_id" 2>/dev/null || echo "")
1282
1348
 
1283
1349
  local main_prompt_args=(
1284
1350
  --feature-list "$feature_list"
@@ -1291,6 +1357,21 @@ DEPLOY_PROMPT_EOF
1291
1357
  --output "$bootstrap_prompt"
1292
1358
  )
1293
1359
 
1360
+ if [[ "$continuation_pending" == "true" ]]; then
1361
+ main_prompt_args+=(
1362
+ --continuation-mode "${continuation_reason:-context_overflow}"
1363
+ --previous-session-id "$previous_session_id"
1364
+ --continuation-count "$continuation_count"
1365
+ --context-overflow-count "$context_overflow_count"
1366
+ --task-type "feature"
1367
+ --active-dev-branch "$active_dev_branch"
1368
+ --base-branch "$base_branch"
1369
+ )
1370
+ if [[ -n "$continuation_summary_path" ]]; then
1371
+ main_prompt_args+=(--continuation-summary-path "$continuation_summary_path")
1372
+ fi
1373
+ fi
1374
+
1294
1375
  # Support PIPELINE_MODE env var (set by launch-feature-daemon.sh --mode)
1295
1376
  if [[ -n "${PIPELINE_MODE:-}" ]]; then
1296
1377
  main_prompt_args+=(--mode "$PIPELINE_MODE")
@@ -1308,7 +1389,7 @@ DEPLOY_PROMPT_EOF
1308
1389
  log_error "Failed to generate bootstrap prompt for $feature_id"
1309
1390
  branch_ensure_return "$_proj_root" "$_ORIGINAL_BRANCH"
1310
1391
  _DEV_BRANCH_NAME=""
1311
- continue
1392
+ continue 2
1312
1393
  }
1313
1394
  local feature_model pipeline_mode agent_count critic_enabled
1314
1395
  feature_model=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('model',''))" 2>/dev/null || echo "")
@@ -1327,6 +1408,11 @@ DEPLOY_PROMPT_EOF
1327
1408
  log_info "Pipeline mode: ${BOLD}$pipeline_mode${NC} ($_mode_desc)"
1328
1409
  log_info "Agents: $agent_count (critic: $([ "$critic_enabled" = "true" ] && echo "enabled" || echo "disabled"))"
1329
1410
 
1411
+ local continuation_artifact_dir="${continuation_summary_path%/continuation-summary.md}"
1412
+ local continuation_checkpoint_path="$continuation_artifact_dir/workflow-checkpoint.json"
1413
+ local progress_before progress_after
1414
+ progress_before=$(prizm_context_progress_fingerprint "$_proj_root" "feature" "$feature_id" "$continuation_artifact_dir" "$continuation_checkpoint_path")
1415
+
1330
1416
  # Spawn session and wait
1331
1417
  prizm_log_bootstrap_prompt "$bootstrap_prompt" "$feature_id"
1332
1418
  log_info "Spawning AI CLI session: $session_id"
@@ -1342,7 +1428,37 @@ DEPLOY_PROMPT_EOF
1342
1428
  local session_status="$_SPAWN_RESULT"
1343
1429
 
1344
1430
  # Merge per-feature dev branch back to original on success
1345
- if [[ "$session_status" == "success" && -n "$_DEV_BRANCH_NAME" ]]; then
1431
+ local active_dev_branch_for_status="$_DEV_BRANCH_NAME"
1432
+ if [[ "$session_status" == "context_overflow" ]]; then
1433
+ progress_after=$(prizm_context_progress_fingerprint "$_proj_root" "feature" "$feature_id" "$continuation_artifact_dir" "$continuation_checkpoint_path")
1434
+ if prizm_context_progress_changed "$progress_before" "$progress_after"; then
1435
+ no_progress_count=0
1436
+ log_info "Context-overflow session made observable progress; continuing on $_DEV_BRANCH_NAME"
1437
+ else
1438
+ no_progress_count=$((no_progress_count + 1))
1439
+ log_warn "Context-overflow session made no observable progress ($no_progress_count consecutive)"
1440
+ fi
1441
+ if [[ "$no_progress_count" -ge 2 ]]; then
1442
+ log_warn "Pausing automatic continuation: context_overflow_without_git_checkpoint_or_artifact_progress"
1443
+ session_status="stalled_context_continuation"
1444
+ else
1445
+ finalize_feature_status_after_branch_return \
1446
+ "$feature_id" "$feature_list" "$session_id" "$session_status" "$MAX_RETRIES" "$MAX_INFRA_RETRIES" "$session_dir" "$_ORIGINAL_BRANCH" "$active_dev_branch_for_status" "context_overflow" "$continuation_summary_path" "$no_progress_count" "$progress_after"
1447
+ session_count=$((session_count + 1))
1448
+ total_subagent_calls=$((total_subagent_calls + _SUBAGENT_COUNT))
1449
+ continuation_pending="true"
1450
+ continuation_reason="context_overflow"
1451
+ previous_session_id="$session_id"
1452
+ active_dev_branch="$_DEV_BRANCH_NAME"
1453
+ base_branch="$_ORIGINAL_BRANCH"
1454
+ context_overflow_count=$((context_overflow_count + 1))
1455
+ continuation_count=$((continuation_count + 1))
1456
+ log_info "Launching automatic continuation for $feature_id on same branch/worktree"
1457
+ continue
1458
+ fi
1459
+ fi
1460
+
1461
+ if [[ "$session_status" == "success" && -n "$_DEV_BRANCH_NAME" ]]; then
1346
1462
  if branch_merge "$_proj_root" "$_DEV_BRANCH_NAME" "$_ORIGINAL_BRANCH" "$AUTO_PUSH"; then
1347
1463
  _DEV_BRANCH_NAME=""
1348
1464
  else
@@ -1353,14 +1469,13 @@ DEPLOY_PROMPT_EOF
1353
1469
  elif [[ -n "$_DEV_BRANCH_NAME" ]]; then
1354
1470
  # Session failed — preserve dev branch for inspection
1355
1471
  log_warn "Session failed — dev branch preserved for inspection: $_DEV_BRANCH_NAME"
1356
- _DEV_BRANCH_NAME=""
1357
1472
  fi
1358
1473
 
1359
1474
  # GUARANTEED: always return to original branch regardless of success/failure/merge outcome
1360
1475
  branch_ensure_return "$_proj_root" "$_ORIGINAL_BRANCH"
1361
1476
 
1362
1477
  finalize_feature_status_after_branch_return \
1363
- "$feature_id" "$feature_list" "$session_id" "$session_status" "$MAX_RETRIES" "$MAX_INFRA_RETRIES" "$session_dir" "$_ORIGINAL_BRANCH"
1478
+ "$feature_id" "$feature_list" "$session_id" "$session_status" "$MAX_RETRIES" "$MAX_INFRA_RETRIES" "$session_dir" "$_ORIGINAL_BRANCH" "$active_dev_branch_for_status" "context_overflow" "$continuation_summary_path" "$no_progress_count" "${progress_after:-}"
1364
1479
  local item_status_after_session="${_SPAWN_ITEM_STATUS:-}"
1365
1480
 
1366
1481
  # Commit feature status update on the original branch (after guaranteed return)
@@ -1370,6 +1485,8 @@ DEPLOY_PROMPT_EOF
1370
1485
 
1371
1486
  session_count=$((session_count + 1))
1372
1487
  total_subagent_calls=$((total_subagent_calls + _SUBAGENT_COUNT))
1488
+ break
1489
+ done
1373
1490
 
1374
1491
  # Stop-on-failure: abort only after the task is actually marked failed.
1375
1492
  # Pending retry outcomes keep running; both code and infra failures have
@@ -1435,8 +1552,7 @@ show_help() {
1435
1552
  echo " HEARTBEAT_INTERVAL Heartbeat log interval in seconds (default: 30)"
1436
1553
  echo " STALE_KILL_THRESHOLD Auto-kill session after N seconds of no progress (default: 900)"
1437
1554
  echo " HEARTBEAT_STALE_THRESHOLD Heartbeat stale threshold in seconds (default: 600)"
1438
- echo " MAX_LOG_SIZE Session log size threshold for compact warning (default: 2097152 = 2MB, set 0 to disable)"
1439
- echo " LOG_MONITOR_POLL_INTERVAL Log monitor poll interval in seconds (default: 30)"
1555
+ echo " MAX_LOG_SIZE Include passive log-size checkpoint guidance above this threshold (default: 2097152 = 2MB, set 0 to disable)"
1440
1556
  echo " PIPELINE_MODE Override mode for all features: lite|standard|full"
1441
1557
  echo " ENABLE_CRITIC Enable critic review for all features: true|false"
1442
1558
  echo " STOP_ON_FAILURE Stop pipeline when a task exhausts retries: 0|1 (default: 0)"