prizmkit 1.1.8 → 1.1.9

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
@@ -1,18 +1,20 @@
1
1
  #!/usr/bin/env python3
2
2
  """Core state machine for updating refactor status in the refactor pipeline.
3
3
 
4
- Handles six actions:
4
+ Handles eight actions:
5
5
  - get_next: Find the next refactor to process based on dependency order, priority, complexity
6
+ - start: Mark a refactor as in_progress when a session starts
6
7
  - update: Update a refactor's status based on session outcome
7
8
  - status: Print a formatted overview of all refactors
8
9
  - pause: Save pipeline state for graceful shutdown
9
10
  - reset: Reset a refactor to pending (status + retry count)
10
11
  - clean: Reset + delete session history + delete refactor artifacts
12
+ - unskip: Reset skipped refactors and their downstream dependents back to pending
11
13
 
12
14
  Usage:
13
15
  python3 update-refactor-status.py \
14
16
  --refactor-list <path> --state-dir <path> \
15
- --action <get_next|update|status|pause|reset|clean> \
17
+ --action <get_next|start|update|status|pause|reset|clean|unskip> \
16
18
  [--refactor-id <id>] [--session-status <status>] \
17
19
  [--session-id <id>] [--max-retries <n>]
18
20
  """
@@ -21,6 +23,7 @@ import argparse
21
23
  import json
22
24
  import os
23
25
  import shutil
26
+ import sys
24
27
  from datetime import datetime, timezone
25
28
 
26
29
  from utils import (
@@ -39,10 +42,12 @@ SESSION_STATUS_VALUES = [
39
42
  "failed",
40
43
  "crashed",
41
44
  "timed_out",
45
+ "commit_missing",
46
+ "docs_missing",
42
47
  "merge_conflict",
43
48
  ]
44
49
 
45
- TERMINAL_STATUSES = {"completed", "failed", "skipped"}
50
+ TERMINAL_STATUSES = {"completed", "failed", "skipped", "auto_skipped"}
46
51
 
47
52
  # Artifact directory names (relative to project root)
48
53
  REFACTOR_ARTIFACTS_REL = os.path.join(".prizmkit", "refactor")
@@ -72,7 +77,7 @@ def parse_args():
72
77
  parser.add_argument("--state-dir", required=True, help="Path to the state directory (default: .prizmkit/state/refactor)")
73
78
  parser.add_argument(
74
79
  "--action", required=True,
75
- choices=["get_next", "update", "status", "pause", "reset", "clean"],
80
+ choices=["get_next", "start", "update", "status", "pause", "reset", "clean", "unskip", "complete"],
76
81
  help="Action to perform",
77
82
  )
78
83
  parser.add_argument("--refactor-id", default=None, help="Refactor ID (required for 'update'/'reset'/'clean' actions)")
@@ -272,16 +277,23 @@ def action_update(args, refactor_list_path, state_dir):
272
277
  if err:
273
278
  error_out("Failed to update .prizmkit/plans/refactor-list.json: {}".format(err))
274
279
  return
275
- elif session_status == "merge_conflict":
280
+ elif session_status in ("commit_missing", "docs_missing", "merge_conflict"):
281
+ # Degraded outcome: keep artifacts for retry.
282
+ # Write schema-valid status to refactor-list.json ("pending" for retry,
283
+ # "failed" if max retries exceeded). Store the granular degraded reason
284
+ # in status.json only (internal pipeline state, not schema-bound).
276
285
  rs["retry_count"] = rs.get("retry_count", 0) + 1
277
286
 
278
287
  if rs["retry_count"] >= max_retries:
279
288
  rs["status"] = "failed"
280
289
  target_status = "failed"
281
290
  else:
282
- rs["status"] = "merge_conflict"
283
- target_status = "merge_conflict"
291
+ # status.json keeps the granular degraded reason for diagnostics
292
+ rs["status"] = session_status
293
+ # refactor-list.json gets schema-valid "pending" (will be retried)
294
+ target_status = "pending"
284
295
 
296
+ rs["degraded_reason"] = session_status
285
297
  rs["resume_from_phase"] = None
286
298
  rs["sessions"] = []
287
299
  rs["last_session_id"] = None
@@ -329,6 +341,13 @@ def action_update(args, refactor_list_path, state_dir):
329
341
  error_out("Failed to save refactor status: {}".format(err))
330
342
  return
331
343
 
344
+ # Auto-skip downstream refactors when this refactor is marked as failed or skipped
345
+ auto_skipped_refactors = []
346
+ if rs["status"] in ("failed", "skipped"):
347
+ auto_skipped_refactors = auto_skip_blocked_refactors(
348
+ refactor_list_path, state_dir, refactor_id
349
+ )
350
+
332
351
  summary = {
333
352
  "action": "update",
334
353
  "refactor_id": refactor_id,
@@ -338,8 +357,10 @@ def action_update(args, refactor_list_path, state_dir):
338
357
  "resume_from_phase": rs.get("resume_from_phase"),
339
358
  "updated_at": rs["updated_at"],
340
359
  }
341
- if session_status == "merge_conflict":
342
- summary["degraded_reason"] = "merge_conflict"
360
+ if auto_skipped_refactors:
361
+ summary["auto_skipped"] = [info["refactor_id"] for info in auto_skipped_refactors]
362
+ if session_status in ("commit_missing", "docs_missing", "merge_conflict"):
363
+ summary["degraded_reason"] = session_status
343
364
  summary["restart_policy"] = "finalization_retry"
344
365
  elif session_status != "success":
345
366
  summary["restart_policy"] = "full_restart"
@@ -410,6 +431,116 @@ def load_session_status(state_dir, refactor_id, session_id):
410
431
  return data, None
411
432
 
412
433
 
434
+ # ---------------------------------------------------------------------------
435
+ # Auto-skip: cascade failure to blocked downstream refactors
436
+ # ---------------------------------------------------------------------------
437
+
438
+ def auto_skip_blocked_refactors(refactor_list_path, state_dir, failed_refactor_id):
439
+ """Recursively mark all downstream refactors blocked by a failed refactor as auto_skipped.
440
+
441
+ When a refactor is marked as failed, any refactor whose dependency chain includes
442
+ the failed refactor can never be executed. This function propagates the failure
443
+ by marking those blocked refactors as auto_skipped, allowing the pipeline to
444
+ continue processing unblocked refactors and eventually reach PIPELINE_COMPLETE.
445
+
446
+ Re-reads .prizmkit/plans/refactor-list.json from disk to get the latest state (including the
447
+ just-written failed status from update_refactor_in_list).
448
+
449
+ NOTE: This function performs a read-modify-write on .prizmkit/plans/refactor-list.json without
450
+ file locking. The caller (action_update) also writes to .prizmkit/plans/refactor-list.json
451
+ immediately before calling this. Safe for single-pipeline execution, but if
452
+ multiple pipeline instances share the same .prizmkit/plans/refactor-list.json concurrently,
453
+ a race condition may cause lost writes. Add file locking if parallel pipelines
454
+ are introduced.
455
+ """
456
+ data, err = load_json_file(refactor_list_path)
457
+ if err:
458
+ return []
459
+ refactors = data.get("refactors", [])
460
+
461
+ # Build current status map
462
+ status_map = {}
463
+ for r in refactors:
464
+ if isinstance(r, dict) and r.get("id"):
465
+ status_map[r["id"]] = r.get("status", "pending")
466
+
467
+ # Collect all refactors to auto-skip (recursive propagation)
468
+ to_skip = set()
469
+ changed = True
470
+ while changed:
471
+ changed = False
472
+ for r in refactors:
473
+ if not isinstance(r, dict):
474
+ continue
475
+ rid = r.get("id")
476
+ if not rid or rid in to_skip:
477
+ continue
478
+ current = status_map.get(rid, "pending")
479
+ if current in TERMINAL_STATUSES:
480
+ continue
481
+ deps = r.get("dependencies", [])
482
+ for dep_id in deps:
483
+ dep_status = status_map.get(dep_id, "pending")
484
+ if dep_status in ("failed", "skipped", "auto_skipped") or dep_id in to_skip:
485
+ to_skip.add(rid)
486
+ status_map[rid] = "auto_skipped"
487
+ changed = True
488
+ break
489
+
490
+ if not to_skip:
491
+ return []
492
+
493
+ # Batch-write to .prizmkit/plans/refactor-list.json
494
+ for r in refactors:
495
+ if isinstance(r, dict) and r.get("id") in to_skip:
496
+ r["status"] = "auto_skipped"
497
+ write_json_file(refactor_list_path, data)
498
+
499
+ # Sync status.json for each auto-skipped refactor
500
+ for rid in to_skip:
501
+ rs = load_refactor_status(state_dir, rid)
502
+ rs["status"] = "auto_skipped"
503
+ rs["updated_at"] = now_iso()
504
+ save_refactor_status(state_dir, rid, rs)
505
+
506
+ # Build blocking reason map for logging
507
+ skipped_info = []
508
+ for r in refactors:
509
+ if not isinstance(r, dict):
510
+ continue
511
+ rid = r.get("id")
512
+ if rid not in to_skip:
513
+ continue
514
+ deps = r.get("dependencies", [])
515
+ blockers = [
516
+ d for d in deps
517
+ if d == failed_refactor_id or d in to_skip
518
+ ]
519
+ skipped_info.append({
520
+ "refactor_id": rid,
521
+ "title": r.get("title", ""),
522
+ "blocked_by": blockers,
523
+ })
524
+
525
+ print(
526
+ "[auto-skip] {} refactor(s) auto-skipped due to failed {}:".format(
527
+ len(skipped_info), failed_refactor_id
528
+ ),
529
+ file=sys.stderr,
530
+ )
531
+ for info in skipped_info:
532
+ print(
533
+ " {} ({}) — blocked by {}".format(
534
+ info["refactor_id"],
535
+ info["title"],
536
+ ", ".join(info["blocked_by"]),
537
+ ),
538
+ file=sys.stderr,
539
+ )
540
+
541
+ return skipped_info
542
+
543
+
413
544
  # ---------------------------------------------------------------------------
414
545
  # Action: status
415
546
  # ---------------------------------------------------------------------------
@@ -445,7 +576,7 @@ def action_status(refactor_list_data, state_dir):
445
576
  refactors = refactor_list_data.get("refactors", [])
446
577
  project_name = refactor_list_data.get("project_name", "Unknown")
447
578
 
448
- counts = {"completed": 0, "in_progress": 0, "failed": 0, "pending": 0, "skipped": 0}
579
+ counts = {"completed": 0, "in_progress": 0, "failed": 0, "pending": 0, "skipped": 0, "auto_skipped": 0}
449
580
  refactor_lines = []
450
581
 
451
582
  for r in refactors:
@@ -478,6 +609,8 @@ def action_status(refactor_list_data, state_dir):
478
609
  icon = COLOR_RED + "[✗]" + COLOR_RESET
479
610
  elif rstatus == "skipped":
480
611
  icon = COLOR_GRAY + "[—]" + COLOR_RESET
612
+ elif rstatus == "auto_skipped":
613
+ icon = COLOR_GRAY + "[⊘]" + COLOR_RESET
481
614
  else:
482
615
  icon = COLOR_GRAY + "[ ]" + COLOR_RESET
483
616
 
@@ -525,8 +658,8 @@ def action_status(refactor_list_data, state_dir):
525
658
  summary_line = "Total: {} refactors | Completed: {} | In Progress: {}".format(
526
659
  total, completed, counts["in_progress"]
527
660
  )
528
- summary_line2 = "Failed: {} | Pending: {} | Skipped: {}".format(
529
- counts["failed"], counts["pending"], counts["skipped"]
661
+ summary_line2 = "Failed: {} | Pending: {} | Skipped: {} | Auto-skipped: {}".format(
662
+ counts["failed"], counts["pending"], counts["skipped"], counts["auto_skipped"]
530
663
  )
531
664
 
532
665
  inner = BOX_WIDTH - 2
@@ -685,6 +818,195 @@ def action_pause(state_dir):
685
818
  print(json.dumps(result, indent=2, ensure_ascii=False))
686
819
 
687
820
 
821
+ # ---------------------------------------------------------------------------
822
+ # Action: start
823
+ # ---------------------------------------------------------------------------
824
+
825
+ def action_start(args, refactor_list_path, state_dir):
826
+ """Mark a refactor as in_progress when a session starts.
827
+
828
+ This keeps refactor-list.json/state status in sync during execution,
829
+ instead of only updating after session end.
830
+ """
831
+ refactor_id = args.refactor_id
832
+ if not refactor_id:
833
+ error_out("--refactor-id is required for 'start' action")
834
+ return
835
+
836
+ rs = load_refactor_status(state_dir, refactor_id)
837
+ old_status = rs.get("status", "pending")
838
+
839
+ rs["status"] = "in_progress"
840
+ rs["updated_at"] = now_iso()
841
+
842
+ err = save_refactor_status(state_dir, refactor_id, rs)
843
+ if err:
844
+ error_out("Failed to save refactor status: {}".format(err))
845
+ return
846
+
847
+ err = update_refactor_in_list(refactor_list_path, refactor_id, "in_progress")
848
+ if err:
849
+ error_out("Failed to update .prizmkit/plans/refactor-list.json: {}".format(err))
850
+ return
851
+
852
+ result = {
853
+ "action": "start",
854
+ "refactor_id": refactor_id,
855
+ "old_status": old_status,
856
+ "new_status": "in_progress",
857
+ "updated_at": rs["updated_at"],
858
+ }
859
+ print(json.dumps(result, indent=2, ensure_ascii=False))
860
+
861
+
862
+ # ---------------------------------------------------------------------------
863
+ # Action: unskip
864
+ # ---------------------------------------------------------------------------
865
+
866
+ def action_unskip(args, refactor_list_path, state_dir):
867
+ """Recover skipped/auto_skipped/failed refactors by resetting them and their failed upstream.
868
+
869
+ Two modes:
870
+ - --refactor-id R-001: Reset the specified failed/skipped/auto_skipped refactor + all
871
+ downstream auto_skipped refactors whose dependency chain includes it.
872
+ If the target is auto_skipped, also walk upstream to find and reset the
873
+ failed/skipped ancestor that caused the cascade.
874
+ - No --refactor-id: Reset ALL failed, skipped, and auto_skipped refactors to pending.
875
+ """
876
+ refactor_id = args.refactor_id
877
+
878
+ data, err = load_json_file(refactor_list_path)
879
+ if err:
880
+ error_out("Cannot load refactor list: {}".format(err))
881
+ return
882
+ refactors = data.get("refactors", [])
883
+
884
+ to_reset = set()
885
+
886
+ if refactor_id:
887
+ # Find the target refactor
888
+ target = None
889
+ for r in refactors:
890
+ if isinstance(r, dict) and r.get("id") == refactor_id:
891
+ target = r
892
+ break
893
+ if not target:
894
+ error_out("Refactor '{}' not found in .prizmkit/plans/refactor-list.json".format(refactor_id))
895
+ return
896
+ if target.get("status") not in ("failed", "skipped", "auto_skipped"):
897
+ error_out(
898
+ "Refactor '{}' has status '{}', expected 'failed', 'skipped', or 'auto_skipped'".format(
899
+ refactor_id, target.get("status", "unknown")
900
+ )
901
+ )
902
+ return
903
+
904
+ # If target is failed or skipped, reset it and find all auto_skipped descendants
905
+ if target.get("status") in ("failed", "skipped"):
906
+ to_reset.add(refactor_id)
907
+ # Find all auto_skipped refactors that depend (transitively) on this one
908
+ changed = True
909
+ while changed:
910
+ changed = False
911
+ for r in refactors:
912
+ if not isinstance(r, dict):
913
+ continue
914
+ rid = r.get("id")
915
+ if not rid or rid in to_reset:
916
+ continue
917
+ if r.get("status") != "auto_skipped":
918
+ continue
919
+ deps = r.get("dependencies", [])
920
+ if any(d in to_reset for d in deps):
921
+ to_reset.add(rid)
922
+ changed = True
923
+
924
+ # If target is auto_skipped, reset it and its failed upstream + siblings
925
+ elif target.get("status") == "auto_skipped":
926
+ to_reset.add(refactor_id)
927
+ # Transitively walk upstream to find ALL failed/auto_skipped ancestors
928
+ # (e.g., R-001 failed → R-002 auto_skipped → R-003 auto_skipped;
929
+ # unskip R-003 must also find and reset R-001)
930
+ upstream_changed = True
931
+ while upstream_changed:
932
+ upstream_changed = False
933
+ for r in refactors:
934
+ if not isinstance(r, dict):
935
+ continue
936
+ rid = r.get("id")
937
+ if not rid or rid not in to_reset:
938
+ continue
939
+ for dep_id in r.get("dependencies", []):
940
+ if dep_id in to_reset:
941
+ continue
942
+ for dep_r in refactors:
943
+ if isinstance(dep_r, dict) and dep_r.get("id") == dep_id:
944
+ if dep_r.get("status") in ("failed", "skipped", "auto_skipped"):
945
+ to_reset.add(dep_id)
946
+ upstream_changed = True
947
+ # Also reset downstream auto_skipped refactors blocked by the same upstreams
948
+ changed = True
949
+ while changed:
950
+ changed = False
951
+ for r in refactors:
952
+ if not isinstance(r, dict):
953
+ continue
954
+ rid = r.get("id")
955
+ if not rid or rid in to_reset:
956
+ continue
957
+ if r.get("status") != "auto_skipped":
958
+ continue
959
+ rdeps = r.get("dependencies", [])
960
+ if any(d in to_reset for d in rdeps):
961
+ to_reset.add(rid)
962
+ changed = True
963
+ else:
964
+ # No refactor-id: reset ALL failed + skipped + auto_skipped
965
+ for r in refactors:
966
+ if isinstance(r, dict) and r.get("id"):
967
+ if r.get("status") in ("failed", "skipped", "auto_skipped"):
968
+ to_reset.add(r["id"])
969
+
970
+ if not to_reset:
971
+ error_out("No refactors to unskip")
972
+ return
973
+
974
+ # Reset all collected refactors in refactor-list.json
975
+ reset_details = []
976
+ for r in refactors:
977
+ if isinstance(r, dict) and r.get("id") in to_reset:
978
+ old_status = r.get("status", "unknown")
979
+ r["status"] = "pending"
980
+ reset_details.append({
981
+ "refactor_id": r["id"],
982
+ "title": r.get("title", ""),
983
+ "old_status": old_status,
984
+ })
985
+
986
+ err = write_json_file(refactor_list_path, data)
987
+ if err:
988
+ error_out("Failed to write .prizmkit/plans/refactor-list.json: {}".format(err))
989
+ return
990
+
991
+ # Reset status.json for each refactor
992
+ for rid in to_reset:
993
+ rs = load_refactor_status(state_dir, rid)
994
+ rs["status"] = "pending"
995
+ rs["retry_count"] = 0
996
+ rs["sessions"] = []
997
+ rs["last_session_id"] = None
998
+ rs["resume_from_phase"] = None
999
+ rs["updated_at"] = now_iso()
1000
+ save_refactor_status(state_dir, rid, rs)
1001
+
1002
+ result = {
1003
+ "action": "unskip",
1004
+ "reset_count": len(to_reset),
1005
+ "refactors": reset_details,
1006
+ }
1007
+ print(json.dumps(result, indent=2, ensure_ascii=False))
1008
+
1009
+
688
1010
  # ---------------------------------------------------------------------------
689
1011
  # Main
690
1012
  # ---------------------------------------------------------------------------
@@ -697,7 +1019,7 @@ def main():
697
1019
  error_out("--refactor-id is required for 'update' action")
698
1020
  if not args.session_status:
699
1021
  error_out("--session-status is required for 'update' action")
700
- if args.action in ("reset", "clean"):
1022
+ if args.action in ("start", "reset", "clean", "complete"):
701
1023
  if not args.refactor_id:
702
1024
  error_out("--refactor-id is required for '{}' action".format(args.action))
703
1025
  if args.action == "clean":
@@ -718,8 +1040,16 @@ def main():
718
1040
  action_reset(args, args.refactor_list, args.state_dir)
719
1041
  elif args.action == "clean":
720
1042
  action_clean(args, args.refactor_list, args.state_dir)
1043
+ elif args.action == "start":
1044
+ action_start(args, args.refactor_list, args.state_dir)
721
1045
  elif args.action == "pause":
722
1046
  action_pause(args.state_dir)
1047
+ elif args.action == "unskip":
1048
+ action_unskip(args, args.refactor_list, args.state_dir)
1049
+ elif args.action == "complete":
1050
+ # Shortcut: 'complete' is equivalent to 'update --session-status success'
1051
+ args.session_status = "success"
1052
+ action_update(args, args.refactor_list, args.state_dir)
723
1053
 
724
1054
 
725
1055
  if __name__ == "__main__":
@@ -1,5 +1,5 @@
1
1
  "Read {{DEV_SUBAGENT_PATH}}. Fix NEEDS_FIXES issues for feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}).
2
- 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` — '## Review Notes' section contains structured Fix Instructions with exact steps.
2
+ 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/review-report.md` — contains structured Fix Instructions with exact steps.
3
3
  2. Follow Fix Instructions in order (respect Depends On / Blocks dependencies). Each FIX-N has: Root Cause, Fix Strategy, Code Guidance, and Verification criteria.
4
4
  3. After each fix, run the Verification command listed in that FIX-N to confirm it works.
5
5
  4. Run `{{TEST_CMD}}` to verify no regressions.
@@ -1,12 +1,8 @@
1
1
  "Read {{REVIEWER_SUBAGENT_PATH}}. For feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}):
2
- **IMPORTANT**: Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST.
3
- 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`:
4
- - Section 3: Prizm Context (RULES, PATTERNS to check against)
5
- - Section 4: File Manifest (original file structure)
6
- - '## Implementation Log': what Dev changed, key decisions, discoveries
7
- - '## Acceptance Criteria Verification Checklist': verify all items are [x]
8
- 2. **AC Verification Gate**: Check that AC Verification Checklist shows ALL criteria marked [x]. If any [ ] remains, return verdict NEEDS_FIXES with message "AC Verification incomplete: [list unmet criteria]"
9
- 3. Run prizmkit-code-review (both phases): Phase 1 diagnostic review (spec compliance, code quality, correctness), then Phase 2 fix strategy formulation for any findings. Read ONLY files listed in Implementation Log for diagnosis; MAY read additional files for impact analysis.
10
- 4. Run the full test suite using `{{TEST_CMD}}` — **ONLY if the Implementation Log does not already confirm all tests passing**. If Implementation Log states tests passed, trust it and skip the re-run. When running tests: `{{TEST_CMD}} 2>&1 | tee /tmp/review-test-out.txt | tail -20`, then grep `/tmp/review-test-out.txt` for details — do NOT re-run the suite multiple times. Write and execute integration tests covering all user stories from spec.md.
11
- 5. Write structured '## Review Notes' to context-snapshot.md with Fix Instructions (Root Cause, Impact, Fix Strategy, Code Guidance, Verification for each finding) and Re-Review Expectations.
12
- Report verdict: PASS, PASS_WITH_WARNINGS, or NEEDS_FIXES."
2
+ 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/spec.md` (if it exists) for goals and acceptance criteria; if spec.md does not exist, read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` Section 1 instead
3
+ 2. Read `.prizmkit/specs/{{FEATURE_SLUG}}/plan.md` for architecture decisions and completed tasks
4
+ 3. Read `.prizm-docs/root.prizm` and relevant L1/L2 docs for RULES, PATTERNS, TRAPS
5
+ 4. Run /prizmkit-code-review with artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/: Phase 1 diagnostic review across all applicable dimensions, then Phase 2 fix strategy for any findings. Read ONLY files referenced in completed plan.md tasks for diagnosis; MAY read additional files for impact analysis.
6
+ 5. Run the full test suite using `{{TEST_CMD}}`. When running tests: `{{TEST_CMD}} 2>&1 | tee /tmp/review-test-out.txt | tail -20`, then grep `/tmp/review-test-out.txt` for details — do NOT re-run the suite multiple times. Write and execute integration tests covering all goals from spec.md.
7
+ 6. review-report.md will be written to .prizmkit/specs/{{FEATURE_SLUG}}/ by prizmkit-code-review.
8
+ Report: number of findings found, or 'no findings' if clean."
@@ -1,10 +1,44 @@
1
- # DEPRECATED bootstrap-prompt.md
1
+ # Dev-Pipeline Fallback Bootstrap Prompt
2
2
 
3
- This file has been replaced by tier-specific templates:
3
+ > **Note**: This is an emergency fallback template. Normally, `generate-bootstrap-prompt.py`
4
+ > selects a tier-specific template (`bootstrap-tier1.md`, `bootstrap-tier2.md`, or `bootstrap-tier3.md`).
5
+ > If you are seeing this prompt, the tier-specific templates were not found.
4
6
 
5
- - `bootstrap-tier1.md` — Tier 1: Single Agent (complexity: low)
6
- - `bootstrap-tier2.md` — Tier 2: Dual Agent (complexity: medium)
7
- - `bootstrap-tier3.md` — Tier 3: Full Team (complexity: high)
7
+ ## Feature Context
8
8
 
9
- `generate-bootstrap-prompt.py` selects the correct file automatically based on `estimated_complexity`.
10
- This file is kept as a fallback only — if none of the tier files exist, the script falls back to this path.
9
+ - **Feature ID**: {{FEATURE_ID}}
10
+ - **Title**: {{FEATURE_TITLE}}
11
+ - **Description**: {{FEATURE_DESCRIPTION}}
12
+ - **Slug**: {{FEATURE_SLUG}}
13
+
14
+ ### Acceptance Criteria
15
+
16
+ {{ACCEPTANCE_CRITERIA}}
17
+
18
+ ## Instructions
19
+
20
+ You are running in **headless non-interactive mode** — no human is available for input.
21
+ Infer what needs to be done from the feature context above and follow the standard dev loop.
22
+
23
+ ### Execution Steps
24
+
25
+ 1. **Read context**: Read `.prizm-docs/root.prizm` and relevant L1/L2 docs to understand the codebase.
26
+
27
+ 2. **Plan**: Run `/prizmkit-plan` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/` to produce `spec.md` and `plan.md`.
28
+
29
+ 3. **Implement**: Run `/prizmkit-implement` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/` to execute the plan using TDD (write tests first, then implement).
30
+
31
+ 4. **Test**: Run the project test suite to verify all tests pass with no regressions.
32
+
33
+ 5. **Review**: Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/` to review changes against the spec. If findings exist, fix them and re-review (max 2 rounds).
34
+
35
+ 6. **Retrospective**: Run `/prizmkit-retrospective` to sync `.prizm-docs/` with code changes.
36
+
37
+ 7. **Commit**: Run `/prizmkit-committer` to commit all changes. Do NOT push.
38
+
39
+ ### Critical Rules
40
+
41
+ - Do NOT ask for user input — decide autonomously.
42
+ - Do NOT push to remote — the user will push manually.
43
+ - Write all artifacts to `.prizmkit/specs/{{FEATURE_SLUG}}/`.
44
+ - If a step fails after 3 attempts, write a status report and stop.
@@ -39,7 +39,9 @@ You are the **session orchestrator**. Implement Feature {{FEATURE_ID}}: "{{FEATU
39
39
 
40
40
  ## ⚠️ Context Budget Rules (CRITICAL — read before any phase)
41
41
 
42
- You are running in headless mode with a FINITE context window. Exceeding it will crash the session and lose all work. Follow these rules strictly:
42
+ You are running in **headless non-interactive mode** with a FINITE context window. Exceeding it will crash the session and lose all work. Follow these rules strictly:
43
+
44
+ 0. **NON-INTERACTIVE MODE** — There is NO human on the other end. NEVER ask for user confirmation, NEVER wait for user input, NEVER use interactive prompts (e.g. "Would you like me to…"). If a skill has an interactive step (e.g. offer remediation, ask for approval), skip it and proceed autonomously. Make decisions based on the data available and move forward.
43
45
 
44
46
  1. **context-snapshot.md is your single source of truth** — After Phase 1 builds it, ALWAYS read context-snapshot.md instead of re-reading individual source files
45
47
  2. **Never re-read your own writes** — After you create/modify a file, do NOT read it back to verify. Trust your write was correct.
@@ -232,7 +234,7 @@ You just implemented this feature — you know the project's tech stack and buil
232
234
  3. **Assess and record** — append to context-snapshot.md:
233
235
  - **ALL builds pass** → `## Deploy Verification: PASS` — proceed to commit
234
236
  - **Some builds fail with fixable errors** → fix and re-verify (already handled in step 2)
235
- - **Cannot build locally** (missing system-level deps you cannot install) → Generate `DEPLOY.md` with:
237
+ - **Cannot build locally** (missing system-level deps you cannot install) → Generate `.prizmkit/deploy.md` with:
236
238
  ```
237
239
  # Local Development Setup
238
240
 
@@ -248,7 +250,7 @@ You just implemented this feature — you know the project's tech stack and buil
248
250
  ## Verify
249
251
  [how to confirm the app is running correctly]
250
252
  ```
251
- Record: `## Deploy Verification: PARTIAL — see DEPLOY.md for missing prerequisites`
253
+ Record: `## Deploy Verification: PARTIAL — see .prizmkit/deploy.md for missing prerequisites`
252
254
 
253
255
  Deploy verification does NOT block the commit, but you MUST attempt it.
254
256
 
@@ -289,6 +291,28 @@ Working tree MUST be clean after this step. If any feature-related files remain,
289
291
 
290
292
  **Exception**: `session-summary.md` in the artifact directory is a local cross-session artifact generated by `/prizmkit-committer` — it is NOT committed to git. Ignore it in the clean-tree check.
291
293
 
294
+ **4e.** Write completion summary for downstream dependency context:
295
+
296
+ Write `.prizmkit/specs/{{FEATURE_SLUG}}/completion-summary.json` with the key changes from this session. This file is NOT committed to git — the pipeline runner reads it to propagate context to dependent features.
297
+
298
+ ```json
299
+ {
300
+ "completion_notes": [
301
+ "<each item: one key change, API, model, or integration point that downstream features may need>",
302
+ "Example: Added User model (id, email, password_hash, display_name) in prisma/schema.prisma",
303
+ "Example: POST /api/auth/register and POST /api/auth/login endpoints in src/api/auth.ts",
304
+ "Example: Auth middleware in src/middleware/auth.ts — validates JWT on protected routes"
305
+ ]
306
+ }
307
+ ```
308
+
309
+ Rules for writing completion notes:
310
+ - Focus on **what downstream features need to know**: new APIs, models, exported functions, key file paths
311
+ - Each note should be self-contained and concise (one line, under 120 characters preferred)
312
+ - Include 3-8 notes covering the most important changes
313
+ - Do NOT include test files, config changes, or internal implementation details unless they affect other features
314
+ - If this feature has no downstream dependents, still write the summary (it serves as documentation)
315
+
292
316
  ## Critical Paths
293
317
 
294
318
  | Resource | Path |