prizmkit 1.1.6 → 1.1.8

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 (63) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/dev-pipeline/README.md +65 -65
  3. package/bundled/dev-pipeline/assets/feature-list-example.json +2 -2
  4. package/bundled/dev-pipeline/launch-bugfix-daemon.sh +11 -10
  5. package/bundled/dev-pipeline/launch-feature-daemon.sh +12 -11
  6. package/bundled/dev-pipeline/launch-refactor-daemon.sh +11 -10
  7. package/bundled/dev-pipeline/reset-bug.sh +305 -0
  8. package/bundled/dev-pipeline/reset-feature.sh +9 -8
  9. package/bundled/dev-pipeline/reset-refactor.sh +10 -9
  10. package/bundled/dev-pipeline/retry-bugfix.sh +7 -6
  11. package/bundled/dev-pipeline/retry-feature.sh +7 -6
  12. package/bundled/dev-pipeline/retry-refactor.sh +7 -6
  13. package/bundled/dev-pipeline/run-bugfix.sh +71 -23
  14. package/bundled/dev-pipeline/run-feature.sh +30 -21
  15. package/bundled/dev-pipeline/run-refactor.sh +21 -17
  16. package/bundled/dev-pipeline/scripts/cleanup-logs.py +2 -2
  17. package/bundled/dev-pipeline/scripts/detect-stuck.py +3 -3
  18. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +26 -14
  19. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +6 -6
  20. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +6 -6
  21. package/bundled/dev-pipeline/scripts/init-bugfix-pipeline.py +4 -4
  22. package/bundled/dev-pipeline/scripts/init-pipeline.py +26 -12
  23. package/bundled/dev-pipeline/scripts/init-refactor-pipeline.py +4 -4
  24. package/bundled/dev-pipeline/scripts/update-bug-status.py +10 -10
  25. package/bundled/dev-pipeline/scripts/update-feature-status.py +31 -31
  26. package/bundled/dev-pipeline/scripts/update-refactor-status.py +8 -8
  27. package/bundled/dev-pipeline/templates/bug-fix-list-schema.json +111 -31
  28. package/bundled/dev-pipeline/templates/feature-list-schema.json +91 -25
  29. package/bundled/dev-pipeline/templates/refactor-list-schema.json +107 -28
  30. package/bundled/dev-pipeline/tests/test_auto_skip.py +1 -1
  31. package/bundled/skills/_metadata.json +10 -2
  32. package/bundled/skills/app-planner/SKILL.md +24 -13
  33. package/bundled/skills/app-planner/references/project-brief-guide.md +1 -1
  34. package/bundled/skills/bug-fix-workflow/SKILL.md +7 -5
  35. package/bundled/skills/bug-planner/SKILL.md +80 -25
  36. package/bundled/skills/bug-planner/scripts/validate-bug-list.py +3 -3
  37. package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +38 -33
  38. package/bundled/skills/feature-pipeline-launcher/SKILL.md +33 -33
  39. package/bundled/skills/feature-pipeline-launcher/scripts/preflight-check.py +3 -3
  40. package/bundled/skills/feature-planner/SKILL.md +96 -24
  41. package/bundled/skills/feature-planner/references/error-recovery.md +9 -9
  42. package/bundled/skills/feature-planner/scripts/validate-and-generate.py +25 -24
  43. package/bundled/skills/feature-workflow/SKILL.md +23 -20
  44. package/bundled/skills/prizmkit-committer/SKILL.md +1 -0
  45. package/bundled/skills/prizmkit-deploy/SKILL.md +1 -0
  46. package/bundled/skills/prizmkit-deploy/assets/deploy-template.md +1 -1
  47. package/bundled/skills/prizmkit-implement/SKILL.md +1 -1
  48. package/bundled/skills/prizmkit-implement/references/deploy-guide-protocol.md +4 -4
  49. package/bundled/skills/prizmkit-plan/SKILL.md +3 -3
  50. package/bundled/skills/prizmkit-retrospective/SKILL.md +40 -3
  51. package/bundled/skills/prizmkit-verify/SKILL.md +281 -0
  52. package/bundled/skills/prizmkit-verify/scripts/verify-light.py +402 -0
  53. package/bundled/skills/recovery-workflow/SKILL.md +15 -14
  54. package/bundled/skills/recovery-workflow/evals/evals.json +5 -5
  55. package/bundled/skills/recovery-workflow/scripts/detect-recovery-state.py +43 -10
  56. package/bundled/skills/refactor-pipeline-launcher/SKILL.md +38 -34
  57. package/bundled/skills/refactor-planner/SKILL.md +74 -24
  58. package/bundled/skills/refactor-planner/scripts/validate-and-generate-refactor.py +17 -17
  59. package/bundled/skills/refactor-workflow/SKILL.md +24 -20
  60. package/package.json +1 -1
  61. package/src/clean.js +4 -4
  62. package/src/gitignore-template.js +7 -8
  63. package/src/scaffold.js +4 -2
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
- """Generate a session-specific bug fix bootstrap prompt from template and bug-fix-list.json.
2
+ """Generate a session-specific bug fix bootstrap prompt from template and .prizmkit/plans/bug-fix-list.json.
3
3
 
4
- Reads the bugfix-bootstrap-prompt.md template and a bug-fix-list.json, resolves all
4
+ Reads the bugfix-bootstrap-prompt.md template and a .prizmkit/plans/bug-fix-list.json, resolves all
5
5
  {{PLACEHOLDER}} variables, handles conditional blocks, and writes the rendered
6
6
  prompt to the specified output path.
7
7
 
@@ -31,16 +31,16 @@ def parse_args():
31
31
  parser = argparse.ArgumentParser(
32
32
  description=(
33
33
  "Generate a session-specific bug fix bootstrap prompt from a template "
34
- "and bug-fix-list.json."
34
+ "and .prizmkit/plans/bug-fix-list.json."
35
35
  )
36
36
  )
37
- parser.add_argument("--bug-list", required=True, help="Path to bug-fix-list.json")
37
+ parser.add_argument("--bug-list", required=True, help="Path to .prizmkit/plans/bug-fix-list.json")
38
38
  parser.add_argument("--bug-id", required=True, help="Bug ID to generate prompt for (e.g. B-001)")
39
39
  parser.add_argument("--session-id", required=True, help="Session ID for this pipeline session")
40
40
  parser.add_argument("--run-id", required=True, help="Pipeline run ID")
41
41
  parser.add_argument("--retry-count", required=True, help="Current retry count")
42
42
  parser.add_argument("--resume-phase", required=True, help='Phase to resume from, or "null" for fresh start')
43
- parser.add_argument("--state-dir", default=None, help="State directory path for reading previous session info")
43
+ parser.add_argument("--state-dir", default=None, help="State directory (default: .prizmkit/state/bugfix)")
44
44
  parser.add_argument("--output", required=True, help="Output path for the rendered prompt")
45
45
  parser.add_argument("--template", default=None, help="Custom template path. Defaults to {script_dir}/../templates/bugfix-bootstrap-prompt.md")
46
46
  return parser.parse_args()
@@ -217,7 +217,7 @@ def build_replacements(args, bug, global_context, script_dir):
217
217
 
218
218
  # Session status path
219
219
  session_status_path = os.path.join(
220
- project_root, "dev-pipeline", "bugfix-state", "bugs", args.bug_id,
220
+ project_root, ".prizmkit", "state", "bugfix", "bugs", args.bug_id,
221
221
  "sessions", args.session_id, "session-status.json"
222
222
  )
223
223
 
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
- """Generate a session-specific refactor bootstrap prompt from template and refactor-list.json.
2
+ """Generate a session-specific refactor bootstrap prompt from template and .prizmkit/plans/refactor-list.json.
3
3
 
4
- Reads the refactor-bootstrap-prompt.md template and a refactor-list.json, resolves all
4
+ Reads the refactor-bootstrap-prompt.md template and a .prizmkit/plans/refactor-list.json, resolves all
5
5
  {{PLACEHOLDER}} variables, handles conditional blocks, and writes the rendered
6
6
  prompt to the specified output path.
7
7
 
@@ -30,16 +30,16 @@ def parse_args():
30
30
  parser = argparse.ArgumentParser(
31
31
  description=(
32
32
  "Generate a session-specific refactor bootstrap prompt from a template "
33
- "and refactor-list.json."
33
+ "and .prizmkit/plans/refactor-list.json."
34
34
  )
35
35
  )
36
- parser.add_argument("--refactor-list", required=True, help="Path to refactor-list.json")
36
+ parser.add_argument("--refactor-list", required=True, help="Path to .prizmkit/plans/refactor-list.json")
37
37
  parser.add_argument("--refactor-id", required=True, help="Refactor ID to generate prompt for (e.g. R-001)")
38
38
  parser.add_argument("--session-id", required=True, help="Session ID for this pipeline session")
39
39
  parser.add_argument("--run-id", required=True, help="Pipeline run ID")
40
40
  parser.add_argument("--retry-count", required=True, help="Current retry count")
41
41
  parser.add_argument("--resume-phase", required=True, help='Phase to resume from, or "null" for fresh start')
42
- parser.add_argument("--state-dir", default=None, help="State directory path for reading previous session info")
42
+ parser.add_argument("--state-dir", default=None, help="State directory (default: .prizmkit/state/refactor)")
43
43
  parser.add_argument("--output", required=True, help="Output path for the rendered prompt")
44
44
  parser.add_argument("--template", default=None, help="Custom template path. Defaults to {script_dir}/../templates/refactor-bootstrap-prompt.md")
45
45
  return parser.parse_args()
@@ -247,7 +247,7 @@ def build_replacements(args, refactor, global_context, script_dir):
247
247
 
248
248
  # Session status path
249
249
  session_status_path = os.path.join(
250
- project_root, "dev-pipeline", "refactor-state", "refactors", args.refactor_id,
250
+ project_root, ".prizmkit", "state", "refactor", "refactors", args.refactor_id,
251
251
  "sessions", args.session_id, "session-status.json"
252
252
  )
253
253
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python3
2
- """Initialize the bug-fix pipeline state directory from a bug-fix-list.json file.
2
+ """Initialize the bug-fix pipeline state directory from a .prizmkit/plans/bug-fix-list.json file.
3
3
 
4
4
  Validates the bug fix list schema, sorts by priority/severity, and creates
5
5
  the state directory structure with pipeline and per-bug status files.
@@ -40,17 +40,17 @@ VALID_STATUSES = [
40
40
 
41
41
  def parse_args():
42
42
  parser = argparse.ArgumentParser(
43
- description="Initialize bug-fix pipeline state from a bug-fix-list.json file."
43
+ description="Initialize bug-fix pipeline state from a .prizmkit/plans/bug-fix-list.json file."
44
44
  )
45
45
  parser.add_argument(
46
46
  "--bug-list",
47
47
  required=True,
48
- help="Path to the bug-fix-list.json file",
48
+ help="Path to the .prizmkit/plans/bug-fix-list.json file",
49
49
  )
50
50
  parser.add_argument(
51
51
  "--state-dir",
52
52
  required=True,
53
- help="Path to the state directory to create/initialize",
53
+ help="Path to the state directory (default: .prizmkit/state/bugfix)",
54
54
  )
55
55
  return parser.parse_args()
56
56
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python3
2
- """Initialize the dev-pipeline state directory from a feature-list.json file.
2
+ """Initialize the dev-pipeline state directory from a .prizmkit/plans/feature-list.json file.
3
3
 
4
4
  Validates the feature list schema, checks dependency DAG for cycles,
5
5
  and creates the state directory structure with pipeline and feature status files.
@@ -20,6 +20,7 @@ from datetime import datetime, timezone
20
20
  EXPECTED_SCHEMA = "dev-pipeline-feature-list-v1"
21
21
  FEATURE_ID_PATTERN = re.compile(r"^F-\d{3}$")
22
22
  TERMINAL_STATUSES = {"completed", "failed", "skipped"}
23
+ VALID_PRIORITIES = {"critical", "high", "medium", "low"}
23
24
 
24
25
  REQUIRED_FEATURE_FIELDS = [
25
26
  "id",
@@ -34,17 +35,17 @@ REQUIRED_FEATURE_FIELDS = [
34
35
 
35
36
  def parse_args():
36
37
  parser = argparse.ArgumentParser(
37
- description="Initialize dev-pipeline state from a feature-list.json file."
38
+ description="Initialize dev-pipeline state from a .prizmkit/plans/feature-list.json file."
38
39
  )
39
40
  parser.add_argument(
40
41
  "--feature-list",
41
42
  required=True,
42
- help="Path to the feature-list.json file",
43
+ help="Path to the .prizmkit/plans/feature-list.json file",
43
44
  )
44
45
  parser.add_argument(
45
46
  "--state-dir",
46
47
  required=True,
47
- help="Path to the state directory to create/initialize",
48
+ help="Path to the state directory (default: .prizmkit/state/features)",
48
49
  )
49
50
  return parser.parse_args()
50
51
 
@@ -75,11 +76,12 @@ def validate_schema(data):
75
76
  "Invalid $schema: expected '{}', got '{}'".format(EXPECTED_SCHEMA, schema)
76
77
  )
77
78
 
78
- # Check app_name
79
- if "app_name" not in data:
80
- errors.append("Missing required field: app_name")
81
- elif not isinstance(data["app_name"], str) or not data["app_name"].strip():
82
- errors.append("app_name must be a non-empty string")
79
+ # Check project_name (supports legacy app_name for backward compatibility)
80
+ project_name = data.get("project_name", data.get("app_name"))
81
+ if project_name is None:
82
+ errors.append("Missing required field: project_name")
83
+ elif not isinstance(project_name, str) or not project_name.strip():
84
+ errors.append("project_name must be a non-empty string")
83
85
 
84
86
  # Check features array
85
87
  if "features" not in data:
@@ -132,6 +134,18 @@ def validate_features(features):
132
134
  )
133
135
  )
134
136
 
137
+ # Validate priority enum
138
+ priority = feature.get("priority")
139
+ if priority is not None and priority not in VALID_PRIORITIES:
140
+ errors.append(
141
+ "Feature '{}' has invalid priority '{}' "
142
+ "(must be one of: {})".format(
143
+ fid if fid else "index {}".format(i),
144
+ priority,
145
+ ", ".join(sorted(VALID_PRIORITIES)),
146
+ )
147
+ )
148
+
135
149
  # Validate acceptance_criteria is a list
136
150
  ac = feature.get("acceptance_criteria")
137
151
  if ac is not None and not isinstance(ac, list):
@@ -269,7 +283,7 @@ def create_state_directory(state_dir, feature_list_path, features):
269
283
  sessions_dir = os.path.join(feature_dir, "sessions")
270
284
  os.makedirs(sessions_dir, exist_ok=True)
271
285
 
272
- # Respect existing terminal status from feature-list.json
286
+ # Respect existing terminal status from .prizmkit/plans/feature-list.json
273
287
  fl_status = feature.get("status", "pending")
274
288
  init_status = fl_status if fl_status in TERMINAL_STATUSES else "pending"
275
289
 
@@ -302,13 +316,13 @@ def main():
302
316
  print(json.dumps(output, indent=2, ensure_ascii=False))
303
317
  sys.exit(1)
304
318
 
305
- # Warn if feature-list.json is not at project root
319
+ # Warn if .prizmkit/plans/feature-list.json is not at project root
306
320
  feature_list_dir = os.path.dirname(os.path.abspath(args.feature_list))
307
321
  indicators = ['.git', 'package.json', '.prizmkit']
308
322
  is_at_root = any(os.path.exists(os.path.join(feature_list_dir, i)) for i in indicators)
309
323
  if not is_at_root:
310
324
  sys.stderr.write(
311
- "Warning: feature-list.json may not be at project root: {}\n".format(feature_list_dir)
325
+ "Warning: .prizmkit/plans/feature-list.json may not be at project root: {}\n".format(feature_list_dir)
312
326
  )
313
327
 
314
328
  # Validate schema
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python3
2
- """Initialize the refactor pipeline state directory from a refactor-list.json file.
2
+ """Initialize the refactor pipeline state directory from a .prizmkit/plans/refactor-list.json file.
3
3
 
4
4
  Validates the refactor list schema, sorts by priority/complexity, checks for
5
5
  circular dependencies, and creates the state directory structure with pipeline
@@ -47,17 +47,17 @@ VALID_BEHAVIOR_STRATEGIES = ["test-gate", "snapshot", "manual"]
47
47
 
48
48
  def parse_args():
49
49
  parser = argparse.ArgumentParser(
50
- description="Initialize refactor pipeline state from a refactor-list.json file."
50
+ description="Initialize refactor pipeline state from a .prizmkit/plans/refactor-list.json file."
51
51
  )
52
52
  parser.add_argument(
53
53
  "--refactor-list",
54
54
  required=True,
55
- help="Path to the refactor-list.json file",
55
+ help="Path to the .prizmkit/plans/refactor-list.json file",
56
56
  )
57
57
  parser.add_argument(
58
58
  "--state-dir",
59
59
  required=True,
60
- help="Path to the state directory to create/initialize",
60
+ help="Path to the state directory (default: .prizmkit/state/refactor)",
61
61
  )
62
62
  return parser.parse_args()
63
63
 
@@ -57,8 +57,8 @@ def parse_args():
57
57
  parser = argparse.ArgumentParser(
58
58
  description="Core state machine for bug-fix pipeline bug status management."
59
59
  )
60
- parser.add_argument("--bug-list", required=True, help="Path to the bug-fix-list.json file")
61
- parser.add_argument("--state-dir", required=True, help="Path to the bugfix-state/ directory")
60
+ parser.add_argument("--bug-list", required=True, help="Path to the .prizmkit/plans/bug-fix-list.json file")
61
+ parser.add_argument("--state-dir", required=True, help="Path to the state directory (default: .prizmkit/state/bugfix)")
62
62
  parser.add_argument(
63
63
  "--action", required=True,
64
64
  choices=["get_next", "update", "status", "pause", "reset", "clean"],
@@ -128,7 +128,7 @@ def update_bug_in_list(bug_list_path, bug_id, new_status):
128
128
  found = True
129
129
  break
130
130
  if not found:
131
- return "Bug '{}' not found in bug-fix-list.json".format(bug_id)
131
+ return "Bug '{}' not found in .prizmkit/plans/bug-fix-list.json".format(bug_id)
132
132
  return write_json_file(bug_list_path, data)
133
133
 
134
134
 
@@ -183,12 +183,12 @@ def action_get_next(bug_list_data, state_dir):
183
183
  elif bstatus == "pending":
184
184
  pending_bugs.append(bug)
185
185
 
186
- _PRIORITY_ORDER = {"high": 0, "medium": 1, "low": 2}
186
+ _PRIORITY_ORDER = {"critical": 0, "high": 1, "medium": 2, "low": 3}
187
187
 
188
188
  def sort_key(b):
189
189
  severity = b.get("severity", "medium")
190
190
  sev_order = SEVERITY_PRIORITY.get(severity, 2)
191
- priority = _PRIORITY_ORDER.get(b.get("priority", "low"), 2)
191
+ priority = _PRIORITY_ORDER.get(b.get("priority", "low"), 3)
192
192
  return (sev_order, priority)
193
193
 
194
194
  if in_progress_bugs:
@@ -238,7 +238,7 @@ def action_update(args, bug_list_path, state_dir):
238
238
  bs["resume_from_phase"] = None
239
239
  err = update_bug_in_list(bug_list_path, bug_id, "completed")
240
240
  if err:
241
- error_out("Failed to update bug-fix-list.json: {}".format(err))
241
+ error_out("Failed to update .prizmkit/plans/bug-fix-list.json: {}".format(err))
242
242
  return
243
243
  elif session_status == "merge_conflict":
244
244
  # Degraded outcome: keep artifacts for retry (branch preserves work)
@@ -257,7 +257,7 @@ def action_update(args, bug_list_path, state_dir):
257
257
 
258
258
  err = update_bug_in_list(bug_list_path, bug_id, target_status)
259
259
  if err:
260
- error_out("Failed to update bug-fix-list.json: {}".format(err))
260
+ error_out("Failed to update .prizmkit/plans/bug-fix-list.json: {}".format(err))
261
261
  return
262
262
  else:
263
263
  bs["retry_count"] = bs.get("retry_count", 0) + 1
@@ -281,7 +281,7 @@ def action_update(args, bug_list_path, state_dir):
281
281
 
282
282
  err = update_bug_in_list(bug_list_path, bug_id, target_status)
283
283
  if err:
284
- error_out("Failed to update bug-fix-list.json: {}".format(err))
284
+ error_out("Failed to update .prizmkit/plans/bug-fix-list.json: {}".format(err))
285
285
  return
286
286
 
287
287
  if session_status == "success" and session_id:
@@ -544,7 +544,7 @@ def action_reset(args, bug_list_path, state_dir):
544
544
 
545
545
  err = update_bug_in_list(bug_list_path, bug_id, "pending")
546
546
  if err:
547
- error_out("Failed to update bug-fix-list.json: {}".format(err))
547
+ error_out("Failed to update .prizmkit/plans/bug-fix-list.json: {}".format(err))
548
548
  return
549
549
 
550
550
  result = {
@@ -620,7 +620,7 @@ def action_clean(args, bug_list_path, state_dir):
620
620
 
621
621
  err = update_bug_in_list(bug_list_path, bug_id, "pending")
622
622
  if err:
623
- error_out("Failed to update bug-fix-list.json: {}".format(err))
623
+ error_out("Failed to update .prizmkit/plans/bug-fix-list.json: {}".format(err))
624
624
  return
625
625
 
626
626
  result = {
@@ -60,12 +60,12 @@ def parse_args():
60
60
  parser.add_argument(
61
61
  "--feature-list",
62
62
  required=True,
63
- help="Path to the feature-list.json file",
63
+ help="Path to the .prizmkit/plans/feature-list.json file",
64
64
  )
65
65
  parser.add_argument(
66
66
  "--state-dir",
67
67
  required=True,
68
- help="Path to the state/ directory",
68
+ help="Path to the state directory (default: .prizmkit/state/features)",
69
69
  )
70
70
  parser.add_argument(
71
71
  "--action",
@@ -159,7 +159,7 @@ def load_feature_status(state_dir, feature_id, feature_list_status=None):
159
159
  If the file does not exist, return a default pending status.
160
160
 
161
161
  If feature_list_status is a terminal status (completed, failed, skipped),
162
- it overrides the status field from status.json. This makes feature-list.json
162
+ it overrides the status field from status.json. This makes .prizmkit/plans/feature-list.json
163
163
  the single source of truth for terminal statuses, while all other fields
164
164
  (retry_count, sessions, etc.) still come from status.json.
165
165
  """
@@ -195,7 +195,7 @@ def load_feature_status(state_dir, feature_id, feature_list_status=None):
195
195
  "created_at": now,
196
196
  "updated_at": now,
197
197
  }
198
- # feature-list.json wins for terminal statuses
198
+ # .prizmkit/plans/feature-list.json wins for terminal statuses
199
199
  if feature_list_status in TERMINAL_STATUSES:
200
200
  data["status"] = feature_list_status
201
201
  return data
@@ -210,7 +210,7 @@ def save_feature_status(state_dir, feature_id, status_data):
210
210
 
211
211
 
212
212
  def update_feature_in_list(feature_list_path, feature_id, new_status):
213
- """Update a feature's status field in feature-list.json.
213
+ """Update a feature's status field in .prizmkit/plans/feature-list.json.
214
214
 
215
215
  Reads the whole file, modifies the target feature's status, writes back.
216
216
  Returns an error string on failure, None on success.
@@ -226,7 +226,7 @@ def update_feature_in_list(feature_list_path, feature_id, new_status):
226
226
  found = True
227
227
  break
228
228
  if not found:
229
- return "Feature '{}' not found in feature-list.json".format(feature_id)
229
+ return "Feature '{}' not found in .prizmkit/plans/feature-list.json".format(feature_id)
230
230
  return write_json_file(feature_list_path, data)
231
231
 
232
232
 
@@ -336,13 +336,13 @@ def auto_skip_blocked_features(feature_list_path, state_dir, failed_feature_id):
336
336
  by marking those blocked features as auto_skipped, allowing the pipeline to
337
337
  continue processing unblocked features and eventually reach PIPELINE_COMPLETE.
338
338
 
339
- Re-reads feature-list.json from disk to get the latest state (including the
339
+ Re-reads .prizmkit/plans/feature-list.json from disk to get the latest state (including the
340
340
  just-written failed status from update_feature_in_list).
341
341
 
342
- NOTE: This function performs a read-modify-write on feature-list.json without
343
- file locking. The caller (action_update) also writes to feature-list.json
342
+ NOTE: This function performs a read-modify-write on .prizmkit/plans/feature-list.json without
343
+ file locking. The caller (action_update) also writes to .prizmkit/plans/feature-list.json
344
344
  immediately before calling this. Safe for single-pipeline execution, but if
345
- multiple pipeline instances share the same feature-list.json concurrently,
345
+ multiple pipeline instances share the same .prizmkit/plans/feature-list.json concurrently,
346
346
  a race condition may cause lost writes. Add file locking if parallel pipelines
347
347
  are introduced.
348
348
  """
@@ -383,7 +383,7 @@ def auto_skip_blocked_features(feature_list_path, state_dir, failed_feature_id):
383
383
  if not to_skip:
384
384
  return []
385
385
 
386
- # Batch-write to feature-list.json
386
+ # Batch-write to .prizmkit/plans/feature-list.json
387
387
  for f in features:
388
388
  if isinstance(f, dict) and f.get("id") in to_skip:
389
389
  f["status"] = "auto_skipped"
@@ -524,19 +524,19 @@ def action_get_next(feature_list_data, state_dir, feature_filter=None):
524
524
  else:
525
525
  pending_features.append(feature)
526
526
 
527
- # Priority mapping: string enum → sort order (high first)
528
- _PRIORITY_ORDER = {"high": 0, "medium": 1, "low": 2}
527
+ # Priority mapping: string enum → sort order (critical first)
528
+ _PRIORITY_ORDER = {"critical": 0, "high": 1, "medium": 2, "low": 3}
529
529
 
530
530
  # Prefer in_progress features, then pending; sort by priority (high > medium > low)
531
531
  if in_progress_features:
532
532
  candidates = sorted(
533
533
  in_progress_features,
534
- key=lambda f: _PRIORITY_ORDER.get(f.get("priority", "low"), 2)
534
+ key=lambda f: _PRIORITY_ORDER.get(f.get("priority", "low"), 3)
535
535
  )
536
536
  else:
537
537
  candidates = sorted(
538
538
  pending_features,
539
- key=lambda f: _PRIORITY_ORDER.get(f.get("priority", "low"), 2)
539
+ key=lambda f: _PRIORITY_ORDER.get(f.get("priority", "low"), 3)
540
540
  )
541
541
 
542
542
  chosen = candidates[0]
@@ -605,7 +605,7 @@ def action_update(args, feature_list_path, state_dir):
605
605
  fs["resume_from_phase"] = None
606
606
  err = update_feature_in_list(feature_list_path, feature_id, "completed")
607
607
  if err:
608
- error_out("Failed to update feature-list.json: {}".format(err))
608
+ error_out("Failed to update .prizmkit/plans/feature-list.json: {}".format(err))
609
609
  return
610
610
  elif session_status in ("commit_missing", "docs_missing", "merge_conflict"):
611
611
  # Degraded outcome: keep artifacts for retry and expose specific status.
@@ -624,7 +624,7 @@ def action_update(args, feature_list_path, state_dir):
624
624
 
625
625
  err = update_feature_in_list(feature_list_path, feature_id, target_status)
626
626
  if err:
627
- error_out("Failed to update feature-list.json: {}".format(err))
627
+ error_out("Failed to update .prizmkit/plans/feature-list.json: {}".format(err))
628
628
  return
629
629
  else:
630
630
  # crashed / failed / timed_out — preserve all artifacts for debugging.
@@ -646,7 +646,7 @@ def action_update(args, feature_list_path, state_dir):
646
646
 
647
647
  err = update_feature_in_list(feature_list_path, feature_id, target_status)
648
648
  if err:
649
- error_out("Failed to update feature-list.json: {}".format(err))
649
+ error_out("Failed to update .prizmkit/plans/feature-list.json: {}".format(err))
650
650
  return
651
651
 
652
652
  if session_status == "success" and session_id:
@@ -860,12 +860,12 @@ def _estimate_remaining_time(features, state_dir, counts, feature_list_data=None
860
860
  def action_status(feature_list_data, state_dir, feature_filter=None):
861
861
  """Print a formatted overview of all features and their status.
862
862
 
863
- Status is read exclusively from feature-list.json (the single source of
863
+ Status is read exclusively from .prizmkit/plans/feature-list.json (the single source of
864
864
  truth). state_dir is only used for ETA estimation when session history
865
865
  is available.
866
866
  """
867
867
  features = feature_list_data.get("features", [])
868
- app_name = feature_list_data.get("app_name", "Unknown")
868
+ app_name = feature_list_data.get("project_name", feature_list_data.get("app_name", "Unknown"))
869
869
 
870
870
  # Apply feature filter
871
871
  if feature_filter is not None:
@@ -887,7 +887,7 @@ def action_status(feature_list_data, state_dir, feature_filter=None):
887
887
  }
888
888
  feature_lines = []
889
889
 
890
- # Build status map from feature-list.json only
890
+ # Build status map from .prizmkit/plans/feature-list.json only
891
891
  status_map = {}
892
892
  for feature in features:
893
893
  if not isinstance(feature, dict):
@@ -1018,7 +1018,7 @@ def action_status(feature_list_data, state_dir, feature_filter=None):
1018
1018
  print("╔" + "═" * BOX_WIDTH + "╗")
1019
1019
  print("║" + pad_right(COLOR_BOLD + " Dev-Pipeline Status" + COLOR_RESET, inner) + " ║")
1020
1020
  print("╠" + "═" * BOX_WIDTH + "╣")
1021
- print("║" + pad_right(" App: {}".format(app_name), inner) + " ║")
1021
+ print("║" + pad_right(" Project: {}".format(app_name), inner) + " ║")
1022
1022
  print("║" + pad_right(" {}".format(summary_line), inner) + " ║")
1023
1023
  print("║" + pad_right(" {}".format(summary_line2), inner) + " ║")
1024
1024
  print("║" + pad_right(" {}".format(summary_line3), inner) + " ║")
@@ -1038,7 +1038,7 @@ def action_status(feature_list_data, state_dir, feature_filter=None):
1038
1038
  def action_start(args, feature_list_path, state_dir):
1039
1039
  """Mark a feature as in_progress at session start.
1040
1040
 
1041
- This keeps feature-list.json/state status in sync during execution,
1041
+ This keeps .prizmkit/plans/feature-list.json/state status in sync during execution,
1042
1042
  instead of only updating after session end.
1043
1043
  """
1044
1044
  feature_id = args.feature_id
@@ -1059,7 +1059,7 @@ def action_start(args, feature_list_path, state_dir):
1059
1059
 
1060
1060
  err = update_feature_in_list(feature_list_path, feature_id, "in_progress")
1061
1061
  if err:
1062
- error_out("Failed to update feature-list.json: {}".format(err))
1062
+ error_out("Failed to update .prizmkit/plans/feature-list.json: {}".format(err))
1063
1063
  return
1064
1064
 
1065
1065
  result = {
@@ -1080,7 +1080,7 @@ def action_reset(args, feature_list_path, state_dir):
1080
1080
  """Reset a feature to pending state.
1081
1081
 
1082
1082
  Resets status.json (status -> pending, retry_count -> 0, clear sessions,
1083
- clear resume_from_phase) and updates feature-list.json status to pending.
1083
+ clear resume_from_phase) and updates .prizmkit/plans/feature-list.json status to pending.
1084
1084
  Does NOT delete any files on disk.
1085
1085
  """
1086
1086
  feature_id = args.feature_id
@@ -1107,10 +1107,10 @@ def action_reset(args, feature_list_path, state_dir):
1107
1107
  error_out("Failed to save feature status: {}".format(err))
1108
1108
  return
1109
1109
 
1110
- # Update feature-list.json
1110
+ # Update .prizmkit/plans/feature-list.json
1111
1111
  err = update_feature_in_list(feature_list_path, feature_id, "pending")
1112
1112
  if err:
1113
- error_out("Failed to update feature-list.json: {}".format(err))
1113
+ error_out("Failed to update .prizmkit/plans/feature-list.json: {}".format(err))
1114
1114
  return
1115
1115
 
1116
1116
  result = {
@@ -1202,7 +1202,7 @@ def action_clean(args, feature_list_path, state_dir):
1202
1202
 
1203
1203
  err = update_feature_in_list(feature_list_path, feature_id, "pending")
1204
1204
  if err:
1205
- error_out("Failed to update feature-list.json: {}".format(err))
1205
+ error_out("Failed to update .prizmkit/plans/feature-list.json: {}".format(err))
1206
1206
  return
1207
1207
 
1208
1208
  result = {
@@ -1248,7 +1248,7 @@ def action_unskip(args, feature_list_path, state_dir):
1248
1248
  target = f
1249
1249
  break
1250
1250
  if not target:
1251
- error_out("Feature '{}' not found in feature-list.json".format(feature_id))
1251
+ error_out("Feature '{}' not found in .prizmkit/plans/feature-list.json".format(feature_id))
1252
1252
  return
1253
1253
  if target.get("status") not in ("failed", "skipped", "auto_skipped"):
1254
1254
  error_out(
@@ -1328,7 +1328,7 @@ def action_unskip(args, feature_list_path, state_dir):
1328
1328
  error_out("No features to unskip")
1329
1329
  return
1330
1330
 
1331
- # Reset all collected features in feature-list.json
1331
+ # Reset all collected features in .prizmkit/plans/feature-list.json
1332
1332
  reset_details = []
1333
1333
  for f in features:
1334
1334
  if isinstance(f, dict) and f.get("id") in to_reset:
@@ -1342,7 +1342,7 @@ def action_unskip(args, feature_list_path, state_dir):
1342
1342
 
1343
1343
  err = write_json_file(feature_list_path, data)
1344
1344
  if err:
1345
- error_out("Failed to write feature-list.json: {}".format(err))
1345
+ error_out("Failed to write .prizmkit/plans/feature-list.json: {}".format(err))
1346
1346
  return
1347
1347
 
1348
1348
  # Reset status.json for each feature
@@ -68,8 +68,8 @@ def parse_args():
68
68
  parser = argparse.ArgumentParser(
69
69
  description="Core state machine for refactor pipeline status management."
70
70
  )
71
- parser.add_argument("--refactor-list", required=True, help="Path to the refactor-list.json file")
72
- parser.add_argument("--state-dir", required=True, help="Path to the refactor-state/ directory")
71
+ parser.add_argument("--refactor-list", required=True, help="Path to the .prizmkit/plans/refactor-list.json file")
72
+ parser.add_argument("--state-dir", required=True, help="Path to the state directory (default: .prizmkit/state/refactor)")
73
73
  parser.add_argument(
74
74
  "--action", required=True,
75
75
  choices=["get_next", "update", "status", "pause", "reset", "clean"],
@@ -133,7 +133,7 @@ def update_refactor_in_list(refactor_list_path, refactor_id, new_status):
133
133
  found = True
134
134
  break
135
135
  if not found:
136
- return "Refactor '{}' not found in refactor-list.json".format(refactor_id)
136
+ return "Refactor '{}' not found in .prizmkit/plans/refactor-list.json".format(refactor_id)
137
137
  return write_json_file(refactor_list_path, data)
138
138
 
139
139
 
@@ -270,7 +270,7 @@ def action_update(args, refactor_list_path, state_dir):
270
270
  rs["resume_from_phase"] = None
271
271
  err = update_refactor_in_list(refactor_list_path, refactor_id, "completed")
272
272
  if err:
273
- error_out("Failed to update refactor-list.json: {}".format(err))
273
+ error_out("Failed to update .prizmkit/plans/refactor-list.json: {}".format(err))
274
274
  return
275
275
  elif session_status == "merge_conflict":
276
276
  rs["retry_count"] = rs.get("retry_count", 0) + 1
@@ -288,7 +288,7 @@ def action_update(args, refactor_list_path, state_dir):
288
288
 
289
289
  err = update_refactor_in_list(refactor_list_path, refactor_id, target_status)
290
290
  if err:
291
- error_out("Failed to update refactor-list.json: {}".format(err))
291
+ error_out("Failed to update .prizmkit/plans/refactor-list.json: {}".format(err))
292
292
  return
293
293
  else:
294
294
  rs["retry_count"] = rs.get("retry_count", 0) + 1
@@ -312,7 +312,7 @@ def action_update(args, refactor_list_path, state_dir):
312
312
 
313
313
  err = update_refactor_in_list(refactor_list_path, refactor_id, target_status)
314
314
  if err:
315
- error_out("Failed to update refactor-list.json: {}".format(err))
315
+ error_out("Failed to update .prizmkit/plans/refactor-list.json: {}".format(err))
316
316
  return
317
317
 
318
318
  if session_status == "success" and session_id:
@@ -572,7 +572,7 @@ def action_reset(args, refactor_list_path, state_dir):
572
572
 
573
573
  err = update_refactor_in_list(refactor_list_path, refactor_id, "pending")
574
574
  if err:
575
- error_out("Failed to update refactor-list.json: {}".format(err))
575
+ error_out("Failed to update .prizmkit/plans/refactor-list.json: {}".format(err))
576
576
  return
577
577
 
578
578
  result = {
@@ -644,7 +644,7 @@ def action_clean(args, refactor_list_path, state_dir):
644
644
 
645
645
  err = update_refactor_in_list(refactor_list_path, refactor_id, "pending")
646
646
  if err:
647
- error_out("Failed to update refactor-list.json: {}".format(err))
647
+ error_out("Failed to update .prizmkit/plans/refactor-list.json: {}".format(err))
648
648
  return
649
649
 
650
650
  result = {