prizmkit 1.1.8 → 1.1.10

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 (123) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/adapters/codebuddy/skill-adapter.js +21 -7
  3. package/bundled/agents/prizm-dev-team-reviewer.md +53 -173
  4. package/bundled/dev-pipeline/.env.example +45 -0
  5. package/bundled/dev-pipeline/SCHEMA_ANALYSIS.md +535 -0
  6. package/bundled/dev-pipeline/assets/feature-list-example.json +0 -1
  7. package/bundled/dev-pipeline/launch-bugfix-daemon.sh +57 -12
  8. package/bundled/dev-pipeline/launch-feature-daemon.sh +3 -1
  9. package/bundled/dev-pipeline/launch-refactor-daemon.sh +57 -12
  10. package/bundled/dev-pipeline/lib/branch.sh +6 -1
  11. package/bundled/dev-pipeline/lib/common.sh +71 -0
  12. package/bundled/dev-pipeline/lib/heartbeat.sh +2 -2
  13. package/bundled/dev-pipeline/retry-bugfix.sh +60 -23
  14. package/bundled/dev-pipeline/retry-feature.sh +47 -12
  15. package/bundled/dev-pipeline/retry-refactor.sh +105 -23
  16. package/bundled/dev-pipeline/run-bugfix.sh +265 -44
  17. package/bundled/dev-pipeline/run-feature.sh +35 -1
  18. package/bundled/dev-pipeline/run-refactor.sh +376 -51
  19. package/bundled/dev-pipeline/scripts/check-session-status.py +24 -1
  20. package/bundled/dev-pipeline/scripts/detect-stuck.py +195 -85
  21. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +31 -19
  22. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +19 -3
  23. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +98 -11
  24. package/bundled/dev-pipeline/scripts/init-bugfix-pipeline.py +30 -5
  25. package/bundled/dev-pipeline/scripts/init-pipeline.py +3 -3
  26. package/bundled/dev-pipeline/scripts/init-refactor-pipeline.py +15 -4
  27. package/bundled/dev-pipeline/scripts/parse-stream-progress.py +1 -5
  28. package/bundled/dev-pipeline/scripts/patch-completion-notes.py +191 -0
  29. package/bundled/dev-pipeline/scripts/update-bug-status.py +159 -14
  30. package/bundled/dev-pipeline/scripts/update-feature-status.py +79 -37
  31. package/bundled/dev-pipeline/scripts/update-refactor-status.py +343 -13
  32. package/bundled/dev-pipeline/templates/agent-prompts/dev-fix.md +1 -1
  33. package/bundled/dev-pipeline/templates/agent-prompts/reviewer-review.md +7 -11
  34. package/bundled/dev-pipeline/templates/bootstrap-prompt.md +41 -7
  35. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +27 -3
  36. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +43 -19
  37. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +54 -26
  38. package/bundled/dev-pipeline/templates/bug-fix-list-schema.json +5 -14
  39. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +36 -25
  40. package/bundled/dev-pipeline/templates/feature-list-schema.json +23 -11
  41. package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +270 -0
  42. package/bundled/dev-pipeline/templates/refactor-list-schema.json +10 -2
  43. package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +3 -1
  44. package/bundled/dev-pipeline/templates/sections/critical-paths-agent.md +1 -0
  45. package/bundled/dev-pipeline/templates/sections/feature-context.md +2 -0
  46. package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +29 -2
  47. package/bundled/dev-pipeline/templates/sections/phase-commit.md +22 -0
  48. package/bundled/dev-pipeline/templates/sections/phase-deploy-verification.md +2 -2
  49. package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +8 -6
  50. package/bundled/dev-pipeline/templates/sections/phase-review-full.md +7 -5
  51. package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +3 -3
  52. package/bundled/skills/_metadata.json +5 -22
  53. package/bundled/skills/app-planner/SKILL.md +92 -66
  54. package/bundled/skills/app-planner/assets/app-design-guide.md +1 -1
  55. package/bundled/skills/app-planner/references/architecture-decisions.md +1 -1
  56. package/bundled/skills/app-planner/references/project-brief-guide.md +69 -66
  57. package/bundled/skills/bug-fix-workflow/SKILL.md +47 -4
  58. package/bundled/skills/bug-planner/SKILL.md +130 -188
  59. package/bundled/skills/bug-planner/assets/bug-confirmation-template.md +43 -0
  60. package/bundled/skills/bug-planner/references/critic-and-verification.md +44 -0
  61. package/bundled/skills/bug-planner/references/error-recovery.md +73 -0
  62. package/bundled/skills/bug-planner/references/input-formats.md +53 -0
  63. package/bundled/skills/bug-planner/references/schema-validation.md +25 -0
  64. package/bundled/skills/bug-planner/references/severity-rules.md +16 -0
  65. package/bundled/skills/bug-planner/scripts/validate-bug-list.py +1 -5
  66. package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +5 -10
  67. package/bundled/skills/feature-pipeline-launcher/SKILL.md +16 -3
  68. package/bundled/skills/feature-planner/SKILL.md +33 -122
  69. package/bundled/skills/feature-planner/assets/evaluation-guide.md +1 -1
  70. package/bundled/skills/feature-planner/assets/planning-guide.md +21 -5
  71. package/bundled/skills/feature-planner/references/browser-interaction.md +2 -4
  72. package/bundled/skills/feature-planner/references/completeness-review.md +57 -0
  73. package/bundled/skills/feature-planner/references/error-recovery.md +15 -34
  74. package/bundled/skills/feature-planner/references/incremental-feature-planning.md +1 -1
  75. package/bundled/skills/feature-planner/references/new-project-planning.md +2 -2
  76. package/bundled/skills/feature-planner/scripts/validate-and-generate.py +1 -2
  77. package/bundled/skills/feature-workflow/SKILL.md +3 -4
  78. package/bundled/skills/prizm-kit/SKILL.md +39 -49
  79. package/bundled/skills/prizmkit-code-review/SKILL.md +51 -64
  80. package/bundled/skills/prizmkit-code-review/rules/dimensions.md +85 -0
  81. package/bundled/skills/prizmkit-code-review/rules/fix-strategy.md +11 -11
  82. package/bundled/skills/prizmkit-committer/SKILL.md +3 -31
  83. package/bundled/skills/prizmkit-deploy/SKILL.md +34 -31
  84. package/bundled/skills/prizmkit-deploy/assets/deploy-template.md +1 -1
  85. package/bundled/skills/prizmkit-implement/SKILL.md +35 -68
  86. package/bundled/skills/prizmkit-init/SKILL.md +112 -65
  87. package/bundled/skills/prizmkit-init/assets/project-brief-template.md +82 -0
  88. package/bundled/skills/prizmkit-plan/SKILL.md +120 -79
  89. package/bundled/skills/prizmkit-plan/assets/plan-template.md +28 -18
  90. package/bundled/skills/prizmkit-plan/assets/spec-template.md +28 -11
  91. package/bundled/skills/prizmkit-plan/references/clarify-guide.md +3 -3
  92. package/bundled/skills/prizmkit-plan/references/verification-checklist.md +60 -0
  93. package/bundled/skills/prizmkit-prizm-docs/SKILL.md +10 -81
  94. package/bundled/skills/prizmkit-prizm-docs/assets/{PRIZM-SPEC.md → prizm-docs-format.md} +41 -526
  95. package/bundled/skills/prizmkit-prizm-docs/references/op-init.md +46 -0
  96. package/bundled/skills/prizmkit-prizm-docs/references/op-rebuild.md +16 -0
  97. package/bundled/skills/prizmkit-prizm-docs/references/op-status.md +14 -0
  98. package/bundled/skills/prizmkit-prizm-docs/references/op-update.md +19 -0
  99. package/bundled/skills/prizmkit-prizm-docs/references/op-validate.md +17 -0
  100. package/bundled/skills/prizmkit-retrospective/SKILL.md +27 -65
  101. package/bundled/skills/prizmkit-retrospective/references/knowledge-injection-steps.md +3 -4
  102. package/bundled/skills/prizmkit-retrospective/references/structural-sync-steps.md +7 -25
  103. package/bundled/skills/recovery-workflow/SKILL.md +8 -8
  104. package/bundled/skills/refactor-pipeline-launcher/SKILL.md +17 -9
  105. package/bundled/skills/refactor-planner/SKILL.md +23 -41
  106. package/bundled/skills/refactor-workflow/SKILL.md +1 -2
  107. package/bundled/team/prizm-dev-team.json +1 -1
  108. package/bundled/{skills/prizm-kit/assets → templates}/project-memory-template.md +1 -1
  109. package/package.json +1 -1
  110. package/src/clean.js +0 -1
  111. package/src/gitignore-template.js +0 -1
  112. package/src/scaffold.js +10 -3
  113. package/bundled/dev-pipeline/templates/agent-prompts/reviewer-analyze.md +0 -5
  114. package/bundled/dev-pipeline/templates/sections/phase-analyze-agent.md +0 -19
  115. package/bundled/dev-pipeline/templates/sections/phase-analyze-full.md +0 -19
  116. package/bundled/skills/app-planner/references/project-conventions.md +0 -93
  117. package/bundled/skills/prizmkit-analyze/SKILL.md +0 -207
  118. package/bundled/skills/prizmkit-code-review/rules/dimensions-bugfix.md +0 -25
  119. package/bundled/skills/prizmkit-code-review/rules/dimensions-feature.md +0 -43
  120. package/bundled/skills/prizmkit-code-review/rules/dimensions-refactor.md +0 -25
  121. package/bundled/skills/prizmkit-implement/references/deploy-guide-protocol.md +0 -69
  122. package/bundled/skills/prizmkit-verify/SKILL.md +0 -281
  123. package/bundled/skills/prizmkit-verify/scripts/verify-light.py +0 -402
@@ -335,6 +335,23 @@ sys.exit(0)
335
335
  fi
336
336
  fi
337
337
 
338
+ # Propagate completion notes for dependency context (only on success)
339
+ if [[ "$session_status" == "success" && -n "$feature_slug" ]]; then
340
+ local summary_path="$project_root/.prizmkit/specs/$feature_slug/completion-summary.json"
341
+ if [[ -f "$summary_path" ]]; then
342
+ python3 "$SCRIPTS_DIR/patch-completion-notes.py" \
343
+ --feature-list "$feature_list" \
344
+ --feature-id "$feature_id" \
345
+ --summary "$summary_path" >/dev/null 2>&1 && {
346
+ log_info "Propagated completion notes for $feature_id to feature-list.json"
347
+ } || {
348
+ log_warn "Failed to propagate completion notes for $feature_id"
349
+ }
350
+ else
351
+ log_info "No completion-summary.json for $feature_id — dependency context will be limited"
352
+ fi
353
+ fi
354
+
338
355
  # Update feature status
339
356
  local update_output
340
357
  update_output=$(python3 "$SCRIPTS_DIR/update-feature-status.py" \
@@ -657,12 +674,25 @@ sys.exit(1)
657
674
 
658
675
  bootstrap_prompt="$session_dir/bootstrap-prompt.md"
659
676
 
677
+ # Read retry count from status.json
678
+ local retry_count
679
+ retry_count=$(python3 -c "
680
+ import json, os
681
+ status_path = os.path.join('$STATE_DIR', 'features', '$feature_id', 'status.json')
682
+ if os.path.isfile(status_path):
683
+ with open(status_path) as f:
684
+ d = json.load(f)
685
+ print(d.get('retry_count', 0))
686
+ else:
687
+ print(0)
688
+ " 2>/dev/null || echo "0")
689
+
660
690
  local prompt_args=(
661
691
  --feature-list "$feature_list"
662
692
  --feature-id "$feature_id"
663
693
  --session-id "$session_id"
664
694
  --run-id "$run_id"
665
- --retry-count 0
695
+ --retry-count "$retry_count"
666
696
  --resume-phase "$resume_phase"
667
697
  --state-dir "$STATE_DIR"
668
698
  --output "$bootstrap_prompt"
@@ -734,6 +764,9 @@ sys.exit(1)
734
764
  return 0
735
765
  fi
736
766
 
767
+ # Log bootstrap prompt in test mode
768
+ prizm_log_bootstrap_prompt "$bootstrap_prompt" "$feature_id"
769
+
737
770
  # Spawn AI CLI Session
738
771
  echo ""
739
772
  echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
@@ -1111,6 +1144,7 @@ print(count)
1111
1144
  --action start >/dev/null 2>&1 || true
1112
1145
 
1113
1146
  # Spawn session and wait
1147
+ prizm_log_bootstrap_prompt "$bootstrap_prompt" "$feature_id"
1114
1148
  log_info "Spawning AI CLI session: $session_id"
1115
1149
  if [[ -n "$feature_model" ]]; then
1116
1150
  log_info "Feature model: $feature_model"
@@ -44,6 +44,7 @@ LOG_CLEANUP_ENABLED=${LOG_CLEANUP_ENABLED:-1}
44
44
  LOG_RETENTION_DAYS=${LOG_RETENTION_DAYS:-14}
45
45
  LOG_MAX_TOTAL_MB=${LOG_MAX_TOTAL_MB:-1024}
46
46
  VERBOSE=${VERBOSE:-0}
47
+ MODEL=${MODEL:-""}
47
48
  DEV_BRANCH=${DEV_BRANCH:-""}
48
49
  AUTO_PUSH=${AUTO_PUSH:-0}
49
50
  STRICT_BEHAVIOR_CHECK=${STRICT_BEHAVIOR_CHECK:-1}
@@ -79,7 +80,8 @@ spawn_and_wait_session() {
79
80
  local bootstrap_prompt="$4"
80
81
  local session_dir="$5"
81
82
  local max_retries="$6"
82
- local base_branch="${7:-main}"
83
+ local item_model="${7:-}"
84
+ local base_branch="${8:-main}"
83
85
 
84
86
  local session_log="$session_dir/logs/session.log"
85
87
  local progress_json="$session_dir/logs/progress.json"
@@ -97,7 +99,9 @@ spawn_and_wait_session() {
97
99
  fi
98
100
 
99
101
  local model_flag=""
100
- if [[ -n "${MODEL:-}" ]]; then
102
+ if [[ -n "$item_model" ]]; then
103
+ model_flag="--model $item_model"
104
+ elif [[ -n "${MODEL:-}" ]]; then
101
105
  model_flag="--model $MODEL"
102
106
  fi
103
107
 
@@ -105,6 +109,9 @@ spawn_and_wait_session() {
105
109
  # within an existing Claude Code session (e.g. via launch-refactor-daemon.sh).
106
110
  unset CLAUDECODE 2>/dev/null || true
107
111
 
112
+ # Log bootstrap prompt in test mode
113
+ prizm_log_bootstrap_prompt "$bootstrap_prompt" "$refactor_id"
114
+
108
115
  case "$CLI_CMD" in
109
116
  *claude*)
110
117
  # Claude Code: prompt via -p, --dangerously-skip-permissions for auto-accept
@@ -227,9 +234,69 @@ spawn_and_wait_session() {
227
234
 
228
235
  log_info "Session result: $session_status"
229
236
 
237
+ # Validate key artifacts exist after successful session
238
+ if [[ "$session_status" == "success" ]]; then
239
+ local _artifact_root
240
+ _artifact_root="$(cd "$SCRIPT_DIR/.." && pwd)"
241
+ local plan_file="$_artifact_root/.prizmkit/refactor/$refactor_id/plan.md"
242
+ if [[ ! -f "$plan_file" ]]; then
243
+ log_warn "ARTIFACT_MISSING: plan.md not found at $plan_file"
244
+ fi
245
+
246
+ # Validate checkpoint completeness
247
+ local checkpoint_file="$_artifact_root/.prizmkit/refactor/$refactor_id/workflow-checkpoint.json"
248
+ if [[ -f "$checkpoint_file" ]]; then
249
+ local checkpoint_result
250
+ checkpoint_result=$(python3 -c "
251
+ import json, sys
252
+ try:
253
+ with open(sys.argv[1]) as f:
254
+ data = json.load(f)
255
+ except json.JSONDecodeError as e:
256
+ print('CORRUPTED: {}'.format(e))
257
+ sys.exit(2)
258
+ incomplete = [s for s in data['steps'] if s['status'] not in ('completed', 'skipped')]
259
+ if incomplete:
260
+ for s in incomplete:
261
+ print('INCOMPLETE: {} {} = {}'.format(s['id'], s['skill'], s['status']))
262
+ sys.exit(1)
263
+ print('ALL_COMPLETE')
264
+ sys.exit(0)
265
+ " "$checkpoint_file" 2>&1)
266
+ local check_exit=$?
267
+ if [[ $check_exit -eq 2 ]]; then
268
+ log_warn "CHECKPOINT_CORRUPTED: workflow-checkpoint.json is not valid JSON"
269
+ elif [[ $check_exit -eq 1 ]]; then
270
+ log_warn "CHECKPOINT_INCOMPLETE: Not all workflow steps completed:"
271
+ echo "$checkpoint_result" | while read -r line; do log_warn " $line"; done
272
+ else
273
+ log_info "CHECKPOINT: All workflow steps completed"
274
+ fi
275
+ else
276
+ log_info "CHECKPOINT: No workflow-checkpoint.json found (checkpoint system not active)"
277
+ fi
278
+ fi
279
+
230
280
  # Subagent detection
231
281
  prizm_detect_subagents "$session_log"
232
282
 
283
+ # Propagate completion notes for dependency context (only on success)
284
+ if [[ "$session_status" == "success" ]]; then
285
+ local summary_path="$project_root/.prizmkit/refactor/$refactor_id/completion-summary.json"
286
+ if [[ -f "$summary_path" ]]; then
287
+ python3 "$SCRIPTS_DIR/patch-completion-notes.py" \
288
+ --refactor-list "$refactor_list" \
289
+ --refactor-id "$refactor_id" \
290
+ --summary "$summary_path" >/dev/null 2>&1 && {
291
+ log_info "Propagated completion notes for $refactor_id to refactor-list.json"
292
+ } || {
293
+ log_warn "Failed to propagate completion notes for $refactor_id"
294
+ }
295
+ else
296
+ log_info "No completion-summary.json for $refactor_id — dependency context will be limited"
297
+ fi
298
+ fi
299
+
233
300
  # Update refactor status
234
301
  python3 "$SCRIPTS_DIR/update-refactor-status.py" \
235
302
  --refactor-list "$refactor_list" \
@@ -320,11 +387,31 @@ run_one() {
320
387
  local refactor_id=""
321
388
  local refactor_list=""
322
389
  local dry_run=false
390
+ local do_clean=false
391
+ local no_reset=false
392
+ local mode_override=""
393
+ local critic_override=""
323
394
 
324
395
  while [[ $# -gt 0 ]]; do
325
396
  case "$1" in
326
397
  --dry-run) dry_run=true; shift ;;
398
+ --clean) do_clean=true; shift ;;
399
+ --no-reset) no_reset=true; shift ;;
327
400
  --timeout) shift; SESSION_TIMEOUT="${1:-0}"; shift ;;
401
+ --mode)
402
+ shift
403
+ if [[ $# -eq 0 ]]; then
404
+ log_error "--mode requires a value (lite|standard|full)"
405
+ exit 1
406
+ fi
407
+ case "$1" in
408
+ lite|standard|full) mode_override="$1" ;;
409
+ *) log_error "Invalid mode: $1 (must be lite, standard, or full)"; exit 1 ;;
410
+ esac
411
+ shift
412
+ ;;
413
+ --critic) critic_override="true"; shift ;;
414
+ --no-critic) critic_override="false"; shift ;;
328
415
  R-*|r-*) refactor_id="$1"; shift ;;
329
416
  *) refactor_list="$1"; shift ;;
330
417
  esac
@@ -405,12 +492,48 @@ for item in data.get('refactors', []):
405
492
  sys.exit(1)
406
493
  " "$refactor_list" "$refactor_id" 2>/dev/null) || refactor_complexity="medium"
407
494
 
408
- # Reset refactor status
409
- python3 "$SCRIPTS_DIR/update-refactor-status.py" \
410
- --refactor-list "$refactor_list" \
411
- --state-dir "$STATE_DIR" \
412
- --refactor-id "$refactor_id" \
413
- --action reset >/dev/null 2>&1 || true
495
+ # Optional Clean
496
+ if [[ "$do_clean" == true ]]; then
497
+ if [[ "$dry_run" == true ]]; then
498
+ log_warn "Dry-run mode: --clean ignored (no artifacts will be deleted)"
499
+ else
500
+ log_info "Cleaning artifacts for $refactor_id..."
501
+
502
+ local project_root
503
+ project_root="$(cd "$SCRIPT_DIR/.." && pwd)"
504
+
505
+ local refactor_dir="$project_root/.prizmkit/refactor/$refactor_id"
506
+ if [[ -d "$refactor_dir" ]]; then
507
+ rm -rf "$refactor_dir"
508
+ log_info "Removed $refactor_dir"
509
+ fi
510
+
511
+ local dev_team_dir="$project_root/.dev-team"
512
+ if [[ -d "$dev_team_dir" ]]; then
513
+ rm -rf "$dev_team_dir"
514
+ log_info "Removed $dev_team_dir"
515
+ fi
516
+
517
+ local refactor_state_dir="$STATE_DIR/refactors/$refactor_id"
518
+ if [[ -d "$refactor_state_dir" ]]; then
519
+ rm -rf "$refactor_state_dir"
520
+ log_info "Removed $refactor_state_dir"
521
+ fi
522
+ fi
523
+ fi
524
+
525
+ # Reset refactor status (conditional)
526
+ if [[ "$no_reset" == false && "$dry_run" == false ]]; then
527
+ python3 "$SCRIPTS_DIR/update-refactor-status.py" \
528
+ --refactor-list "$refactor_list" \
529
+ --state-dir "$STATE_DIR" \
530
+ --refactor-id "$refactor_id" \
531
+ --action reset >/dev/null 2>&1 || {
532
+ log_warn "Failed to reset refactor status (may already be pending)"
533
+ }
534
+ elif [[ "$dry_run" == true && "$no_reset" == false ]]; then
535
+ log_info "Dry-run mode: skipping status reset"
536
+ fi
414
537
 
415
538
  # Generate bootstrap prompt
416
539
  local run_id session_id session_dir bootstrap_prompt
@@ -421,16 +544,66 @@ sys.exit(1)
421
544
 
422
545
  bootstrap_prompt="$session_dir/bootstrap-prompt.md"
423
546
 
547
+ # Read retry count from status.json
548
+ local retry_count
549
+ retry_count=$(python3 -c "
550
+ import json, os
551
+ status_path = os.path.join('$STATE_DIR', 'refactors', '$refactor_id', 'status.json')
552
+ if os.path.isfile(status_path):
553
+ with open(status_path) as f:
554
+ d = json.load(f)
555
+ print(d.get('retry_count', 0))
556
+ else:
557
+ print(0)
558
+ " 2>/dev/null || echo "0")
559
+ local resume_phase
560
+ resume_phase=$(python3 -c "
561
+ import json, os
562
+ status_path = os.path.join('$STATE_DIR', 'refactors', '$refactor_id', 'status.json')
563
+ if os.path.isfile(status_path):
564
+ with open(status_path) as f:
565
+ d = json.load(f)
566
+ print(d.get('resume_from_phase') or 'null')
567
+ else:
568
+ print('null')
569
+ " 2>/dev/null || echo "null")
570
+
424
571
  log_info "Generating refactor bootstrap prompt..."
425
- python3 "$SCRIPTS_DIR/generate-refactor-prompt.py" \
426
- --refactor-list "$refactor_list" \
427
- --refactor-id "$refactor_id" \
428
- --session-id "$session_id" \
429
- --run-id "$run_id" \
430
- --retry-count 0 \
431
- --resume-phase "null" \
432
- --state-dir "$STATE_DIR" \
433
- --output "$bootstrap_prompt" >/dev/null 2>&1
572
+ local prompt_args=(
573
+ --refactor-list "$refactor_list"
574
+ --refactor-id "$refactor_id"
575
+ --session-id "$session_id"
576
+ --run-id "$run_id"
577
+ --retry-count "$retry_count"
578
+ --resume-phase "$resume_phase"
579
+ --state-dir "$STATE_DIR"
580
+ --output "$bootstrap_prompt"
581
+ )
582
+
583
+ if [[ -n "$mode_override" ]]; then
584
+ prompt_args+=(--mode "$mode_override")
585
+ elif [[ -n "${PIPELINE_MODE:-}" ]]; then
586
+ prompt_args+=(--mode "$PIPELINE_MODE")
587
+ fi
588
+
589
+ if [[ -n "${critic_override:-}" ]]; then
590
+ prompt_args+=(--critic "$critic_override")
591
+ elif [[ "${ENABLE_CRITIC:-}" == "true" || "${ENABLE_CRITIC:-}" == "1" ]]; then
592
+ prompt_args+=(--critic "true")
593
+ elif [[ "${ENABLE_CRITIC:-}" == "false" || "${ENABLE_CRITIC:-}" == "0" ]]; then
594
+ prompt_args+=(--critic "false")
595
+ fi
596
+
597
+ local gen_output
598
+ gen_output=$(python3 "$SCRIPTS_DIR/generate-refactor-prompt.py" "${prompt_args[@]}" 2>/dev/null) || {
599
+ log_error "Failed to generate bootstrap prompt for $refactor_id"
600
+ return 1
601
+ }
602
+ local refactor_model pipeline_mode agent_count critic_enabled
603
+ refactor_model=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('model',''))" 2>/dev/null || echo "")
604
+ pipeline_mode=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('pipeline_mode','standard'))" 2>/dev/null || echo "standard")
605
+ agent_count=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('agent_count',3))" 2>/dev/null || echo "3")
606
+ critic_enabled=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('critic_enabled','false'))" 2>/dev/null || echo "false")
434
607
 
435
608
  if [[ "$dry_run" == true ]]; then
436
609
  echo ""
@@ -439,6 +612,20 @@ sys.exit(1)
439
612
  echo -e "${BOLD} Complexity: $refactor_complexity${NC}"
440
613
  echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
441
614
  echo ""
615
+ log_info "Session ID: $session_id"
616
+ if [[ -n "$mode_override" ]]; then
617
+ log_info "Mode Override: $mode_override"
618
+ fi
619
+ log_info "Pipeline mode: $pipeline_mode"
620
+ log_info "Agents: $agent_count (critic: $([ "$critic_enabled" = "true" ] && echo "enabled" || echo "disabled"))"
621
+ if [[ -n "$refactor_model" ]]; then
622
+ log_info "Refactor Model: $refactor_model"
623
+ elif [[ -n "$MODEL" ]]; then
624
+ log_info "Model (env): $MODEL"
625
+ else
626
+ log_info "Model: (CLI default)"
627
+ fi
628
+ echo ""
442
629
  log_info "Bootstrap prompt written to:"
443
630
  echo " $bootstrap_prompt"
444
631
  echo ""
@@ -455,6 +642,18 @@ sys.exit(1)
455
642
  log_info "Session ID: $session_id"
456
643
  log_info "Prompt: $bootstrap_prompt"
457
644
  log_info "Log: $session_dir/logs/session.log"
645
+ local _run_one_mode_desc
646
+ case "$pipeline_mode" in
647
+ lite) _run_one_mode_desc="Tier 1 — Single Agent" ;;
648
+ standard) _run_one_mode_desc="Tier 2 — Orchestrator + Dev + Reviewer" ;;
649
+ full) _run_one_mode_desc="Tier 3 — Full Team (+ Multi-Critic)" ;;
650
+ *) _run_one_mode_desc="$pipeline_mode" ;;
651
+ esac
652
+ log_info "Pipeline mode: ${BOLD}$pipeline_mode${NC} ($_run_one_mode_desc)"
653
+ log_info "Agents: $agent_count (critic: $([ "$critic_enabled" = "true" ] && echo "enabled" || echo "disabled"))"
654
+ if [[ -n "$refactor_model" ]]; then
655
+ log_info "Refactor model: $refactor_model"
656
+ fi
458
657
  if [[ "$STRICT_BEHAVIOR_CHECK" == "1" ]]; then
459
658
  log_info "Strict behavior check: enabled"
460
659
  fi
@@ -492,7 +691,7 @@ sys.exit(1)
492
691
 
493
692
  spawn_and_wait_session \
494
693
  "$refactor_id" "$refactor_list" "$session_id" \
495
- "$bootstrap_prompt" "$session_dir" 999 "$_ORIGINAL_BRANCH"
694
+ "$bootstrap_prompt" "$session_dir" 999 "$refactor_model" "$_ORIGINAL_BRANCH"
496
695
  local session_status="$_SPAWN_RESULT"
497
696
 
498
697
  # Merge dev branch back to original on success
@@ -600,23 +799,13 @@ main() {
600
799
  echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
601
800
  echo ""
602
801
 
603
- # Branch lifecycle: create refactor branch for this pipeline run
802
+ # Branch lifecycle: per-refactor branches (like feature pipeline)
604
803
  local _proj_root
605
804
  _proj_root="$(cd "$SCRIPT_DIR/.." && pwd)"
606
805
  local _source_branch
607
806
  _source_branch=$(git -C "$_proj_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
608
807
  _ORIGINAL_BRANCH="$_source_branch"
609
808
 
610
- local run_id_for_branch
611
- run_id_for_branch=$(jq -r '.run_id' "$STATE_DIR/pipeline.json" 2>/dev/null || echo "$$")
612
- local _branch_name="${DEV_BRANCH:-refactor/pipeline-${run_id_for_branch}}"
613
- if branch_create "$_proj_root" "$_branch_name" "$_source_branch"; then
614
- _DEV_BRANCH_NAME="$_branch_name"
615
- log_info "Dev branch: $_branch_name"
616
- else
617
- log_warn "Failed to create refactor branch; running on current branch: $_source_branch"
618
- fi
619
-
620
809
  local session_count=0
621
810
  local total_subagent_calls=0
622
811
 
@@ -640,20 +829,11 @@ main() {
640
829
  log_success " Total subagent calls: $total_subagent_calls"
641
830
  log_success "════════════════════════════════════════════════════"
642
831
 
643
- # Merge dev branch back to original
644
- if [[ -n "$_DEV_BRANCH_NAME" ]]; then
645
- if branch_merge "$_proj_root" "$_DEV_BRANCH_NAME" "$_ORIGINAL_BRANCH" "$AUTO_PUSH"; then
646
- _DEV_BRANCH_NAME=""
647
- else
648
- log_warn "Auto-merge failed — dev branch preserved: $_DEV_BRANCH_NAME"
649
- log_warn "Merge manually: git checkout $_ORIGINAL_BRANCH && git rebase $_DEV_BRANCH_NAME"
650
- fi
651
- fi
652
832
  break
653
833
  fi
654
834
 
655
835
  if [[ "$next_refactor" == "PIPELINE_BLOCKED" ]]; then
656
- log_warn "All remaining refactors are blocked (needs_info/failed)."
836
+ log_warn "All remaining refactors are blocked (failed/dependency unmet)."
657
837
  log_warn "Run './run-refactor.sh status' to see details."
658
838
  log_warn "Waiting 60s before re-checking... (Ctrl+C to stop)"
659
839
  sleep 60
@@ -677,6 +857,23 @@ main() {
677
857
  fi
678
858
  echo -e "${BOLD}────────────────────────────────────────────────────${NC}"
679
859
 
860
+ # Pre-commit any dirty tree from previous iteration
861
+ if ! git -C "$_proj_root" diff --quiet HEAD 2>/dev/null || [ -n "$(git -C "$_proj_root" ls-files --others --exclude-standard 2>/dev/null)" ]; then
862
+ log_info "Dirty working tree detected — committing before $refactor_id..."
863
+ git -C "$_proj_root" add -A 2>/dev/null || true
864
+ git -C "$_proj_root" commit --no-verify -m "chore: capture artifacts before $refactor_id session" 2>/dev/null || true
865
+ fi
866
+
867
+ # Create per-refactor dev branch
868
+ local _refactor_branch="${DEV_BRANCH:-refactor/${refactor_id}-$(date +%Y%m%d%H%M)}"
869
+ if branch_create "$_proj_root" "$_refactor_branch" "$_ORIGINAL_BRANCH"; then
870
+ _DEV_BRANCH_NAME="$_refactor_branch"
871
+ log_info "Dev branch: $_refactor_branch"
872
+ else
873
+ log_warn "Failed to create dev branch; running on current branch: $_ORIGINAL_BRANCH"
874
+ _DEV_BRANCH_NAME=""
875
+ fi
876
+
680
877
  # Generate session
681
878
  local session_id run_id
682
879
  run_id=$(jq -r '.run_id' "$STATE_DIR/pipeline.json")
@@ -686,19 +883,62 @@ main() {
686
883
  mkdir -p "$session_dir/logs"
687
884
 
688
885
  local bootstrap_prompt="$session_dir/bootstrap-prompt.md"
689
- python3 "$SCRIPTS_DIR/generate-refactor-prompt.py" \
886
+
887
+ local main_prompt_args=(
888
+ --refactor-list "$refactor_list"
889
+ --refactor-id "$refactor_id"
890
+ --session-id "$session_id"
891
+ --run-id "$run_id"
892
+ --retry-count "$retry_count"
893
+ --resume-phase "$resume_phase"
894
+ --state-dir "$STATE_DIR"
895
+ --output "$bootstrap_prompt"
896
+ )
897
+
898
+ # Support PIPELINE_MODE env var (set by launch-refactor-daemon.sh --mode)
899
+ if [[ -n "${PIPELINE_MODE:-}" ]]; then
900
+ main_prompt_args+=(--mode "$PIPELINE_MODE")
901
+ fi
902
+
903
+ # Support ENABLE_CRITIC env var (set by launch-refactor-daemon.sh --critic)
904
+ if [[ "${ENABLE_CRITIC:-}" == "true" || "${ENABLE_CRITIC:-}" == "1" ]]; then
905
+ main_prompt_args+=(--critic "true")
906
+ elif [[ "${ENABLE_CRITIC:-}" == "false" || "${ENABLE_CRITIC:-}" == "0" ]]; then
907
+ main_prompt_args+=(--critic "false")
908
+ fi
909
+
910
+ local gen_output
911
+ gen_output=$(python3 "$SCRIPTS_DIR/generate-refactor-prompt.py" "${main_prompt_args[@]}" 2>/dev/null) || {
912
+ log_error "Failed to generate bootstrap prompt for $refactor_id"
913
+ continue
914
+ }
915
+ local refactor_model pipeline_mode agent_count critic_enabled
916
+ refactor_model=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('model',''))" 2>/dev/null || echo "")
917
+ pipeline_mode=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('pipeline_mode','standard'))" 2>/dev/null || echo "standard")
918
+ agent_count=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('agent_count',3))" 2>/dev/null || echo "3")
919
+ critic_enabled=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('critic_enabled','false'))" 2>/dev/null || echo "false")
920
+
921
+ # Log pipeline mode and agent configuration
922
+ local _mode_desc
923
+ case "$pipeline_mode" in
924
+ lite) _mode_desc="Tier 1 — Single Agent" ;;
925
+ standard) _mode_desc="Tier 2 — Orchestrator + Dev + Reviewer" ;;
926
+ full) _mode_desc="Tier 3 — Full Team (+ Multi-Critic)" ;;
927
+ *) _mode_desc="$pipeline_mode" ;;
928
+ esac
929
+ log_info "Pipeline mode: ${BOLD}$pipeline_mode${NC} ($_mode_desc)"
930
+ log_info "Agents: $agent_count (critic: $([ "$critic_enabled" = "true" ] && echo "enabled" || echo "disabled"))"
931
+
932
+ if [[ -n "$refactor_model" ]]; then
933
+ log_info "Refactor model: $refactor_model"
934
+ fi
935
+
936
+ # Mark refactor as in-progress before spawning session
937
+ python3 "$SCRIPTS_DIR/update-refactor-status.py" \
690
938
  --refactor-list "$refactor_list" \
691
- --refactor-id "$refactor_id" \
692
- --session-id "$session_id" \
693
- --run-id "$run_id" \
694
- --retry-count "$retry_count" \
695
- --resume-phase "$resume_phase" \
696
939
  --state-dir "$STATE_DIR" \
697
- --output "$bootstrap_prompt" >/dev/null 2>&1
698
-
699
- # Log agent configuration (refactor always uses dual-agent: Orchestrator + Dev + Reviewer)
700
- log_info "Pipeline mode: ${BOLD}standard${NC} (Dual Agent — Orchestrator + Dev + Reviewer)"
701
- log_info "Agents: 3 (critic: disabled)"
940
+ --refactor-id "$refactor_id" \
941
+ --action start >/dev/null 2>&1 || true
702
942
 
703
943
  # Spawn session
704
944
  log_info "Spawning AI CLI session: $session_id"
@@ -706,7 +946,50 @@ main() {
706
946
 
707
947
  spawn_and_wait_session \
708
948
  "$refactor_id" "$refactor_list" "$session_id" \
709
- "$bootstrap_prompt" "$session_dir" "$MAX_RETRIES" "$_ORIGINAL_BRANCH"
949
+ "$bootstrap_prompt" "$session_dir" "$MAX_RETRIES" "$refactor_model" "$_ORIGINAL_BRANCH"
950
+
951
+ # Validate key artifacts after successful session
952
+ if [[ "$_SPAWN_RESULT" == "success" ]]; then
953
+ local _artifact_root
954
+ _artifact_root="$(cd "$SCRIPT_DIR/.." && pwd)"
955
+ local plan_file="$_artifact_root/.prizmkit/refactor/$refactor_id/plan.md"
956
+ if [[ ! -f "$plan_file" ]]; then
957
+ log_warn "ARTIFACT_MISSING: plan.md not found at $plan_file"
958
+ else
959
+ log_info "ARTIFACT_CHECK: plan.md exists for $refactor_id"
960
+ fi
961
+ fi
962
+
963
+ local session_status="$_SPAWN_RESULT"
964
+
965
+ # Merge per-refactor dev branch back to original on success
966
+ if [[ "$session_status" == "success" && -n "$_DEV_BRANCH_NAME" ]]; then
967
+ if branch_merge "$_proj_root" "$_DEV_BRANCH_NAME" "$_ORIGINAL_BRANCH" "$AUTO_PUSH"; then
968
+ _DEV_BRANCH_NAME=""
969
+ else
970
+ log_warn "Auto-merge failed — dev branch preserved: $_DEV_BRANCH_NAME"
971
+ log_warn "Merge manually: git checkout $_ORIGINAL_BRANCH && git rebase $_DEV_BRANCH_NAME"
972
+ git -C "$_proj_root" checkout "$_ORIGINAL_BRANCH" 2>/dev/null || true
973
+ _DEV_BRANCH_NAME=""
974
+ fi
975
+ elif [[ -n "$_DEV_BRANCH_NAME" ]]; then
976
+ # Session failed — return to original branch, preserve dev branch for inspection
977
+ if ! git -C "$_proj_root" checkout "$_ORIGINAL_BRANCH" 2>/dev/null; then
978
+ log_warn "Failed to checkout $_ORIGINAL_BRANCH after session failure — staying on dev branch"
979
+ fi
980
+ log_warn "Session failed — dev branch preserved for inspection: $_DEV_BRANCH_NAME"
981
+ _DEV_BRANCH_NAME=""
982
+ fi
983
+
984
+ # Stuck detection
985
+ if python3 "$SCRIPTS_DIR/detect-stuck.py" \
986
+ --state-dir "$STATE_DIR" \
987
+ --pipeline-type refactor \
988
+ --refactor-list "$REFACTOR_LIST" \
989
+ --max-retries "$MAX_RETRIES" \
990
+ 2>/dev/null | jq -e '.stuck_count > 0' >/dev/null 2>&1; then
991
+ log_warn "STUCK_DETECTED: Some refactors may be stuck — run detect-stuck.py for details"
992
+ fi
710
993
 
711
994
  session_count=$((session_count + 1))
712
995
  total_subagent_calls=$((total_subagent_calls + _SUBAGENT_COUNT))
@@ -732,11 +1015,19 @@ show_help() {
732
1015
  echo ""
733
1016
  echo "Single Refactor Options (run <refactor-id>):"
734
1017
  echo " --dry-run Generate bootstrap prompt only, don't spawn session"
1018
+ echo " --clean Delete artifacts and reset before running"
1019
+ echo " --no-reset Skip status reset (preserve retry count)"
735
1020
  echo " --timeout N Session timeout in seconds (default: 0 = no limit)"
1021
+ echo " --mode <lite|standard|full> Override pipeline mode"
1022
+ echo " --critic Enable adversarial critic review"
1023
+ echo " --no-critic Disable adversarial critic review"
736
1024
  echo ""
737
1025
  echo "Environment Variables:"
738
1026
  echo " MAX_RETRIES Max retries per refactor (default: 3)"
739
1027
  echo " SESSION_TIMEOUT Session timeout in seconds (default: 0 = no limit)"
1028
+ echo " MODEL Default AI model (overridden by per-refactor model in refactor list)"
1029
+ echo " PIPELINE_MODE Default pipeline mode: lite|standard|full (overridden by --mode)"
1030
+ echo " ENABLE_CRITIC Enable/disable critic: true|false|1|0 (overridden by --critic/--no-critic)"
740
1031
  echo " AI_CLI AI CLI command name (auto-detected: cbc or claude)"
741
1032
  echo " VERBOSE Set to 1 for verbose AI CLI output"
742
1033
  echo " STRICT_BEHAVIOR_CHECK Force full test suite after each refactor (default: 1)"
@@ -780,6 +1071,40 @@ case "${1:-run}" in
780
1071
  rm -rf "$STATE_DIR"
781
1072
  log_success "Refactor state cleared. Run './run-refactor.sh run' to start fresh."
782
1073
  ;;
1074
+ unskip)
1075
+ check_dependencies
1076
+ if [[ ! -f "$STATE_DIR/pipeline.json" ]]; then
1077
+ log_error "No refactor pipeline state found. Run './run-refactor.sh run' first."
1078
+ exit 1
1079
+ fi
1080
+ _unskip_refactor_list=".prizmkit/plans/refactor-list.json"
1081
+ _unskip_refactor_id=""
1082
+ shift || true
1083
+ # Parse arguments: optional refactor-id and refactor-list path
1084
+ while [[ $# -gt 0 ]]; do
1085
+ if [[ "$1" =~ ^[Rr]-[0-9]+ ]]; then
1086
+ _unskip_refactor_id="$1"
1087
+ else
1088
+ _unskip_refactor_list="$1"
1089
+ fi
1090
+ shift
1091
+ done
1092
+ _unskip_args=(
1093
+ --refactor-list "$_unskip_refactor_list"
1094
+ --state-dir "$STATE_DIR"
1095
+ --action unskip
1096
+ )
1097
+ if [[ -n "$_unskip_refactor_id" ]]; then
1098
+ _unskip_args+=(--refactor-id "$_unskip_refactor_id")
1099
+ fi
1100
+ python3 "$SCRIPTS_DIR/update-refactor-status.py" "${_unskip_args[@]}"
1101
+
1102
+ # Commit the status change
1103
+ if ! git diff --quiet "$_unskip_refactor_list" 2>/dev/null; then
1104
+ git add "$_unskip_refactor_list"
1105
+ git commit -m "chore: unskip auto-skipped refactors" 2>/dev/null || true
1106
+ fi
1107
+ ;;
783
1108
  help|--help|-h)
784
1109
  show_help
785
1110
  ;;