prizmkit 1.1.154 → 1.1.156

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 (164) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/adapters/codex/skill-adapter.js +1 -1
  3. package/bundled/adapters/pi/skill-adapter.js +2 -1
  4. package/bundled/dev-pipeline/.env.example +2 -6
  5. package/bundled/dev-pipeline/README.md +21 -27
  6. package/bundled/dev-pipeline/prizmkit_runtime/checkpoint_state.py +341 -15
  7. package/bundled/dev-pipeline/prizmkit_runtime/cli.py +0 -3
  8. package/bundled/dev-pipeline/prizmkit_runtime/daemon.py +1 -15
  9. package/bundled/dev-pipeline/prizmkit_runtime/gitops.py +48 -14
  10. package/bundled/dev-pipeline/prizmkit_runtime/runner_classification.py +50 -2
  11. package/bundled/dev-pipeline/prizmkit_runtime/runner_models.py +0 -9
  12. package/bundled/dev-pipeline/prizmkit_runtime/runner_prompts.py +3 -3
  13. package/bundled/dev-pipeline/prizmkit_runtime/runners.py +120 -22
  14. package/bundled/dev-pipeline/prizmkit_runtime/runtime_commit.py +482 -0
  15. package/bundled/dev-pipeline/prizmkit_runtime/test_result.py +64 -11
  16. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +145 -367
  17. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +91 -62
  18. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +105 -69
  19. package/bundled/dev-pipeline/scripts/prompt_framework.py +36 -41
  20. package/bundled/dev-pipeline/scripts/update-bug-status.py +1 -4
  21. package/bundled/dev-pipeline/scripts/update-checkpoint.py +61 -13
  22. package/bundled/dev-pipeline/scripts/update-feature-status.py +1 -4
  23. package/bundled/dev-pipeline/scripts/update-refactor-status.py +1 -4
  24. package/bundled/dev-pipeline/templates/bootstrap-prompt.md +22 -27
  25. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +71 -104
  26. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +59 -111
  27. package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +37 -72
  28. package/bundled/dev-pipeline/templates/sections/artifact-manifest.md +39 -0
  29. package/bundled/dev-pipeline/templates/sections/bugfix-critical-paths.md +3 -1
  30. package/bundled/dev-pipeline/templates/sections/bugfix-phase-commit-report.md +8 -25
  31. package/bundled/dev-pipeline/templates/sections/bugfix-phase-diagnose-plan.md +3 -3
  32. package/bundled/dev-pipeline/templates/sections/bugfix-phase-implement.md +2 -2
  33. package/bundled/dev-pipeline/templates/sections/bugfix-phase-review.md +3 -3
  34. package/bundled/dev-pipeline/templates/sections/bugfix-phase-test.md +2 -2
  35. package/bundled/dev-pipeline/templates/sections/bugfix-reminders.md +4 -4
  36. package/bundled/dev-pipeline/templates/sections/bugfix-session-context.md +0 -1
  37. package/bundled/dev-pipeline/templates/sections/checkpoint-system.md +7 -4
  38. package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +14 -27
  39. package/bundled/dev-pipeline/templates/sections/feature-completion-summary.md +20 -0
  40. package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +8 -71
  41. package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +7 -7
  42. package/bundled/dev-pipeline/templates/sections/phase-prizmkit-test.md +3 -3
  43. package/bundled/dev-pipeline/templates/sections/phase-review-full.md +4 -4
  44. package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +5 -17
  45. package/bundled/dev-pipeline/templates/sections/refactor-critical-paths.md +3 -1
  46. package/bundled/dev-pipeline/templates/sections/refactor-phase-commit-report.md +10 -23
  47. package/bundled/dev-pipeline/templates/sections/refactor-phase-implement.md +2 -2
  48. package/bundled/dev-pipeline/templates/sections/refactor-phase-plan.md +2 -2
  49. package/bundled/dev-pipeline/templates/sections/refactor-phase-review.md +3 -3
  50. package/bundled/dev-pipeline/templates/sections/refactor-phase-test.md +2 -2
  51. package/bundled/dev-pipeline/templates/sections/refactor-reminders.md +7 -7
  52. package/bundled/dev-pipeline/templates/sections/refactor-session-context.md +0 -1
  53. package/bundled/dev-pipeline/templates/sections/retrospective.md +12 -0
  54. package/bundled/dev-pipeline/templates/sections/runtime-commit-handoff.md +35 -0
  55. package/bundled/dev-pipeline/templates/session-status-schema.json +45 -62
  56. package/bundled/dev-pipeline/tests/test_checkpoint_state.py +469 -18
  57. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +262 -175
  58. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +62 -23
  59. package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +76 -28
  60. package/bundled/dev-pipeline/tests/test_python_runner_parity.py +168 -18
  61. package/bundled/dev-pipeline/tests/test_recovery_workflow.py +111 -0
  62. package/bundled/dev-pipeline/tests/test_reset_preserve.py +0 -2
  63. package/bundled/dev-pipeline/tests/test_runtime_commit.py +608 -0
  64. package/bundled/dev-pipeline/tests/test_unified_cli.py +167 -25
  65. package/bundled/skills/_metadata.json +9 -9
  66. package/bundled/skills/app-planner/SKILL.md +3 -3
  67. package/bundled/skills/app-planner/references/generated-plan-review.md +2 -1
  68. package/bundled/skills/app-planner/references/rules/backend/derivation-rules.md +56 -64
  69. package/bundled/skills/app-planner/references/rules/backend/fixed-rules.md +85 -240
  70. package/bundled/skills/app-planner/references/rules/backend/question-bank.md +25 -25
  71. package/bundled/skills/app-planner/references/rules/backend/question-manifest.json +16 -7
  72. package/bundled/skills/app-planner/references/rules/backend/template.md +74 -92
  73. package/bundled/skills/app-planner/references/rules/database/derivation-rules.md +93 -93
  74. package/bundled/skills/app-planner/references/rules/database/fixed-rules.md +66 -173
  75. package/bundled/skills/app-planner/references/rules/database/question-bank.md +31 -26
  76. package/bundled/skills/app-planner/references/rules/database/question-manifest.json +13 -4
  77. package/bundled/skills/app-planner/references/rules/database/template.md +76 -98
  78. package/bundled/skills/app-planner/references/rules/frontend/derivation-rules.md +68 -95
  79. package/bundled/skills/app-planner/references/rules/frontend/fixed-rules.md +93 -166
  80. package/bundled/skills/app-planner/references/rules/frontend/question-bank.md +46 -36
  81. package/bundled/skills/app-planner/references/rules/frontend/question-manifest.json +11 -2
  82. package/bundled/skills/app-planner/references/rules/frontend/template.md +79 -257
  83. package/bundled/skills/app-planner/references/rules/mobile/derivation-rules.md +91 -99
  84. package/bundled/skills/app-planner/references/rules/mobile/fixed-rules.md +73 -246
  85. package/bundled/skills/app-planner/references/rules/mobile/question-bank.md +17 -17
  86. package/bundled/skills/app-planner/references/rules/mobile/question-manifest.json +17 -2
  87. package/bundled/skills/app-planner/references/rules/mobile/template.md +73 -85
  88. package/bundled/skills/app-planner/references/rules-configuration.md +133 -65
  89. package/bundled/skills/app-planner/scripts/validate-rules-configuration.py +291 -0
  90. package/bundled/skills/prizmkit/SKILL.md +17 -18
  91. package/bundled/skills/prizmkit/references/workflow-state-protocol.md +22 -18
  92. package/bundled/skills/prizmkit-code-review/SKILL.md +22 -58
  93. package/bundled/skills/prizmkit-code-review/references/independent-code-review.md +6 -6
  94. package/bundled/skills/prizmkit-code-review/references/review-report-template.md +2 -2
  95. package/bundled/skills/prizmkit-committer/SKILL.md +82 -132
  96. package/bundled/skills/prizmkit-deploy/SKILL.md +27 -11
  97. package/bundled/skills/prizmkit-deploy/assets/deploy-document-template.md +89 -0
  98. package/bundled/skills/prizmkit-deploy/references/ci-cd-workflows.md +44 -14
  99. package/bundled/skills/prizmkit-deploy/references/cloud-platform-deploy.md +19 -3
  100. package/bundled/skills/prizmkit-deploy/references/database-setup.md +22 -12
  101. package/bundled/skills/prizmkit-deploy/references/deploy-config-schema.md +3 -1
  102. package/bundled/skills/prizmkit-deploy/references/deploy-history-schema.md +22 -6
  103. package/bundled/skills/prizmkit-deploy/references/deploy-metadata-schema.json +49 -0
  104. package/bundled/skills/prizmkit-deploy/references/live-validation-notes.md +1 -1
  105. package/bundled/skills/prizmkit-deploy/references/pending-input-schema.json +164 -0
  106. package/bundled/skills/prizmkit-deploy/references/ssh-adapter-flow.md +9 -8
  107. package/bundled/skills/prizmkit-deploy/references/ssh-execution-flow.md +6 -6
  108. package/bundled/skills/prizmkit-implement/SKILL.md +30 -66
  109. package/bundled/skills/prizmkit-implement/references/implementation-subagent-procedure.md +4 -4
  110. package/bundled/skills/prizmkit-init/SKILL.md +4 -0
  111. package/bundled/skills/prizmkit-plan/SKILL.md +21 -64
  112. package/bundled/skills/prizmkit-plan/references/artifact-identity.md +38 -0
  113. package/bundled/skills/prizmkit-plan/references/independent-plan-review.md +4 -4
  114. package/bundled/skills/prizmkit-plan/references/review-plan-spec-loop.md +5 -5
  115. package/bundled/skills/prizmkit-prizm-docs/SKILL.md +75 -11
  116. package/bundled/skills/prizmkit-prizm-docs/assets/prizm-docs-format.md +191 -56
  117. package/bundled/skills/prizmkit-prizm-docs/references/op-init.md +18 -18
  118. package/bundled/skills/prizmkit-prizm-docs/references/op-rebuild.md +14 -8
  119. package/bundled/skills/prizmkit-prizm-docs/references/op-status.md +12 -5
  120. package/bundled/skills/prizmkit-prizm-docs/references/op-update.md +23 -12
  121. package/bundled/skills/prizmkit-prizm-docs/references/op-validate.md +13 -9
  122. package/bundled/skills/prizmkit-retrospective/SKILL.md +94 -97
  123. package/bundled/skills/prizmkit-retrospective/references/knowledge-injection-steps.md +79 -37
  124. package/bundled/skills/prizmkit-retrospective/references/retrospective-result-schema.json +138 -0
  125. package/bundled/skills/prizmkit-retrospective/references/structural-sync-steps.md +111 -54
  126. package/bundled/skills/prizmkit-test/SKILL.md +64 -51
  127. package/bundled/skills/prizmkit-test/references/boundary-contract-and-test-double-guidance.md +206 -0
  128. package/bundled/skills/prizmkit-test/references/independent-test-review.md +17 -9
  129. package/bundled/skills/prizmkit-test/references/test-coverage-model.md +45 -21
  130. package/bundled/skills/prizmkit-test/references/test-report-template.md +20 -13
  131. package/bundled/skills/prizmkit-workflow/SKILL.md +35 -37
  132. package/bundled/skills/prizmkit-workflow/references/artifact-identity.md +34 -0
  133. package/bundled/skills/prizmkit-workflow/references/workflow-state-protocol.md +22 -18
  134. package/bundled/skills/recovery-workflow/SKILL.md +2 -1
  135. package/bundled/skills/recovery-workflow/references/detection.md +4 -3
  136. package/bundled/skills/recovery-workflow/scripts/detect-recovery-state.py +15 -5
  137. package/bundled/templates/hooks/validate-prizm-docs.py +124 -12
  138. package/package.json +1 -1
  139. package/src/scaffold.js +33 -22
  140. package/bundled/dev-pipeline/templates/sections/bugfix-artifacts.md +0 -16
  141. package/bundled/dev-pipeline/templates/sections/bugfix-session-status.md +0 -31
  142. package/bundled/dev-pipeline/templates/sections/critical-paths-agent.md +0 -7
  143. package/bundled/dev-pipeline/templates/sections/critical-paths-lite.md +0 -7
  144. package/bundled/dev-pipeline/templates/sections/directory-convention-agent.md +0 -9
  145. package/bundled/dev-pipeline/templates/sections/directory-convention-lite.md +0 -6
  146. package/bundled/dev-pipeline/templates/sections/headless-commit-authorization.md +0 -15
  147. package/bundled/dev-pipeline/templates/sections/phase-commit.md +0 -61
  148. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-agent-suffix.md +0 -24
  149. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-lite-suffix.md +0 -12
  150. package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +0 -44
  151. package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +0 -25
  152. package/bundled/dev-pipeline/templates/sections/phase-plan-agent.md +0 -20
  153. package/bundled/dev-pipeline/templates/sections/phase-plan-lite.md +0 -20
  154. package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +0 -20
  155. package/bundled/dev-pipeline/templates/sections/refactor-artifacts.md +0 -17
  156. package/bundled/dev-pipeline/templates/sections/refactor-session-status.md +0 -28
  157. package/bundled/dev-pipeline/templates/sections/test-failure-recovery-agent.md +0 -52
  158. package/bundled/dev-pipeline/templates/sections/test-failure-recovery-lite.md +0 -52
  159. package/bundled/skills/prizmkit-code-review/references/workflow-state-protocol.md +0 -174
  160. package/bundled/skills/prizmkit-committer/references/workflow-state-protocol.md +0 -174
  161. package/bundled/skills/prizmkit-implement/references/workflow-state-protocol.md +0 -174
  162. package/bundled/skills/prizmkit-plan/references/workflow-state-protocol.md +0 -174
  163. package/bundled/skills/prizmkit-retrospective/references/workflow-state-protocol.md +0 -174
  164. package/bundled/skills/prizmkit-test/references/external-contract-mock-guidance.md +0 -119
@@ -182,7 +182,6 @@ class TestExplicitProjectRoot:
182
182
  state_dir=str(main_checkout / ".prizmkit" / "state" / "bugfix"),
183
183
  output=str(main_checkout / ".prizmkit" / "state" / "bugfix" / "B-001" / "sessions" / "session-1" / "bootstrap-prompt.md"),
184
184
  template=None,
185
- mode=None,
186
185
  project_root=str(execution_root),
187
186
  )
188
187
  bug = {"id": "B-001", "title": "Worktree Bug", "description": "d"}
@@ -195,11 +194,7 @@ class TestExplicitProjectRoot:
195
194
  )
196
195
 
197
196
  assert replacements["{{PROJECT_ROOT}}"] == str(execution_root.resolve())
198
- assert replacements["{{SESSION_STATUS_PATH}}"] == str(
199
- main_checkout / ".prizmkit" / "state" / "bugfix" / "B-001" /
200
- "sessions" / "session-1" / "session-status.json"
201
- )
202
- assert not replacements["{{SESSION_STATUS_PATH}}"].startswith(str(execution_root.resolve()))
197
+ assert "{{SESSION_STATUS_PATH}}" not in replacements
203
198
  assert "{{" + "DEV_" + "SUBAGENT_PATH" + "}}" not in replacements
204
199
  assert replacements["{{SESSION_LOG_PATH}}"].endswith(
205
200
  ".prizmkit/state/bugfix/B-001/sessions/session-1/logs/session.log"
@@ -321,7 +316,8 @@ def test_template_source_is_clean_for_headless_prompt_contract():
321
316
  assert "FAST_PATH=true" not in content
322
317
  assert "prizmkit-workflow" not in content
323
318
  assert "/prizmkit-test scope=this-change artifact_dir=.prizmkit/bugfix/{{BUG_ID}}/" in content
324
- assert "local_commit_authorized=true" in content
319
+ assert "operation=prepare-runtime-commit" in content
320
+ assert "local_commit_authorized" not in content
325
321
  assert "push_authorized" not in content
326
322
 
327
323
 
@@ -494,11 +490,21 @@ class TestBugfixCheckpointGeneration:
494
490
  "prizmkit-implement",
495
491
  "prizmkit-code-review",
496
492
  "prizmkit-test",
493
+ "bug-report",
497
494
  "prizmkit-retrospective",
498
495
  "prizmkit-committer",
499
- "bug-report",
500
496
  ]
497
+ plan_step = checkpoint["steps"][1]
498
+ review_step = checkpoint["steps"][3]
501
499
  test_step = checkpoint["steps"][4]
500
+ assert plan_step["required_artifacts"] == [
501
+ ".prizmkit/bugfix/B-001/context-snapshot.md",
502
+ ".prizmkit/bugfix/B-001/spec.md",
503
+ ".prizmkit/bugfix/B-001/plan.md",
504
+ ]
505
+ assert review_step["required_artifacts"] == [
506
+ ".prizmkit/bugfix/B-001/review-report.md"
507
+ ]
502
508
  assert test_step["depends_on"] == "S04"
503
509
  assert test_step["required_artifacts"] == [
504
510
  ".prizmkit/bugfix/B-001/test-report.md",
@@ -506,23 +512,31 @@ class TestBugfixCheckpointGeneration:
506
512
  ]
507
513
  assert checkpoint["steps"][5]["depends_on"] == "S05"
508
514
 
509
- def test_bugfix_result_routing_stops_test_non_pass(self):
510
- review = route_bugfix_repair("REVIEW_NEEDS_FIXES", repair_round=0)
511
- needs_fixes = route_bugfix_repair("TEST_NEEDS_FIXES", repair_round=1)
515
+ def test_bugfix_result_routing_owns_bounded_test_repair(self):
516
+ review = route_bugfix_repair(
517
+ "REVIEW_NEEDS_FIXES", repair_scope="production", repair_round=0,
518
+ )
519
+ needs_fixes = route_bugfix_repair(
520
+ "TEST_NEEDS_FIXES", repair_scope="production", repair_round=1,
521
+ )
512
522
  blocked = route_bugfix_repair("TEST_BLOCKED", repair_round=1)
513
523
 
514
524
  assert review["route"] == [
515
525
  "prizmkit-implement", "prizmkit-code-review", "prizmkit-test",
516
526
  ]
517
527
  assert review["repair_round"] == 1
518
- assert needs_fixes["blocked"] is True
519
- assert needs_fixes["route"] == []
520
- assert needs_fixes["blocked_reason"] == "test_needs_fixes"
528
+ assert needs_fixes["blocked"] is False
529
+ assert needs_fixes["route"] == [
530
+ "prizmkit-implement", "prizmkit-code-review", "prizmkit-test",
531
+ ]
532
+ assert needs_fixes["repair_round"] == 2
521
533
  assert blocked["blocked"] is True
522
534
  assert blocked["resumable"] is False
523
535
  assert blocked["next_stage"] is None
524
536
  assert blocked["terminal_status"] == "WORKFLOW_BLOCKED"
525
537
  assert blocked["blocked_reason"] == "test_blocked"
538
+ unsafe = route_bugfix_repair("REVIEW_NEEDS_FIXES", repair_round=0)
539
+ assert unsafe["blocked_reason"] == "unsafe_repair_scope"
526
540
 
527
541
  def test_bugfix_checkpoint_metadata_has_no_evidence_handoff(self):
528
542
  metadata = bugfix_checkpoint_metadata(
@@ -542,28 +556,51 @@ class TestBugfixCheckpointGeneration:
542
556
 
543
557
  def test_manual_bugfix_uses_automatic_verification_and_keeps_commit_gate(self):
544
558
  sections = assemble_bugfix_sections(
545
- "standard", "dev-pipeline/templates/sections", False, True,
559
+ "dev-pipeline/templates/sections", False, True,
546
560
  )
547
561
  names = [name for name, _ in sections]
548
562
 
549
563
  assert "bugfix-manual-gate" in names
550
- assert "headless-commit-authorization" in names
564
+ assert names.index("bugfix-manual-gate") < names.index("bugfix-phase-test")
565
+ assert "runtime-commit-handoff" in names
551
566
  assert "bugfix-phase-commit-report" in names
567
+ checkpoint = generate_bugfix_checkpoint(
568
+ "B-001", "session", sections=sections,
569
+ )
570
+ skills = [step["skill"] for step in checkpoint["steps"]]
571
+ assert skills.index("prizmkit-code-review") < skills.index(
572
+ "manual-verification"
573
+ ) < skills.index("prizmkit-test")
574
+ compatibility = generate_bugfix_checkpoint(
575
+ "B-001",
576
+ "session",
577
+ browser_enabled=True,
578
+ manual_gate=True,
579
+ )
580
+ compatibility_skills = [step["skill"] for step in compatibility["steps"]]
581
+ assert compatibility_skills.index("prizmkit-code-review") < compatibility_skills.index(
582
+ "browser-verification"
583
+ ) < compatibility_skills.index("manual-verification") < compatibility_skills.index(
584
+ "prizmkit-test"
585
+ )
552
586
 
553
587
  def test_rendered_bugfix_prompt_is_atomic_headless_and_local_commit_only(self, tmp_path):
554
588
  prompt = _render_bugfix_prompt(tmp_path)
555
589
 
556
590
  assert prompt.index("/prizmkit-code-review") < prompt.index(
557
591
  "/prizmkit-test scope=this-change artifact_dir=.prizmkit/bugfix/B-001/"
558
- ) < prompt.index("### Headless Commit Authorization")
592
+ ) < prompt.index("### Bug Fix Report") < prompt.index("### Retrospective") < prompt.index("### Runtime Commit Handoff")
559
593
  assert "FAST_PATH=true" not in prompt
560
594
  assert "prizmkit-workflow" not in prompt
561
- assert '"local_commit_authorized": true' in prompt
562
- assert "push_authorized" not in prompt
563
- assert "Do not ask questions, wait for user input" in prompt
564
- assert "Remote publication is controlled by the runtime" in prompt
595
+ assert "local_commit_authorized" not in prompt
596
+ assert "operation=prepare-runtime-commit" in prompt
597
+ assert "NEVER ask for user confirmation" in prompt
598
+ assert "The Python runtime, not the AI session, executes" in prompt
599
+ assert "all `.prizmkit/**` paths are PrizmKit-internal" in prompt
600
+ assert "Unknown Git-visible paths are not silently ignored" in prompt
565
601
  assert "push_authorized\": true" not in prompt
566
602
  assert ".prizmkit/bugfix/B-001/" in prompt
603
+ assert "write the session status" not in prompt.lower()
567
604
 
568
605
  def test_setup_section_skips_and_finalization_group_expands(self):
569
606
  checkpoint = generate_bugfix_checkpoint(
@@ -572,15 +609,17 @@ class TestBugfixCheckpointGeneration:
572
609
  sections=[
573
610
  ("bugfix-phase-init", "setup"),
574
611
  ("bugfix-phase-implement", "implement"),
575
- ("bugfix-phase-commit-report", "finalize"),
612
+ ("bugfix-phase-commit-report", "report"),
613
+ ("retrospective", "retrospective"),
614
+ ("runtime-commit-handoff", "commit"),
576
615
  ],
577
616
  )
578
617
 
579
618
  assert [step["skill"] for step in checkpoint["steps"]] == [
580
619
  "prizmkit-init",
581
620
  "prizmkit-implement",
621
+ "bug-report",
582
622
  "prizmkit-retrospective",
583
623
  "prizmkit-committer",
584
- "bug-report",
585
624
  ]
586
625
  assert checkpoint["steps"][2]["depends_on"] == "S02"
@@ -8,6 +8,8 @@ import os
8
8
  from continuation import append_continuation_handoff
9
9
  from generate_refactor_prompt import (
10
10
  build_replacements,
11
+ format_behavior_preservation,
12
+ format_existing_tests,
11
13
  generate_refactor_checkpoint,
12
14
  merge_refactor_checkpoint_state,
13
15
  refactor_checkpoint_metadata,
@@ -52,6 +54,39 @@ class TestRefactorContinuationHandoff:
52
54
  assert (tmp_path / ".prizmkit/refactor/R-007/continuation-summary.md").exists()
53
55
 
54
56
 
57
+ class TestRefactorBehaviorPreservation:
58
+ def test_schema_boolean_existing_tests_renders_without_iteration(self):
59
+ assert format_existing_tests(True) == (
60
+ "- Coverage declared: yes (specific test paths not supplied)"
61
+ )
62
+ assert format_existing_tests(False) == (
63
+ "- Coverage declared: no (specific test paths not supplied)"
64
+ )
65
+ assert "**Existing Tests Cover Scope**: yes" in format_behavior_preservation({
66
+ "strategy": "test-gate",
67
+ "existing_tests": True,
68
+ })
69
+
70
+ def test_historical_test_path_list_remains_supported(self):
71
+ value = ["test/unit.test.js", "test/integration.test.js"]
72
+ rendered = format_existing_tests(value)
73
+ assert "`test/unit.test.js`" in rendered
74
+ assert "`test/integration.test.js`" in rendered
75
+ preservation = format_behavior_preservation({
76
+ "strategy": "test-gate",
77
+ "existing_tests": value,
78
+ })
79
+ assert "**Existing Tests**" in preservation
80
+ assert "`test/unit.test.js`" in preservation
81
+
82
+ def test_invalid_test_shapes_degrade_to_unspecified(self):
83
+ assert format_existing_tests("test/unit.test.js") == "- (none specified)"
84
+ assert "Existing Tests" not in format_behavior_preservation({
85
+ "strategy": "test-gate",
86
+ "existing_tests": {"path": "test/unit.test.js"},
87
+ })
88
+
89
+
55
90
  class TestRefactorCheckpointMerge:
56
91
  def test_preserves_skipped_without_artifacts(self, tmp_path):
57
92
  fresh = generate_refactor_checkpoint("R-008", "R-008-new")
@@ -96,7 +131,6 @@ class TestExplicitProjectRoot:
96
131
  state_dir=str(project / ".prizmkit" / "state" / "refactor"),
97
132
  output=str(project / "out.md"),
98
133
  template=None,
99
- mode=None,
100
134
  )
101
135
  refactor = {"id": "R-001", "title": "Restructure", "description": "d"}
102
136
 
@@ -106,10 +140,7 @@ class TestExplicitProjectRoot:
106
140
 
107
141
  assert replacements["{{PROJECT_ROOT}}"] == str(project.resolve())
108
142
  assert "{{" + "REVIEWER_" + "SUBAGENT_PATH" + "}}" not in replacements
109
- assert replacements["{{SESSION_STATUS_PATH}}"] == str(
110
- project / ".prizmkit" / "state" / "refactor" / "R-001" /
111
- "sessions" / "session-1" / "session-status.json"
112
- )
143
+ assert "{{SESSION_STATUS_PATH}}" not in replacements
113
144
 
114
145
  def test_build_replacements_uses_cli_project_root_for_rendered_paths(self, tmp_path, monkeypatch):
115
146
  monkeypatch.setenv("PRIZMKIT_PLATFORM", "claude")
@@ -127,7 +158,6 @@ class TestExplicitProjectRoot:
127
158
  state_dir=str(main_checkout / ".prizmkit" / "state" / "refactor"),
128
159
  output=str(main_checkout / ".prizmkit" / "state" / "refactor" / "R-001" / "sessions" / "session-1" / "bootstrap-prompt.md"),
129
160
  template=None,
130
- mode=None,
131
161
  project_root=str(execution_root),
132
162
  )
133
163
  refactor = {"id": "R-001", "title": "Worktree Refactor", "description": "d"}
@@ -141,11 +171,7 @@ class TestExplicitProjectRoot:
141
171
  )
142
172
 
143
173
  assert replacements["{{PROJECT_ROOT}}"] == str(execution_root.resolve())
144
- assert replacements["{{SESSION_STATUS_PATH}}"] == str(
145
- main_checkout / ".prizmkit" / "state" / "refactor" / "R-001" /
146
- "sessions" / "session-1" / "session-status.json"
147
- )
148
- assert not replacements["{{SESSION_STATUS_PATH}}"].startswith(str(execution_root.resolve()))
174
+ assert "{{SESSION_STATUS_PATH}}" not in replacements
149
175
  assert "{{" + "DEV_" + "SUBAGENT_PATH" + "}}" not in replacements
150
176
  assert "### Checkpoint Update Helper" in replacements["{{CHECKPOINT_SYSTEM}}"]
151
177
  assert "{{CHECKPOINT_PYTHON_CMD}}" in replacements["{{CHECKPOINT_SYSTEM}}"]
@@ -178,7 +204,6 @@ class TestRefactorPromptMaxLogRemoval:
178
204
  state_dir=None,
179
205
  output="out.md",
180
206
  template=None,
181
- mode=None,
182
207
  )
183
208
  refactor = {"id": "R-001", "title": "Restructure", "description": "d"}
184
209
 
@@ -214,7 +239,8 @@ def test_template_source_is_clean_for_headless_prompt_contract():
214
239
  assert forbidden not in content
215
240
  assert "prizmkit-workflow" not in content
216
241
  assert "/prizmkit-test scope=this-change artifact_dir=.prizmkit/refactor/{{REFACTOR_ID}}/" in content
217
- assert "local_commit_authorized=true" in content
242
+ assert "operation=prepare-runtime-commit" in content
243
+ assert "local_commit_authorized" not in content
218
244
  assert "push_authorized" not in content
219
245
  assert "Behavior-preservation context remains supporting input" in content
220
246
 
@@ -344,10 +370,10 @@ class TestRefactorCheckpointGeneration:
344
370
  "prizmkit-implement",
345
371
  "prizmkit-code-review",
346
372
  "prizmkit-test",
347
- "prizmkit-retrospective",
348
- "prizmkit-committer",
349
373
  "refactor-report",
350
374
  "completion-summary",
375
+ "prizmkit-retrospective",
376
+ "prizmkit-committer",
351
377
  ]
352
378
  assert checkpoint["steps"][4]["depends_on"] == "S04"
353
379
  assert checkpoint["steps"][4]["required_artifacts"] == [
@@ -356,22 +382,30 @@ class TestRefactorCheckpointGeneration:
356
382
  ]
357
383
  assert checkpoint["steps"][5]["depends_on"] == "S05"
358
384
 
359
- def test_refactor_result_routing_stops_test_non_pass(self):
360
- review = route_refactor_repair("REVIEW_NEEDS_FIXES", repair_round=0)
361
- needs_fixes = route_refactor_repair("TEST_NEEDS_FIXES", repair_round=1)
385
+ def test_refactor_result_routing_owns_bounded_test_repair(self):
386
+ review = route_refactor_repair(
387
+ "REVIEW_NEEDS_FIXES", repair_scope="production", repair_round=0,
388
+ )
389
+ needs_fixes = route_refactor_repair(
390
+ "TEST_NEEDS_FIXES", repair_scope="production", repair_round=1,
391
+ )
362
392
  blocked = route_refactor_repair("TEST_BLOCKED", repair_round=1)
363
393
 
364
394
  assert review["route"] == [
365
395
  "prizmkit-implement", "prizmkit-code-review", "prizmkit-test",
366
396
  ]
367
- assert needs_fixes["blocked"] is True
368
- assert needs_fixes["route"] == []
369
- assert needs_fixes["blocked_reason"] == "test_needs_fixes"
397
+ assert needs_fixes["blocked"] is False
398
+ assert needs_fixes["route"] == [
399
+ "prizmkit-implement", "prizmkit-code-review", "prizmkit-test",
400
+ ]
401
+ assert needs_fixes["repair_round"] == 2
370
402
  assert blocked["blocked"] is True
371
403
  assert blocked["route"] == []
372
404
  assert blocked["next_stage"] is None
373
405
  assert blocked["terminal_status"] == "WORKFLOW_BLOCKED"
374
406
  assert blocked["blocked_reason"] == "test_blocked"
407
+ unsafe = route_refactor_repair("TEST_NEEDS_FIXES", repair_round=0)
408
+ assert unsafe["blocked_reason"] == "unsafe_repair_scope"
375
409
 
376
410
  def test_refactor_checkpoint_metadata_has_no_evidence_handoff(self):
377
411
  metadata = refactor_checkpoint_metadata(
@@ -395,14 +429,26 @@ class TestRefactorCheckpointGeneration:
395
429
 
396
430
  assert prompt.index("/prizmkit-code-review") < prompt.index(
397
431
  "/prizmkit-test scope=this-change artifact_dir=.prizmkit/refactor/R-001/"
398
- ) < prompt.index("### Headless Commit Authorization")
432
+ ) < prompt.index("### Refactor Report") < prompt.index("### Retrospective") < prompt.index("### Runtime Commit Handoff")
399
433
  assert "prizmkit-workflow" not in prompt
400
434
  assert "Existing behavior-preservation context is input to testing" in prompt
401
- assert '"local_commit_authorized": true' in prompt
402
- assert "push_authorized" not in prompt
403
- assert "Remote publication is controlled by the runtime" in prompt
435
+ assert "local_commit_authorized" not in prompt
436
+ assert "operation=prepare-runtime-commit" in prompt
437
+ assert "The Python runtime, not the AI session, executes" in prompt
438
+ assert "all `.prizmkit/**` paths are PrizmKit-internal" in prompt
439
+ assert "Unknown Git-visible paths are not silently ignored" in prompt
404
440
  assert "automatic push" not in prompt.lower()
405
441
  assert "push_authorized\": true" not in prompt
442
+ assert "write the session status" not in prompt.lower()
443
+
444
+ def test_compatibility_checkpoint_keeps_configured_browser_before_test(self):
445
+ checkpoint = generate_refactor_checkpoint(
446
+ "R-001", "session", browser_enabled=True,
447
+ )
448
+ skills = [step["skill"] for step in checkpoint["steps"]]
449
+ assert skills.index("prizmkit-code-review") < skills.index(
450
+ "browser-verification"
451
+ ) < skills.index("prizmkit-test")
406
452
 
407
453
 
408
454
  class TestRefactorCheckpointGenerationLegacy:
@@ -413,16 +459,18 @@ class TestRefactorCheckpointGenerationLegacy:
413
459
  sections=[
414
460
  ("refactor-phase-init", "setup"),
415
461
  ("refactor-phase-implement", "implement"),
416
- ("refactor-phase-commit-report", "finalize"),
462
+ ("refactor-phase-commit-report", "report"),
463
+ ("retrospective", "retrospective"),
464
+ ("runtime-commit-handoff", "commit"),
417
465
  ],
418
466
  )
419
467
 
420
468
  assert [step["skill"] for step in checkpoint["steps"]] == [
421
469
  "prizmkit-init",
422
470
  "prizmkit-implement",
423
- "prizmkit-retrospective",
424
- "prizmkit-committer",
425
471
  "refactor-report",
426
472
  "completion-summary",
473
+ "prizmkit-retrospective",
474
+ "prizmkit-committer",
427
475
  ]
428
476
  assert checkpoint["steps"][2]["depends_on"] == "S02"