prizmkit 1.1.92 → 1.1.93

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 (34) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/dev-pipeline/.env.example +0 -4
  3. package/bundled/dev-pipeline/README.md +9 -39
  4. package/bundled/dev-pipeline/SCHEMA_ANALYSIS.md +0 -4
  5. package/bundled/dev-pipeline/assets/prizm-dev-team-integration.md +0 -2
  6. package/bundled/dev-pipeline/launch-bugfix-daemon.sh +0 -1
  7. package/bundled/dev-pipeline/launch-feature-daemon.sh +2 -3
  8. package/bundled/dev-pipeline/launch-refactor-daemon.sh +0 -1
  9. package/bundled/dev-pipeline/run-bugfix.sh +7 -67
  10. package/bundled/dev-pipeline/run-feature.sh +6 -84
  11. package/bundled/dev-pipeline/run-recovery.sh +1 -32
  12. package/bundled/dev-pipeline/run-refactor.sh +6 -68
  13. package/bundled/dev-pipeline/tests/test-deploy-safety.sh +3 -3
  14. package/bundled/dev-pipeline-windows/.env.example +0 -4
  15. package/bundled/dev-pipeline-windows/SCHEMA_ANALYSIS.md +0 -4
  16. package/bundled/dev-pipeline-windows/assets/prizm-dev-team-integration.md +0 -2
  17. package/bundled/dev-pipeline-windows/lib/pipeline.ps1 +13 -90
  18. package/bundled/dev-pipeline-windows/run-recovery.ps1 +4 -19
  19. package/bundled/skills/_metadata.json +1 -1
  20. package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +1 -1
  21. package/bundled/skills/bugfix-pipeline-launcher/references/configuration.md +5 -15
  22. package/bundled/skills/feature-pipeline-launcher/SKILL.md +4 -4
  23. package/bundled/skills/feature-pipeline-launcher/references/configuration.md +3 -13
  24. package/bundled/skills/refactor-pipeline-launcher/SKILL.md +3 -3
  25. package/bundled/skills/refactor-pipeline-launcher/references/configuration.md +4 -14
  26. package/bundled/skills-windows/bugfix-pipeline-launcher/SKILL.md +1 -1
  27. package/bundled/skills-windows/bugfix-pipeline-launcher/references/configuration.md +4 -14
  28. package/bundled/skills-windows/feature-pipeline-launcher/SKILL.md +4 -4
  29. package/bundled/skills-windows/feature-pipeline-launcher/references/configuration.md +2 -12
  30. package/bundled/skills-windows/refactor-pipeline-launcher/SKILL.md +3 -3
  31. package/bundled/skills-windows/refactor-pipeline-launcher/references/configuration.md +4 -14
  32. package/package.json +1 -1
  33. package/bundled/dev-pipeline/scripts/cleanup-logs.py +0 -192
  34. package/bundled/dev-pipeline-windows/scripts/cleanup-logs.py +0 -192
@@ -23,7 +23,6 @@ set -euo pipefail
23
23
  # ./run-recovery.sh help Show help
24
24
  #
25
25
  # Environment Variables:
26
- # SESSION_TIMEOUT Session timeout in seconds (default: 0 = no limit)
27
26
  # AI_CLI AI CLI command name (auto-detected: cbc, claude, or codex)
28
27
  # PRIZMKIT_PLATFORM Platform hint for custom AI_CLI wrappers: codebuddy, claude, or codex
29
28
  # MODEL AI model to use (e.g. claude-opus-4.6)
@@ -62,7 +61,6 @@ if [[ -z "$RECOVERY_DETECT_SCRIPT" ]]; then
62
61
  fi
63
62
 
64
63
  # Configuration
65
- SESSION_TIMEOUT=${SESSION_TIMEOUT:-0}
66
64
  HEARTBEAT_INTERVAL=${HEARTBEAT_INTERVAL:-30}
67
65
  STALE_KILL_THRESHOLD=${STALE_KILL_THRESHOLD:-900}
68
66
  VERBOSE=${VERBOSE:-0}
@@ -108,7 +106,6 @@ Options (for 'run' command):
108
106
  --model M Override AI model (e.g. claude-opus-4.6)
109
107
 
110
108
  Environment Variables:
111
- SESSION_TIMEOUT Session timeout in seconds (default: 0 = no limit)
112
109
  MODEL AI model to use
113
110
  PRIZMKIT_EFFORT AI reasoning effort (low|medium|high|xhigh|max; max is Claude Code only)
114
111
  VERBOSE Set to 1 for verbose AI CLI output
@@ -283,13 +280,6 @@ spawn_recovery_session() {
283
280
  start_progress_parser "$session_log" "$progress_json" "$SCRIPTS_DIR"
284
281
  local parser_pid="${_PARSER_PID:-}"
285
282
 
286
- # Timeout watchdog
287
- local watcher_pid=""
288
- if [[ $SESSION_TIMEOUT -gt 0 ]]; then
289
- ( sleep "$SESSION_TIMEOUT" && kill -TERM "$_SESSION_PID" 2>/dev/null ) &
290
- watcher_pid=$!
291
- fi
292
-
293
283
  # Heartbeat monitor
294
284
  start_heartbeat "$_SESSION_PID" "$session_log" "$progress_json" "$HEARTBEAT_INTERVAL" "$STALE_KILL_THRESHOLD"
295
285
  _HEARTBEAT_PID="${_HEARTBEAT_PID:-}"
@@ -303,17 +293,10 @@ spawn_recovery_session() {
303
293
  fi
304
294
  _SESSION_PID=""
305
295
 
306
- # Cleanup background processes
307
- [[ -n "$watcher_pid" ]] && kill "$watcher_pid" 2>/dev/null || true
296
+ # Clean up heartbeat and parser
308
297
  stop_heartbeat "${_HEARTBEAT_PID:-}"
309
298
  _HEARTBEAT_PID=""
310
299
  stop_progress_parser "$parser_pid"
311
- [[ -n "$watcher_pid" ]] && wait "$watcher_pid" 2>/dev/null || true
312
-
313
- # Map SIGTERM to timeout
314
- if [[ $exit_code -eq 143 ]]; then
315
- exit_code=124
316
- fi
317
300
 
318
301
  # Check for stale-kill
319
302
  local stale_kill_marker="$session_dir/logs/stale-kill.json"
@@ -347,12 +330,6 @@ detect_session_outcome() {
347
330
  local was_stale_killed=false
348
331
  [[ -f "$stale_kill_marker" ]] && was_stale_killed=true
349
332
 
350
- if [[ $exit_code -eq 124 ]]; then
351
- log_warn "Session timed out"
352
- echo "timed_out"
353
- return
354
- fi
355
-
356
333
  if [[ "$was_stale_killed" == true ]]; then
357
334
  log_warn "Session stale-killed"
358
335
  fi
@@ -611,14 +588,6 @@ cmd_run() {
611
588
  echo " • Commit manually: git add <files> && git commit"
612
589
  echo ""
613
590
  ;;
614
- timed_out)
615
- log_warn "Session timed out before completing."
616
- echo ""
617
- echo " Options:"
618
- echo " • Run recovery again: ./run-recovery.sh"
619
- echo " • Increase timeout: SESSION_TIMEOUT=3600 ./run-recovery.sh"
620
- echo ""
621
- ;;
622
591
  no_changes)
623
592
  log_warn "Session completed but produced no changes."
624
593
  echo ""
@@ -16,7 +16,6 @@ set -euo pipefail
16
16
  # Environment Variables:
17
17
  # MAX_RETRIES Max code retries per refactor (default: 3)
18
18
  # MAX_INFRA_RETRIES Max infrastructure/provider retries per refactor (default: 3)
19
- # SESSION_TIMEOUT Session timeout in seconds (default: 0 = no limit)
20
19
  # AI_CLI AI CLI command name (auto-detected: cbc, claude, or codex)
21
20
  # CODEBUDDY_CLI Legacy alias for AI_CLI (deprecated, use AI_CLI instead)
22
21
  # PRIZMKIT_PLATFORM Platform hint for custom AI_CLI wrappers: codebuddy, claude, or codex
@@ -24,9 +23,6 @@ set -euo pipefail
24
23
  # HEARTBEAT_INTERVAL Heartbeat log interval in seconds (default: 30)
25
24
  # STALE_KILL_THRESHOLD Auto-kill session after N seconds of no progress (default: 900)
26
25
  # HEARTBEAT_STALE_THRESHOLD Heartbeat stale threshold in seconds (default: 600)
27
- # LOG_CLEANUP_ENABLED Run periodic log cleanup (default: 1)
28
- # LOG_RETENTION_DAYS Delete logs older than N days (default: 14)
29
- # LOG_MAX_TOTAL_MB Keep total logs under N MB via oldest-first cleanup (default: 1024)
30
26
  # DEV_BRANCH Custom dev branch name (default: auto-generated refactor/pipeline-{run_id})
31
27
  # AUTO_PUSH Auto-push to remote after successful refactor (default: 0). Set to 1 to enable.
32
28
  # STOP_ON_FAILURE Stop pipeline after a task exhausts all retries (default: 0). Set to 1 to stop.
@@ -45,13 +41,9 @@ SCRIPTS_DIR="$SCRIPT_DIR/scripts"
45
41
  # Configuration
46
42
  MAX_RETRIES=${MAX_RETRIES:-3}
47
43
  MAX_INFRA_RETRIES=${MAX_INFRA_RETRIES:-3}
48
- SESSION_TIMEOUT=${SESSION_TIMEOUT:-0}
49
44
  HEARTBEAT_STALE_THRESHOLD=${HEARTBEAT_STALE_THRESHOLD:-600}
50
45
  HEARTBEAT_INTERVAL=${HEARTBEAT_INTERVAL:-30}
51
46
  STALE_KILL_THRESHOLD=${STALE_KILL_THRESHOLD:-900}
52
- LOG_CLEANUP_ENABLED=${LOG_CLEANUP_ENABLED:-1}
53
- LOG_RETENTION_DAYS=${LOG_RETENTION_DAYS:-14}
54
- LOG_MAX_TOTAL_MB=${LOG_MAX_TOTAL_MB:-1024}
55
47
  VERBOSE=${VERBOSE:-0}
56
48
  MODEL=${MODEL:-""}
57
49
  PRIZMKIT_EFFORT=${PRIZMKIT_EFFORT:-""}
@@ -119,13 +111,6 @@ spawn_and_wait_session() {
119
111
  start_progress_parser "$session_log" "$progress_json" "$SCRIPTS_DIR"
120
112
  local parser_pid="${_PARSER_PID:-}"
121
113
 
122
- # Timeout watchdog
123
- local watcher_pid=""
124
- if [[ $SESSION_TIMEOUT -gt 0 ]]; then
125
- ( sleep "$SESSION_TIMEOUT" && kill -TERM "$cli_pid" 2>/dev/null ) &
126
- watcher_pid=$!
127
- fi
128
-
129
114
  # Heartbeat monitor (with stale-kill protection)
130
115
  start_heartbeat "$cli_pid" "$session_log" "$progress_json" "$HEARTBEAT_INTERVAL" "$STALE_KILL_THRESHOLD"
131
116
  local heartbeat_pid="${_HEARTBEAT_PID:-}"
@@ -139,16 +124,12 @@ spawn_and_wait_session() {
139
124
  fi
140
125
 
141
126
  # Cleanup
142
- [[ -n "$watcher_pid" ]] && kill "$watcher_pid" 2>/dev/null || true
143
127
  stop_heartbeat "$heartbeat_pid"
144
128
  stop_progress_parser "$parser_pid"
145
- [[ -n "$watcher_pid" ]] && wait "$watcher_pid" 2>/dev/null || true
146
129
 
147
130
  # Recover session log from backup if truncated by subagent stdout redirection
148
131
  prizm_recover_session_log "$session_log"
149
132
 
150
- [[ $exit_code -eq 143 ]] && exit_code=124
151
-
152
133
  # Check for stale-kill marker (heartbeat killed the process due to no progress)
153
134
  local stale_kill_marker="$session_dir/logs/stale-kill.json"
154
135
  local was_stale_killed=false
@@ -194,10 +175,7 @@ PY
194
175
  project_root="$PROJECT_ROOT"
195
176
  local default_branch="$base_branch"
196
177
 
197
- if [[ $exit_code -eq 124 ]]; then
198
- log_warn "Session timed out after ${SESSION_TIMEOUT}s"
199
- session_status="timed_out"
200
- elif [[ "$was_infra_error" == true ]]; then
178
+ if [[ "$was_infra_error" == true ]]; then
201
179
  log_warn "Session failed due to AI CLI/provider infrastructure error"
202
180
  log_warn "Infrastructure errors are retried without consuming code retry budget"
203
181
  session_status="infra_error"
@@ -426,29 +404,6 @@ check_dependencies() {
426
404
  prizm_ensure_git_repo "$_project_root"
427
405
  }
428
406
 
429
- run_log_cleanup() {
430
- if [[ "$LOG_CLEANUP_ENABLED" != "1" ]]; then
431
- return 0
432
- fi
433
-
434
- local cleanup_result
435
- cleanup_result=$(python3 "$SCRIPTS_DIR/cleanup-logs.py" \
436
- --state-dir "$STATE_DIR" \
437
- --retention-days "$LOG_RETENTION_DAYS" \
438
- --max-total-mb "$LOG_MAX_TOTAL_MB" 2>/dev/null) || {
439
- log_warn "Log cleanup failed (continuing)"
440
- return 0
441
- }
442
-
443
- local deleted reclaimed_kb
444
- deleted=$(echo "$cleanup_result" | python3 -c "import sys,json; print(json.load(sys.stdin).get('deleted_files', 0))" 2>/dev/null || echo "0")
445
- reclaimed_kb=$(echo "$cleanup_result" | python3 -c "import sys,json; print(int(json.load(sys.stdin).get('reclaimed_bytes', 0)/1024))" 2>/dev/null || echo "0")
446
-
447
- if [[ "$deleted" -gt 0 ]]; then
448
- log_info "Log cleanup: deleted $deleted files, reclaimed ${reclaimed_kb}KB"
449
- fi
450
- }
451
-
452
407
  # ============================================================
453
408
  # run-one: Run a single refactor
454
409
  # ============================================================
@@ -467,7 +422,6 @@ run_one() {
467
422
  --dry-run) dry_run=true; shift ;;
468
423
  --clean) do_clean=true; shift ;;
469
424
  --no-reset) no_reset=true; shift ;;
470
- --timeout) shift; SESSION_TIMEOUT="${1:-0}"; shift ;;
471
425
  --max-infra-retries)
472
426
  shift
473
427
  if [[ $# -eq 0 ]]; then
@@ -518,7 +472,6 @@ run_one() {
518
472
  fi
519
473
 
520
474
  check_dependencies
521
- run_log_cleanup
522
475
 
523
476
  # Initialize state if needed
524
477
  if [[ ! -f "$STATE_DIR/pipeline.json" ]]; then
@@ -907,7 +860,6 @@ main() {
907
860
  fi
908
861
 
909
862
  check_dependencies
910
- run_log_cleanup
911
863
 
912
864
  # Initialize pipeline state if needed
913
865
  if [[ ! -f "$STATE_DIR/pipeline.json" ]]; then
@@ -956,11 +908,6 @@ main() {
956
908
  log_info "Refactor list: $refactor_list"
957
909
  log_info "Max code retries per refactor: $MAX_RETRIES"
958
910
  log_info "Max infrastructure retries per refactor: $MAX_INFRA_RETRIES"
959
- if [[ $SESSION_TIMEOUT -gt 0 ]]; then
960
- log_info "Session timeout: ${SESSION_TIMEOUT}s"
961
- else
962
- log_info "Session timeout: none"
963
- fi
964
911
  log_info "AI CLI: $CLI_CMD (platform: $PLATFORM)"
965
912
  if [[ -n "${MODEL:-}" ]]; then
966
913
  log_info "Default Model: $MODEL"
@@ -1112,17 +1059,14 @@ DEPLOY_PROMPT_EOF
1112
1059
  fi
1113
1060
  echo -e "${BOLD}────────────────────────────────────────────────────${NC}"
1114
1061
 
1115
- # Do not auto-commit an arbitrary dirty baseline on the original branch.
1116
- # Only pipeline bookkeeping is committed explicitly; user/source WIP,
1117
- # submodule dirt, specs, and root-level hidden tool temporary worktrees
1118
- # must never be swept into main by a broad git add.
1062
+ # Auto-commit any uncommitted workspace changes before starting the pipeline.
1063
+ # This ensures a clean baseline without blocking execution.
1119
1064
  local _dirty_files=""
1120
1065
  _dirty_files=$(prizm_git_status_non_bookkeeping "$_proj_root" "$STATE_DIR" "$refactor_list" || true)
1121
1066
  if [[ -n "$_dirty_files" ]]; then
1122
- log_error "Dirty working tree detected before $refactor_id; refusing to commit it on $_ORIGINAL_BRANCH."
1123
- log_error "Commit/stash your changes or start from a clean branch, then rerun the pipeline."
1124
- printf '%s\n' "$_dirty_files" | sed 's/^/ /'
1125
- break
1067
+ log_info "Auto-committing workspace changes before $refactor_id..."
1068
+ prizm_git_add_all_safe "$_proj_root"
1069
+ git -C "$_proj_root" commit --no-verify -m "chore: workspace snapshot ready for run $refactor_id" 2>/dev/null || true
1126
1070
  fi
1127
1071
 
1128
1072
  local _bookkeeping_dirty=""
@@ -1315,7 +1259,6 @@ show_help() {
1315
1259
  echo " --dry-run Generate bootstrap prompt only, don't spawn session"
1316
1260
  echo " --clean Delete artifacts and reset before running"
1317
1261
  echo " --no-reset Skip status reset (preserve retry count)"
1318
- echo " --timeout N Session timeout in seconds (default: 0 = no limit)"
1319
1262
  echo " --max-infra-retries N Max infrastructure/provider retries (default: 3)"
1320
1263
  echo " --mode <lite|standard|full> Override pipeline mode"
1321
1264
  echo " --critic Enable adversarial critic review"
@@ -1327,7 +1270,6 @@ show_help() {
1327
1270
  echo "Environment Variables:"
1328
1271
  echo " MAX_RETRIES Max code retries per refactor (default: 3)"
1329
1272
  echo " MAX_INFRA_RETRIES Max infrastructure/provider retries per refactor (default: 3)"
1330
- echo " SESSION_TIMEOUT Session timeout in seconds (default: 0 = no limit)"
1331
1273
  echo " MODEL Default AI model (overridden by per-refactor model in refactor list)"
1332
1274
  echo " PRIZMKIT_EFFORT AI reasoning effort (low|medium|high|xhigh|max; max is Claude Code only)"
1333
1275
  echo " PIPELINE_MODE Default pipeline mode: lite|standard|full (overridden by --mode)"
@@ -1338,15 +1280,11 @@ show_help() {
1338
1280
  echo " HEARTBEAT_INTERVAL Heartbeat log interval in seconds (default: 30)"
1339
1281
  echo " STALE_KILL_THRESHOLD Auto-kill session after N seconds of no progress (default: 900)"
1340
1282
  echo " STOP_ON_FAILURE Stop pipeline when a task exhausts retries: 0|1 (default: 0)"
1341
- echo " LOG_CLEANUP_ENABLED Run log cleanup before execution (default: 1)"
1342
- echo " LOG_RETENTION_DAYS Delete logs older than N days (default: 14)"
1343
- echo " LOG_MAX_TOTAL_MB Keep total logs under N MB (default: 1024)"
1344
1283
  echo ""
1345
1284
  echo "Examples:"
1346
1285
  echo " ./run-refactor.sh run # Run all refactors"
1347
1286
  echo " ./run-refactor.sh run .prizmkit/plans/refactor-list.json # Custom refactor list"
1348
1287
  echo " ./run-refactor.sh run R-001 --dry-run # Inspect generated prompt"
1349
- echo " ./run-refactor.sh run R-001 --timeout 3600 # 1h timeout"
1350
1288
  echo " ./run-refactor.sh status # Show status"
1351
1289
  echo " STRICT_BEHAVIOR_CHECK=0 ./run-refactor.sh run # Skip full test suite"
1352
1290
  echo " MAX_RETRIES=5 ./run-refactor.sh run # Custom retries"
@@ -80,10 +80,10 @@ else
80
80
  fail "incomplete_count=$count, expected 0"
81
81
  fi
82
82
 
83
- # --- Test 4: Timed-out status -> deploy blocked ---
84
- echo "[Test 4] 'timed_out' status: incomplete_count should be 1"
83
+ # --- Test 4: auto_skipped status -> deploy blocked ---
84
+ echo "[Test 4] 'auto_skipped' status: incomplete_count should be 1"
85
85
  cat > /tmp/test-deploy-timeout.json << 'JSON'
86
- {"features": [{"id": "F-A", "status": "completed"}, {"id": "F-B", "status": "timed_out"}]}
86
+ {"features": [{"id": "F-A", "status": "completed"}, {"id": "F-B", "status": "auto_skipped"}]}
87
87
  JSON
88
88
  count=$(python3 -c "
89
89
  import json
@@ -19,16 +19,12 @@
19
19
 
20
20
  # ─── Pipeline Execution ──────────────────────────────────────────────
21
21
  # MAX_RETRIES=3 # Max retry attempts per task before marking failed
22
- # SESSION_TIMEOUT=0 # Session timeout in seconds (0 = no limit)
23
22
  # VERBOSE=1 # Verbose logging (1=on, 0=off)
24
23
  # HEARTBEAT_INTERVAL=30 # Poll interval for session progress/stale checks
25
24
  # STALE_KILL_THRESHOLD=900 # Auto-kill session after N seconds without parent log progress (0 = disabled)
26
25
  # STALE_KILL_GRACE_SECONDS=10 # Grace period after stale-kill before force-stopping the job
27
26
  # CODEX_WAIT_STALE_KILL_THRESHOLD=3600 # Longer no-log window while Codex waits on subagents
28
27
  # CODEX_SUBAGENT_TIMEOUT_SECONDS=3300 # Codex subagent max runtime; defaults to wait threshold - 300
29
- # LOG_CLEANUP_ENABLED=1 # Run periodic session log cleanup
30
- # LOG_RETENTION_DAYS=14 # Delete session logs older than N days
31
- # LOG_MAX_TOTAL_MB=1024 # Keep total logs under N MB via oldest-first cleanup
32
28
  # STOP_ON_FAILURE=0 # Stop after the first failed task (1=stop, 0=continue)
33
29
  # ENABLE_DEPLOY=0 # Start a deploy session after all tasks complete successfully
34
30
  # DEV_BRANCH= # Optional custom dev branch name for each task
@@ -343,16 +343,12 @@ pending, in_progress, completed, failed, skipped
343
343
  | `AI_CLI` | string | auto-detect | codex, claude, or cbc |
344
344
  | `MODEL` | string | (unset) | AI model override (per-task overrides this) |
345
345
  | `MAX_RETRIES` | integer | (not specified) | Retry attempts per task |
346
- | `SESSION_TIMEOUT` | integer | 0 | 0 = no limit |
347
346
  | `VERBOSE` | integer | (not specified) | 1=on, 0=off |
348
347
  | `HEARTBEAT_INTERVAL` | integer | 30 | Poll interval for session progress/stale checks |
349
348
  | `STALE_KILL_THRESHOLD` | integer | 900 | Auto-kill after N seconds without parent log progress; 0 disables |
350
349
  | `STALE_KILL_GRACE_SECONDS` | integer | 10 | Grace period after stale-kill before force-stopping |
351
350
  | `CODEX_WAIT_STALE_KILL_THRESHOLD` | integer | 3600 | Longer no-log stale window while Codex waits on subagents |
352
351
  | `CODEX_SUBAGENT_TIMEOUT_SECONDS` | integer | 3300 | Codex subagent max runtime |
353
- | `LOG_CLEANUP_ENABLED` | boolean | 1 | Periodic session log cleanup |
354
- | `LOG_RETENTION_DAYS` | integer | 14 | Delete session logs older than N days |
355
- | `LOG_MAX_TOTAL_MB` | integer | 1024 | Keep total logs under N MB |
356
352
  | `STOP_ON_FAILURE` | boolean | 0 | Stop after a task exhausts retries |
357
353
  | `ENABLE_DEPLOY` | boolean | 0 | Start deploy session after all tasks complete |
358
354
  | `DEV_BRANCH` | string | auto-generated | Optional custom dev branch name |
@@ -51,7 +51,6 @@ Located at `.prizmkit/dev-pipeline/scripts/`:
51
51
  | `check-session-status.py` | Read and validate session-status.json output |
52
52
  | `detect-stuck.py` | Detect stuck/hung pipeline sessions via heartbeat |
53
53
  | `parse-stream-progress.py` | Parse AI CLI output stream for progress tracking |
54
- | `cleanup-logs.py` | Clean up old pipeline logs and state files |
55
54
  | `utils.py` | Shared utility functions for pipeline scripts |
56
55
 
57
56
  ## Artifact Mapping
@@ -125,7 +124,6 @@ The agent MUST write `session-status.json` before exiting:
125
124
  | `status: "partial"`, `can_resume: false` | Retry from scratch |
126
125
  | `status: "failed"` | Retry (up to MAX_RETRIES) |
127
126
  | No status file (crash) | Treat as failed, retry |
128
- | Timeout (exit 124) | Treat as timed_out, retry |
129
127
 
130
128
  ## Team Naming Convention
131
129
 
@@ -44,7 +44,7 @@ function Invoke-PrizmPipeline {
44
44
  }
45
45
 
46
46
  if ($command -in @('help','--help','-h')) {
47
- Write-Host "Usage: .\run-$Kind.ps1 run [item-id] [list-path] [--dry-run] [--mode lite|standard|full] [--critic] [--max-retries N] [--max-infra-retries N] [--timeout seconds]"
47
+ Write-Host "Usage: .\run-$Kind.ps1 run [item-id] [list-path] [--dry-run] [--mode lite|standard|full] [--critic] [--max-retries N] [--max-infra-retries N]"
48
48
  Write-Host " .\run-$Kind.ps1 status [list-path]"
49
49
  Write-Host " .\run-$Kind.ps1 reset"
50
50
  Write-Host ""
@@ -90,14 +90,6 @@ function Invoke-PrizmPipeline {
90
90
  $maxInfraRetries = $null
91
91
  if ($envMaxInfraRetryArgs.Count -gt 0) { $maxInfraRetries = [int]$envMaxInfraRetryArgs[1] }
92
92
  $verboseEnabled = $env:VERBOSE -in @('1','true','yes','on')
93
- $timeoutSeconds = 0
94
- if ($env:SESSION_TIMEOUT) {
95
- $parsedEnvTimeout = 0
96
- if (-not [int]::TryParse($env:SESSION_TIMEOUT, [ref]$parsedEnvTimeout) -or $parsedEnvTimeout -lt 0) {
97
- throw "SESSION_TIMEOUT must be a non-negative integer: $($env:SESSION_TIMEOUT)"
98
- }
99
- $timeoutSeconds = $parsedEnvTimeout
100
- }
101
93
  $heartbeatInterval = 30
102
94
  if ($env:HEARTBEAT_INTERVAL) {
103
95
  $parsedHeartbeatInterval = 0
@@ -126,26 +118,6 @@ function Invoke-PrizmPipeline {
126
118
  $enableDeploy = $env:ENABLE_DEPLOY -in @('1','true','yes','on')
127
119
  $stopOnFailure = $env:STOP_ON_FAILURE -in @('1','true','yes','on')
128
120
  $devBranchOverride = if ($env:DEV_BRANCH) { $env:DEV_BRANCH.Trim() } else { '' }
129
- $logCleanupEnabled = $true
130
- if ($env:LOG_CLEANUP_ENABLED) {
131
- $logCleanupEnabled = $env:LOG_CLEANUP_ENABLED -in @('1','true','yes','on')
132
- }
133
- $logRetentionDays = 14
134
- if ($env:LOG_RETENTION_DAYS) {
135
- $parsedLogRetentionDays = 0
136
- if (-not [int]::TryParse($env:LOG_RETENTION_DAYS, [ref]$parsedLogRetentionDays) -or $parsedLogRetentionDays -lt 0) {
137
- throw "LOG_RETENTION_DAYS must be a non-negative integer: $($env:LOG_RETENTION_DAYS)"
138
- }
139
- $logRetentionDays = $parsedLogRetentionDays
140
- }
141
- $logMaxTotalMb = 1024
142
- if ($env:LOG_MAX_TOTAL_MB) {
143
- $parsedLogMaxTotalMb = 0
144
- if (-not [int]::TryParse($env:LOG_MAX_TOTAL_MB, [ref]$parsedLogMaxTotalMb) -or $parsedLogMaxTotalMb -lt 0) {
145
- throw "LOG_MAX_TOTAL_MB must be a non-negative integer: $($env:LOG_MAX_TOTAL_MB)"
146
- }
147
- $logMaxTotalMb = $parsedLogMaxTotalMb
148
- }
149
121
  $featuresFilter = $null
150
122
 
151
123
  for ($i = 0; $i -lt $remaining.Count; $i++) {
@@ -173,16 +145,6 @@ function Invoke-PrizmPipeline {
173
145
  $maxInfraRetries = $parsedMaxInfraRetries
174
146
  continue
175
147
  }
176
- '^--timeout$' {
177
- $i++
178
- if ($i -ge $remaining.Count) { throw '--timeout requires a seconds value.' }
179
- $parsedTimeout = 0
180
- if (-not [int]::TryParse($remaining[$i], [ref]$parsedTimeout) -or $parsedTimeout -lt 0) {
181
- throw "--timeout must be a non-negative integer: $($remaining[$i])"
182
- }
183
- $timeoutSeconds = $parsedTimeout
184
- continue
185
- }
186
148
  '^--features$' { $i++; $featuresFilter = $remaining[$i]; continue }
187
149
  '^-' { Write-PrizmWarn "Ignoring unsupported option: $arg"; continue }
188
150
  default {
@@ -205,7 +167,7 @@ function Invoke-PrizmPipeline {
205
167
  $retryLabel = if ($maxRetries -ne $null) { [string]$maxRetries } else { 'default' }
206
168
  $infraRetryLabel = if ($maxInfraRetries -ne $null) { [string]$maxInfraRetries } else { 'default' }
207
169
  Write-PrizmInfo "Verbose mode enabled."
208
- Write-PrizmInfo "Effective options: mode=$modeLabel critic=$criticLabel maxRetries=$retryLabel maxInfraRetries=$infraRetryLabel timeoutSeconds=$timeoutSeconds staleKillThreshold=$staleKillThreshold dryRun=$dryRun"
170
+ Write-PrizmInfo "Effective options: mode=$modeLabel critic=$criticLabel maxRetries=$retryLabel maxInfraRetries=$infraRetryLabel staleKillThreshold=$staleKillThreshold dryRun=$dryRun"
209
171
  }
210
172
 
211
173
  # Validate PRIZMKIT_EFFORT early (fail-fast before any sessions are spawned)
@@ -571,26 +533,6 @@ function Invoke-PrizmPipeline {
571
533
  }
572
534
  }
573
535
 
574
- function Invoke-PrizmLogCleanup {
575
- if (-not $logCleanupEnabled) { return }
576
- if (-not (Test-Path $stateDir)) { return }
577
-
578
- try {
579
- $cleanup = Invoke-PrizmPythonJson $python @(
580
- (Join-Path $paths.ScriptsDir 'cleanup-logs.py'),
581
- '--state-dir', $stateDir,
582
- '--retention-days', [string]$logRetentionDays,
583
- '--max-total-mb', [string]$logMaxTotalMb
584
- )
585
- if ($cleanup -and $cleanup.deleted_files -gt 0) {
586
- $reclaimedKb = [int]([int64]$cleanup.reclaimed_bytes / 1024)
587
- Write-PrizmInfo "Log cleanup: deleted $($cleanup.deleted_files) files, reclaimed ${reclaimedKb}KB"
588
- }
589
- } catch {
590
- Write-PrizmWarn "Log cleanup failed (continuing)"
591
- }
592
- }
593
-
594
536
  function Get-PrizmDeployIncompleteItems {
595
537
  param([string]$Kind, [string]$ListPath)
596
538
 
@@ -694,11 +636,12 @@ function Invoke-PrizmPipeline {
694
636
  $devBranchName = ''
695
637
  $hadDirtyBaseline = if ($isGitRepository) { Test-PrizmGitWorkDirty $paths.ProjectRoot $stateDir $listPath } else { $false }
696
638
  if ($hadDirtyBaseline) {
697
- Write-PrizmError "Dirty working tree detected before $CurrentItemId; refusing to run on $originalBranch."
698
- Write-PrizmError "Commit/stash your changes or start from a clean branch, then rerun the pipeline."
699
- $script:PRIZM_ITEM_LIST_STATUS = ''
700
- $script:PRIZM_ITEM_EXIT_CODE = 1
701
- return
639
+ if ($dryRun) {
640
+ Write-PrizmWarn "Dirty working tree detected before $CurrentItemId; would auto-commit snapshot in real run."
641
+ } else {
642
+ Write-PrizmInfo "Dirty working tree detected before $CurrentItemId; auto-committing snapshot."
643
+ Invoke-PrizmGitAutoCommit $paths.ProjectRoot "chore: workspace snapshot ready for run $CurrentItemId" | Out-Null
644
+ }
702
645
  }
703
646
 
704
647
  if ($dryRun) {
@@ -788,16 +731,13 @@ function Invoke-PrizmPipeline {
788
731
  $previousProgressSignature = ''
789
732
  $previousChildActivitySignature = ''
790
733
  $previousErrorLoopSignature = ''
791
- $wasTimedOut = $false
792
734
  $staleKillMarker = Join-Path $logsDir 'stale-kill.json'
793
735
  $wasStaleKilled = $false
794
736
  while ($true) {
795
- $remainingTimeout = if ($timeoutSeconds -gt 0) { $timeoutSeconds - $elapsedSeconds } else { $heartbeatInterval }
796
- $waitSeconds = if ($timeoutSeconds -gt 0) { [Math]::Min($heartbeatInterval, [Math]::Max(1, $remainingTimeout)) } else { $heartbeatInterval }
797
- $completed = Wait-Job $job -Timeout $waitSeconds
737
+ $completed = Wait-Job $job -Timeout $heartbeatInterval
798
738
  if ($completed) { break }
799
739
 
800
- $elapsedSeconds += $waitSeconds
740
+ $elapsedSeconds += $heartbeatInterval
801
741
  $currentLogSize = 0
802
742
  if (Test-Path $sessionLog) {
803
743
  $currentLogSize = [int64](Get-Item $sessionLog).Length
@@ -851,13 +791,7 @@ function Invoke-PrizmPipeline {
851
791
  $staleSeconds = 0
852
792
  } else {
853
793
  $staleReason = 'stale_session'
854
- $staleSeconds += $waitSeconds
855
- }
856
-
857
- if ($timeoutSeconds -gt 0 -and $elapsedSeconds -ge $timeoutSeconds) {
858
- $wasTimedOut = $true
859
- Stop-PrizmSessionProcess $pidPath
860
- break
794
+ $staleSeconds += $heartbeatInterval
861
795
  }
862
796
 
863
797
  $fatalErrorCode = Get-PrizmProgressFatalErrorCode -ProgressFile $progressJson
@@ -886,11 +820,7 @@ function Invoke-PrizmPipeline {
886
820
  }
887
821
 
888
822
  $exitCode = 0
889
- if ($wasTimedOut) {
890
- Stop-Job $job
891
- Remove-Job $job
892
- $exitCode = 124
893
- } elseif ($wasStaleKilled) {
823
+ if ($wasStaleKilled) {
894
824
  Stop-Job $job
895
825
  Remove-Job $job
896
826
  $exitCode = 143
@@ -923,7 +853,7 @@ function Invoke-PrizmPipeline {
923
853
  $status = 'crashed'
924
854
  if ($semanticCompletion) {
925
855
  $status = 'success'
926
- if ($exitCode -ne 0 -or $wasStaleKilled -or $wasTimedOut -or $wasAiRuntimeError) {
856
+ if ($exitCode -ne 0 -or $wasStaleKilled -or $wasAiRuntimeError) {
927
857
  Write-PrizmWarn "Session ended with a failure signal after semantic completion; treating as finalized success"
928
858
  Write-PrizmWarn "Semantic completion commit: $($semanticCompletion.CommitSha)"
929
859
  }
@@ -931,9 +861,6 @@ function Invoke-PrizmPipeline {
931
861
  $status = 'infra_error'
932
862
  Write-PrizmWarn "AI session failed due to structured AI runtime/context error"
933
863
  Write-PrizmWarn "AI runtime errors are retried without consuming code retry budget"
934
- } elseif ($wasTimedOut) {
935
- $status = 'timed_out'
936
- Write-PrizmWarn "AI session timed out after $timeoutSeconds seconds"
937
864
  } elseif ($wasInfraError) {
938
865
  $status = 'infra_error'
939
866
  Write-PrizmWarn "AI session failed due to AI CLI/provider infrastructure error"
@@ -1027,10 +954,6 @@ function Invoke-PrizmPipeline {
1027
954
  return
1028
955
  }
1029
956
 
1030
- if (-not $dryRun) {
1031
- Invoke-PrizmLogCleanup
1032
- }
1033
-
1034
957
  if ($itemId) {
1035
958
  Invoke-PrizmPipelineItem $itemId
1036
959
  $global:PRIZM_EXIT_CODE = $script:PRIZM_ITEM_EXIT_CODE
@@ -62,7 +62,6 @@ function Get-PrizmRecoveryIntEnv {
62
62
  return $parsed
63
63
  }
64
64
 
65
- $timeoutSeconds = Get-PrizmRecoveryIntEnv 'SESSION_TIMEOUT' 0 0
66
65
  $heartbeatInterval = Get-PrizmRecoveryIntEnv 'HEARTBEAT_INTERVAL' 30 1
67
66
  $staleKillThreshold = Get-PrizmRecoveryIntEnv 'STALE_KILL_THRESHOLD' 900 0
68
67
  $staleKillGraceSeconds = Get-PrizmRecoveryIntEnv 'STALE_KILL_GRACE_SECONDS' 10 0
@@ -123,15 +122,12 @@ $staleSeconds = 0
123
122
  $previousLogSize = 0
124
123
  $previousProgressSignature = ''
125
124
  $previousChildActivitySignature = ''
126
- $wasTimedOut = $false
127
125
  $wasStaleKilled = $false
128
126
  while ($true) {
129
- $remainingTimeout = if ($timeoutSeconds -gt 0) { $timeoutSeconds - $elapsedSeconds } else { $heartbeatInterval }
130
- $waitSeconds = if ($timeoutSeconds -gt 0) { [Math]::Min($heartbeatInterval, [Math]::Max(1, $remainingTimeout)) } else { $heartbeatInterval }
131
- $completed = Wait-Job $job -Timeout $waitSeconds
127
+ $completed = Wait-Job $job -Timeout $heartbeatInterval
132
128
  if ($completed) { break }
133
129
 
134
- $elapsedSeconds += $waitSeconds
130
+ $elapsedSeconds += $heartbeatInterval
135
131
  $currentLogSize = 0
136
132
  if (Test-Path $logPath) { $currentLogSize = [int64](Get-Item $logPath).Length }
137
133
  $growth = $currentLogSize - $previousLogSize
@@ -145,13 +141,7 @@ while ($true) {
145
141
  $childAdvanced = ($childSignature -and $childSignature -ne $previousChildActivitySignature)
146
142
  $previousChildActivitySignature = $childSignature
147
143
 
148
- if ($growth -gt 0 -or $childAdvanced -or $progressAdvanced) { $staleSeconds = 0 } else { $staleSeconds += $waitSeconds }
149
-
150
- if ($timeoutSeconds -gt 0 -and $elapsedSeconds -ge $timeoutSeconds) {
151
- $wasTimedOut = $true
152
- Stop-PrizmSessionProcess $pidPath
153
- break
154
- }
144
+ if ($growth -gt 0 -or $childAdvanced -or $progressAdvanced) { $staleSeconds = 0 } else { $staleSeconds += $heartbeatInterval }
155
145
 
156
146
  if ($staleKillThreshold -gt 0 -and $staleSeconds -ge $staleKillThreshold) {
157
147
  $wasStaleKilled = $true
@@ -164,11 +154,7 @@ while ($true) {
164
154
  }
165
155
 
166
156
  $exitCode = 0
167
- if ($wasTimedOut) {
168
- Stop-Job $job
169
- Remove-Job $job
170
- $exitCode = 124
171
- } elseif ($wasStaleKilled) {
157
+ if ($wasStaleKilled) {
172
158
  Stop-Job $job
173
159
  Remove-Job $job
174
160
  $exitCode = 143
@@ -188,7 +174,6 @@ if (Test-Path $logPath) {
188
174
  $sizeKb = [int](([int64](Get-Item $logPath).Length) / 1024)
189
175
  Write-PrizmInfo "Session log: $lineCount lines, ${sizeKb}KB"
190
176
  }
191
- if ($wasTimedOut) { Write-PrizmWarn "Recovery session timed out after $timeoutSeconds seconds." }
192
177
  if ($wasStaleKilled -or (Test-Path $staleKillMarker)) { Write-PrizmWarn "Recovery session was stale-killed." }
193
178
  if ($exitCode -eq 0) { Write-PrizmSuccess "Recovery session completed." } else { Write-PrizmError "Recovery session failed. Log: $logPath" }
194
179
  exit $exitCode
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.92",
2
+ "version": "1.1.93",
3
3
  "skills": {
4
4
  "prizm-kit": {
5
5
  "description": "Full-lifecycle dev toolkit. Covers spec-driven development, Prizm context docs, code quality, debugging, deployment, and knowledge management.",
@@ -129,7 +129,7 @@ Detect user intent from their message, then follow the corresponding workflow:
129
129
  ```
130
130
  With all options:
131
131
  ```bash
132
- VERBOSE=1 MAX_RETRIES=5 SESSION_TIMEOUT=3600 ENABLE_DEPLOY=1 PRIZMKIT_EFFORT=high \
132
+ VERBOSE=1 MAX_RETRIES=5 ENABLE_DEPLOY=1 PRIZMKIT_EFFORT=high \
133
133
  .prizmkit/dev-pipeline/run-bugfix.sh run .prizmkit/plans/bug-fix-list.json
134
134
  ```
135
135