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
@@ -1,18 +1,14 @@
1
1
  #!/usr/bin/env python3
2
2
  """Generate a session-specific bootstrap prompt from template and feature list.
3
3
 
4
- Supports two modes:
4
+ Supports two rendering paths:
5
5
  1. **Section assembly** (preferred): Loads modular section files from
6
- templates/sections/ and assembles the unified full/tier3-equivalent
7
- feature guidance by default. Conditional logic is handled in Python code,
8
- not regex-based template blocks.
9
- 2. **Legacy template** (fallback): Reads the monolithic bootstrap-tier3.md
10
- template, falling back to bootstrap-prompt.md when tier3 is unavailable,
11
- and resolves {{PLACEHOLDER}} variables and {{IF_xxx}} blocks.
6
+ templates/sections/ and assembles one canonical Feature lifecycle prompt.
7
+ 2. **Explicit custom template**: When `--template` is supplied, resolves its
8
+ placeholders and legacy conditional blocks for compatibility.
12
9
 
13
- The section assembly mode is used when templates/sections/ directory exists
14
- and no explicit --template path is supplied. Otherwise, falls back to legacy
15
- templates for backward compatibility.
10
+ Canonical section generation fails closed when required sections are missing;
11
+ it never falls back to a reduced or stale built-in prompt.
16
12
 
17
13
  Usage:
18
14
  python3 generate-bootstrap-prompt.py \
@@ -33,7 +29,6 @@ from continuation import add_continuation_args, append_continuation_handoff, is_
33
29
  from prompt_framework import (
34
30
  artifact_exists,
35
31
  browser_enabled_from_item,
36
- checkpoint_group,
37
32
  checkpoint_skip,
38
33
  checkpoint_step,
39
34
  completed_test_artifacts_valid,
@@ -103,21 +98,19 @@ def parse_args():
103
98
  default=None,
104
99
  help="AI-visible project root used for rendered prompt paths",
105
100
  )
101
+ parser.add_argument(
102
+ "--no-checkpoint-write",
103
+ action="store_true",
104
+ help="Render and validate a preview without creating or updating checkpoint state",
105
+ )
106
106
  parser.add_argument(
107
107
  "--template",
108
108
  default=None,
109
109
  help=(
110
- "Custom template path. Defaults to section-based full feature "
111
- "prompt assembly, or {script_dir}/../templates/bootstrap-tier3.md "
112
- "when sections are unavailable."
110
+ "Explicit custom template path. Without it, canonical section "
111
+ "assembly is required and missing sections fail closed."
113
112
  ),
114
113
  )
115
- parser.add_argument(
116
- "--mode",
117
- choices=["lite", "standard", "full"],
118
- default=None,
119
- help="Override pipeline mode (default: auto-detect from complexity)",
120
- )
121
114
  parser.add_argument(
122
115
  "--extract-baselines",
123
116
  action="store_true",
@@ -529,33 +522,9 @@ def process_conditional_blocks(content, resume_phase):
529
522
  return content
530
523
 
531
524
 
532
- def process_mode_blocks(content, pipeline_mode, init_done,
533
- browser_interaction=False, browser_tool="auto"):
534
- """Process pipeline mode, init, and browser conditional blocks.
535
-
536
- Keeps the block matching the current mode, removes the others.
537
- Handles {{IF_BROWSER_INTERACTION}} / {{END_IF_BROWSER_INTERACTION}} blocks.
538
- Handles {{IF_BROWSER_TOOL_PLAYWRIGHT}} / {{IF_BROWSER_TOOL_OPENCLI}} /
539
- {{IF_BROWSER_TOOL_AUTO}} blocks (nested inside browser interaction block).
540
- """
541
- # Handle lite/standard/full blocks
542
- modes = ["lite", "standard", "full"]
543
-
544
- for mode in modes:
545
- tag_open = "{{{{IF_MODE_{}}}}}".format(mode.upper())
546
- tag_close = "{{{{END_IF_MODE_{}}}}}".format(mode.upper())
547
-
548
- if mode == pipeline_mode:
549
- # Keep content, remove tags
550
- content = content.replace(tag_open + "\n", "")
551
- content = content.replace(tag_open, "")
552
- content = content.replace(tag_close + "\n", "")
553
- content = content.replace(tag_close, "")
554
- else:
555
- # Remove entire block
556
- pattern = re.escape(tag_open) + r".*?" + re.escape(tag_close) + r"\n?"
557
- content = re.sub(pattern, "", content, flags=re.DOTALL)
558
-
525
+ def process_template_blocks(content, init_done, browser_interaction=False,
526
+ browser_tool="auto"):
527
+ """Process init and browser blocks in an explicit custom template."""
559
528
  # Init blocks
560
529
  if init_done:
561
530
  content = re.sub(r"\{\{IF_INIT_DONE\}\}\n?", "", content)
@@ -634,32 +603,6 @@ def detect_existing_artifacts(project_root, feature_slug):
634
603
  return result
635
604
 
636
605
 
637
- def determine_pipeline_mode(complexity):
638
- """Return the unified feature prompt mode for any complexity.
639
-
640
- ``estimated_complexity`` remains input metadata for planning summaries,
641
- dependency ordering, and rendered Session Context, but prompt guidance is
642
- intentionally no longer tiered by complexity. Every feature task receives
643
- the full/tier3-equivalent guidance by default.
644
- """
645
- return "full"
646
-
647
-
648
- def determine_legacy_template_mode(complexity):
649
- """Map complexity for explicit custom template conditional compatibility.
650
-
651
- This is used only when a caller supplies ``--template`` and omits
652
- ``--mode``. The normal feature prompt path never uses this mapping.
653
- """
654
- mapping = {
655
- "low": "lite",
656
- "medium": "lite",
657
- "high": "standard",
658
- "critical": "full",
659
- }
660
- return mapping.get(complexity, "lite")
661
-
662
-
663
606
  # ============================================================
664
607
  # Checkpoint generation
665
608
  # ============================================================
@@ -681,6 +624,7 @@ SECTION_TO_SKILL = {
681
624
  "phase-specify-plan": checkpoint_step(
682
625
  "context-snapshot-and-plan", "Specify & Plan",
683
626
  [".prizmkit/specs/{slug}/context-snapshot.md",
627
+ ".prizmkit/specs/{slug}/spec.md",
684
628
  ".prizmkit/specs/{slug}/plan.md"],
685
629
  ),
686
630
  "phase-plan": checkpoint_step(
@@ -693,14 +637,23 @@ SECTION_TO_SKILL = {
693
637
  [".prizmkit/specs/{slug}/test-report.md",
694
638
  ".prizmkit/specs/{slug}/test-result.json"],
695
639
  ),
696
- "phase-review": checkpoint_step("prizmkit-code-review", "Code Review", []),
640
+ "phase-review": checkpoint_step(
641
+ "prizmkit-code-review", "Code Review",
642
+ [".prizmkit/specs/{slug}/review-report.md"],
643
+ ),
697
644
  "phase-browser": checkpoint_step("browser-verification", "Browser Verification", []),
698
- "phase-commit": checkpoint_group([
699
- ("prizmkit-retrospective", "Retrospective", []),
700
- ("prizmkit-committer", "Commit", []),
701
- ("completion-summary", "Completion Summary",
702
- [".prizmkit/specs/{slug}/completion-summary.json"]),
703
- ]),
645
+ "feature-completion-summary": checkpoint_step(
646
+ "completion-summary", "Completion Summary",
647
+ [".prizmkit/specs/{slug}/completion-summary.json"],
648
+ ),
649
+ "phase-commit": checkpoint_step(
650
+ "prizmkit-retrospective", "Retrospective",
651
+ [".prizmkit/specs/{slug}/retrospective-result.json"],
652
+ ),
653
+ "runtime-commit-handoff": checkpoint_step(
654
+ "prizmkit-committer", "Runtime Commit Handoff",
655
+ [".prizmkit/specs/{slug}/runtime-commit-request.json"],
656
+ ),
704
657
  }
705
658
 
706
659
  _COMMIT_STEPS = []
@@ -737,14 +690,31 @@ def _completed_step_artifacts_valid(project_root, skill_key, artifacts):
737
690
  return all(artifact_exists(project_root, artifact) for artifact in artifacts)
738
691
 
739
692
 
740
- def generate_checkpoint_definition(sections, pipeline_mode, workflow_type,
741
- item_id, item_slug, session_id,
742
- init_done=False):
693
+ def _compatibility_checkpoint_sections(init_done=False, browser_enabled=False):
694
+ """Return the canonical stage skeleton for an explicit custom template."""
695
+ sections = [
696
+ ("phase0-test-baseline" if init_done else "phase0-init", ""),
697
+ ("phase-specify-plan", ""),
698
+ ("phase-implement", ""),
699
+ ("phase-review", ""),
700
+ ]
701
+ if browser_enabled:
702
+ sections.append(("phase-browser", ""))
703
+ sections.extend([
704
+ ("phase-prizmkit-test", ""),
705
+ ("feature-completion-summary", ""),
706
+ ("phase-commit", ""),
707
+ ("runtime-commit-handoff", ""),
708
+ ])
709
+ return sections
710
+
711
+
712
+ def generate_checkpoint_definition(sections, workflow_type, item_id, item_slug,
713
+ session_id, init_done=False):
743
714
  """Derive checkpoint step definitions from explicit section contracts."""
744
715
  return generate_checkpoint_from_sections(
745
716
  sections,
746
717
  SECTION_TO_SKILL,
747
- pipeline_mode,
748
718
  workflow_type,
749
719
  item_id,
750
720
  item_slug,
@@ -814,110 +784,41 @@ def load_active_agent_prompts(templates_dir):
814
784
  return prompt_map
815
785
 
816
786
 
817
- def _tier_header(pipeline_mode):
818
- """Return the tier-specific header and mission description."""
819
- headers = {
820
- "lite": (
821
- "# Dev-Pipeline Session Bootstrap Unified Full Guidance "
822
- "(compatibility mode: lite)\n",
823
- "**Unified Full Guidance**: Feature prompts use the "
824
- "full/tier3-equivalent sections for every estimated complexity. "
825
- "The lite label remains metadata only for compatibility.\n",
826
- ),
827
- "standard": (
828
- "# Dev-Pipeline Session Bootstrap — Unified Full Guidance "
829
- "(compatibility mode: standard)\n",
830
- "**Unified Full Guidance**: Feature prompts use the "
831
- "full/tier3-equivalent sections for every estimated complexity. "
832
- "The standard label remains metadata only for compatibility.\n",
833
- ),
834
- "full": (
835
- "# Dev-Pipeline Session Bootstrap — Full Guidance\n",
836
- "**Full Guidance**: Follow the active skills and runtime contracts "
837
- "for context, planning, implementation, review, testing, recovery, "
838
- "and commit.\n",
839
- ),
840
- }
841
- return headers.get(pipeline_mode, headers["lite"])
842
-
843
-
844
- def _tier_reminders(pipeline_mode):
845
- """Return tier-specific reminder text."""
846
- common = [
847
- "- MANDATORY skills: `/prizmkit-retrospective`, `/prizmkit-committer` "
848
- "— never skip these",
849
- "- Build context-snapshot.md FIRST; use it throughout instead of "
850
- "re-reading files",
851
- "- `/prizmkit-committer` is mandatory after all required gates pass — "
852
- "do NOT replace it with manual git commit commands",
853
- "- Do NOT run `git add`/`git commit` during implementation phases — "
854
- "all changes are committed once in the commit phase",
855
- "- If any files remain after the commit, amend the existing commit — "
856
- "do NOT create a follow-up commit",
857
- "- When staging files, always use explicit file names — NEVER use "
858
- "`git add -A` or `git add .`",
859
- ]
860
-
861
- if pipeline_mode == "lite":
862
- specific = [
863
- "- Tier 1: compatibility label only; feature prompts now render "
864
- "the unified full/tier3-equivalent guidance by default",
865
- ]
866
- elif pipeline_mode == "standard":
867
- specific = [
868
- "- Tier 2: compatibility label only; feature prompts now render "
869
- "the unified full/tier3-equivalent guidance by default",
870
- "- context-snapshot.md is the implementation knowledge base; "
871
- "Code Review writes only review-report.md",
872
- "- Gate checks require the Implementation Log (with Gate Evidence) "
873
- "and a valid review-report.md Final Result before proceeding",
874
- "- Follow the active skills and runtime contracts for execution "
875
- "units, review ownership, timeout, and recovery",
876
- ]
877
- else: # full
878
- specific = [
879
- "- Tier 3: follow the active skills and runtime contracts for "
880
- "execution topology and review ownership",
881
- "- context-snapshot.md is the implementation knowledge base; "
882
- "Code Review writes only review-report.md",
883
- "- Gate checks require the Implementation Log and a valid "
884
- "review-report.md Final Result before proceeding",
885
- "- Review execution outside the owning skill contract is forbidden",
886
- "- Do not infer execution-unit permissions or retry behavior from "
887
- "this prompt; use the owning skill/runtime contract",
888
- "- NEVER delete, modify, or touch any file under `.prizmkit/state/` "
889
- "— those are pipeline runtime files managed by the runner",
890
- "- NEVER run `rm -rf`, `git clean`, or destructive filesystem "
891
- "cleanup during the feature session",
892
- "- On execution-unit timeout: preserve the active checkout and "
893
- "artifacts and follow the owning contract's recovery or downgrade "
894
- "path",
895
- ]
896
-
897
- lines = ["## Reminders\n"] + specific + common
898
- return "\n".join(lines) + "\n"
787
+ def _canonical_header():
788
+ """Return the single canonical Feature guidance header."""
789
+ return (
790
+ "# Dev-Pipeline Session Bootstrap — Canonical Guidance\n",
791
+ "**Canonical Guidance**: Follow the active skills and runtime contracts "
792
+ "for context, planning, implementation, review, testing, recovery, "
793
+ "retrospective, and runtime-owned commit execution.\n",
794
+ )
899
795
 
900
796
 
901
- def assemble_sections(pipeline_mode, sections_dir, init_done, is_resume,
902
- browser_enabled, retry_count=0, browser_tool="auto"):
903
- """Assemble prompt sections based on tier and conditions.
797
+ def _canonical_reminders():
798
+ """Return family-neutral reminders for the canonical guidance profile."""
799
+ lines = [
800
+ "## Reminders\n",
801
+ "- Every formal lifecycle stage is mandatory; only configured optional verification may be skipped with evidence.",
802
+ "- Use context-snapshot.md for navigation and handoff, then inspect current source and diffs when correctness requires it.",
803
+ "- Code Review writes only review-report.md and `/prizmkit-test` exclusively owns the test repair loop and terminal test artifacts.",
804
+ "- Atomic Skills return stage-local results only; this injected session owns checkpoint mapping and routing.",
805
+ "- Do not run git add, commit, amend, merge, push, reset, clean, or destructive filesystem cleanup.",
806
+ "- `/prizmkit-committer` prepares the exact runtime commit request; the Python runtime executes and verifies the local commit.",
807
+ "- On execution-unit timeout, preserve the active checkout and artifacts and follow the owning skill's continuation or downgrade contract.",
808
+ ]
809
+ return "\n".join(lines) + "\n"
904
810
 
905
- Uses Python code for conditional logic instead of regex-based
906
- template blocks. Each section is loaded from a separate .md file.
907
811
 
908
- Returns a list of (section_name, content) tuples in order.
909
- """
812
+ def assemble_sections(sections_dir, init_done, browser_enabled,
813
+ browser_tool="auto"):
814
+ """Assemble the canonical prompt sections and configured optional gates."""
910
815
  sections = []
911
816
 
912
- # --- Header ---
913
- title, tier_desc = _tier_header(pipeline_mode)
817
+ title, guidance_desc = _canonical_header()
914
818
  sections.append(("header", title))
915
-
916
- # --- Session Context ---
917
819
  sections.append(("session-context",
918
820
  load_section(sections_dir, "session-context.md")))
919
821
 
920
- # --- Mission ---
921
822
  mission = (
922
823
  "## Your Mission\n\n"
923
824
  "You are the **session orchestrator**. Implement Feature "
@@ -925,180 +826,69 @@ def assemble_sections(pipeline_mode, sections_dir, init_done, is_resume,
925
826
  "**CRITICAL**: Do not exit while recoverable work remains. "
926
827
  "If a required gate is blocked or the workflow cannot safely "
927
828
  "continue, record the blocker and stop with a truthful blocked "
928
- "status; do not claim success or commit an incomplete change."
929
- )
930
- if pipeline_mode != "lite":
931
- mission += (
932
- " Follow the active skill and runtime contracts for any "
933
- "execution units they create, including completion, timeout, "
934
- "resume, and failure handling."
935
- )
936
- mission += "\n\n" + tier_desc
829
+ "status; do not claim success or commit an incomplete change. "
830
+ "Follow the active skill and runtime contracts for any execution "
831
+ "units they create, including completion, timeout, resume, and "
832
+ "failure handling.\n\n"
833
+ ) + guidance_desc
937
834
  sections.append(("mission", mission))
938
835
 
939
- # --- Task Contract: single source of current scope and gates ---
940
836
  sections.append(("task-contract",
941
837
  load_section(sections_dir, "task-contract.md")))
942
-
943
- # --- Feature Context (XML-wrapped, optimization 3) ---
944
838
  sections.append(("feature-context",
945
839
  load_section(sections_dir, "feature-context.md")))
946
-
947
- # --- Context Budget Rules ---
948
840
  sections.append(("context-budget-rules",
949
841
  load_section(sections_dir, "context-budget-rules.md")))
950
-
951
- # --- Directory Convention (tier-specific) ---
952
- if pipeline_mode == "lite":
953
- dc_file = "directory-convention-lite.md"
954
- elif pipeline_mode == "standard":
955
- dc_file = "directory-convention-agent.md"
956
- else:
957
- dc_file = "directory-convention-full.md"
958
842
  sections.append(("directory-convention",
959
- load_section(sections_dir, dc_file)))
843
+ load_section(sections_dir, "directory-convention-full.md")))
844
+ sections.append(("timeout-recovery",
845
+ load_section(sections_dir, "subagent-timeout-recovery.md")))
846
+ sections.append(("artifact-manifest",
847
+ load_section(sections_dir, "artifact-manifest.md")))
960
848
 
961
- # --- Execution-unit timeout recovery ---
962
- if pipeline_mode in ("standard", "full"):
963
- sections.append(("timeout-recovery",
964
- load_section(sections_dir,
965
- "subagent-timeout-recovery.md")))
966
-
967
- # --- Checkpoint System ---
968
849
  checkpoint_section_path = os.path.join(sections_dir, "checkpoint-system.md")
969
850
  if os.path.isfile(checkpoint_section_path):
970
851
  sections.append(("checkpoint-system",
971
852
  load_section(sections_dir, "checkpoint-system.md")))
972
853
 
973
- # --- Execution header ---
974
854
  sections.append(("execution-header", "---\n\n## Execution\n"))
975
-
976
- # --- Phase 0: Init or Test Baseline ---
977
855
  if not init_done:
978
856
  sections.append(("phase0-init",
979
857
  load_section(sections_dir, "phase0-init.md")))
980
858
  else:
981
- if pipeline_mode in ("standard", "full"):
982
- sections.append(("phase0-test-baseline",
983
- load_section(sections_dir,
984
- "phase0-test-baseline.md")))
985
- else:
986
- sections.append(("phase0-skip",
987
- "### Phase 0: SKIP (already initialized)\n"))
988
-
989
- # --- Context Snapshot + Plan (tier-dependent) ---
990
- if pipeline_mode == "full":
991
- # Tier 3: full specify + plan workflow
992
- sections.append(("phase-specify-plan",
993
- load_section(sections_dir,
994
- "phase-specify-plan-full.md")))
995
- else:
996
- # Tier 1 & 2: separate context snapshot + plan
997
- snapshot_base = load_section(sections_dir,
998
- "phase-context-snapshot-base.md")
999
- if pipeline_mode == "lite":
1000
- snapshot_suffix = load_section(
1001
- sections_dir, "phase-context-snapshot-lite-suffix.md")
1002
- else:
1003
- snapshot_suffix = load_section(
1004
- sections_dir, "phase-context-snapshot-agent-suffix.md")
1005
- sections.append(("phase-context-snapshot",
1006
- snapshot_base + "\n" + snapshot_suffix))
1007
-
1008
- if pipeline_mode == "lite":
1009
- sections.append(("phase-plan",
1010
- load_section(sections_dir,
1011
- "phase-plan-lite.md")))
1012
- else:
1013
- sections.append(("phase-plan",
1014
- load_section(sections_dir,
1015
- "phase-plan-agent.md")))
1016
-
1017
-
1018
- # --- Implement (tier-dependent) ---
1019
- if pipeline_mode == "lite":
1020
- sections.append(("phase-implement",
1021
- load_section(sections_dir,
1022
- "phase-implement-lite.md")))
1023
- elif pipeline_mode == "full":
1024
- sections.append(("phase-implement",
1025
- load_section(sections_dir,
1026
- "phase-implement-full.md")))
1027
- else:
1028
- sections.append(("phase-implement",
1029
- load_section(sections_dir,
1030
- "phase-implement-agent.md")))
1031
-
1032
- # Verification Gates are included in Task Contract. Keep AC in one place so
1033
- # background context and implementation prompts cannot redefine scope.
1034
- # --- Review ---
1035
- if pipeline_mode == "full":
1036
- sections.append(("phase-review",
1037
- load_section(sections_dir,
1038
- "phase-review-full.md")))
1039
- else:
1040
- sections.append(("phase-review",
1041
- load_section(sections_dir,
1042
- "phase-review-agent.md")))
1043
-
1044
- # --- Test Failure Recovery Protocol (tier-specific) ---
1045
- if pipeline_mode == "lite":
1046
- sections.append(("test-failure-recovery",
1047
- load_section(sections_dir,
1048
- "test-failure-recovery-lite.md")))
1049
- else:
1050
- sections.append(("test-failure-recovery",
1051
- load_section(sections_dir,
1052
- "test-failure-recovery-agent.md")))
859
+ sections.append(("phase0-test-baseline",
860
+ load_section(sections_dir, "phase0-test-baseline.md")))
1053
861
 
1054
- # --- Scoped Feature Test Gate ---
1055
- sections.append(("phase-prizmkit-test",
1056
- load_section(sections_dir,
1057
- "phase-prizmkit-test.md")))
862
+ sections.append(("phase-specify-plan",
863
+ load_section(sections_dir, "phase-specify-plan-full.md")))
864
+ sections.append(("phase-implement",
865
+ load_section(sections_dir, "phase-implement-full.md")))
866
+ sections.append(("phase-review",
867
+ load_section(sections_dir, "phase-review-full.md")))
1058
868
 
1059
- # --- Browser Verification (conditional, tool-aware) ---
1060
869
  if browser_enabled:
1061
870
  if browser_tool == "opencli":
1062
871
  browser_section_file = "phase-browser-verification-opencli.md"
1063
872
  elif browser_tool == "playwright-cli":
1064
873
  browser_section_file = "phase-browser-verification.md"
1065
874
  else:
1066
- # "auto" or unknown → let AI choose at runtime
1067
875
  browser_section_file = "phase-browser-verification-auto.md"
1068
876
  sections.append(("phase-browser",
1069
- load_section(sections_dir,
1070
- browser_section_file)))
877
+ load_section(sections_dir, browser_section_file)))
1071
878
 
1072
- # --- Headless commit authorization ---
1073
- sections.append(("headless-commit-authorization",
1074
- load_section(sections_dir, "headless-commit-authorization.md")))
1075
-
1076
- # --- Commit (tier-dependent) ---
1077
- if pipeline_mode == "full":
1078
- sections.append(("phase-commit", load_section(sections_dir, "phase-commit-full.md")))
1079
- else:
1080
- sections.append(("phase-commit",
1081
- load_section(sections_dir,
1082
- "phase-commit.md")))
1083
-
1084
- # --- Critical Paths ---
1085
- if pipeline_mode == "lite":
1086
- cp_file = "critical-paths-lite.md"
1087
- elif pipeline_mode == "full":
1088
- cp_file = "critical-paths-full.md"
1089
- else:
1090
- cp_file = "critical-paths-agent.md"
879
+ sections.append(("phase-prizmkit-test",
880
+ load_section(sections_dir, "phase-prizmkit-test.md")))
881
+ sections.append(("feature-completion-summary",
882
+ load_section(sections_dir, "feature-completion-summary.md")))
883
+ sections.append(("phase-commit",
884
+ load_section(sections_dir, "phase-commit-full.md")))
885
+ sections.append(("runtime-commit-handoff",
886
+ load_section(sections_dir, "runtime-commit-handoff.md")))
1091
887
  sections.append(("critical-paths",
1092
- load_section(sections_dir, cp_file)))
1093
-
1094
- # --- Failure Capture ---
888
+ load_section(sections_dir, "critical-paths-full.md")))
1095
889
  sections.append(("failure-capture",
1096
890
  load_section(sections_dir, "failure-capture.md")))
1097
-
1098
- # --- Reminders ---
1099
- sections.append(("reminders",
1100
- _tier_reminders(pipeline_mode)))
1101
-
891
+ sections.append(("reminders", _canonical_reminders()))
1102
892
  return sections
1103
893
 
1104
894
 
@@ -1208,16 +998,6 @@ def build_replacements(args, feature, features, global_context, script_dir):
1208
998
  "estimated_complexity",
1209
999
  feature.get("complexity", "medium"),
1210
1000
  )
1211
- if args.template:
1212
- pipeline_mode = args.mode or determine_legacy_template_mode(complexity)
1213
- else:
1214
- pipeline_mode = determine_pipeline_mode(complexity)
1215
- if args.mode and args.mode != pipeline_mode and not args.template:
1216
- LOGGER.info(
1217
- "Ignoring feature prompt --mode=%s; unified full guidance is used",
1218
- args.mode,
1219
- )
1220
-
1221
1001
  # Auto-detect resume: if all planning artifacts exist and resume_phase
1222
1002
  # is "null" (fresh start), skip to Phase 6
1223
1003
  effective_resume = args.resume_phase
@@ -1277,10 +1057,14 @@ def build_replacements(args, feature, features, global_context, script_dir):
1277
1057
  "{{PROJECT_ROOT}}": project_root,
1278
1058
  "{{FEATURE_SLUG}}": feature_slug,
1279
1059
  "{{ARTIFACT_DIR}}": os.path.join(".prizmkit", "specs", feature_slug),
1060
+ "{{FAMILY_ARTIFACTS}}": "├── completion-summary.json",
1280
1061
  "{{CHECKPOINT_PATH}}": os.path.join(
1281
1062
  ".prizmkit", "specs", feature_slug, "workflow-checkpoint.json",
1282
1063
  ),
1283
- "{{PIPELINE_MODE}}": pipeline_mode,
1064
+ "{{CHECKPOINT_SYSTEM}}": load_section(
1065
+ os.path.join(os.path.dirname(__file__), "..", "templates", "sections"),
1066
+ "checkpoint-system.md",
1067
+ ),
1284
1068
  "{{COMPLEXITY}}": complexity,
1285
1069
  "{{INIT_DONE}}": "true" if init_done else "false",
1286
1070
  "{{HAS_SPEC}}": "true" if artifacts["has_spec"] else "false",
@@ -1314,10 +1098,10 @@ def render_template(template_content, replacements, resume_phase,
1314
1098
  content = process_conditional_blocks(template_content, resume_phase)
1315
1099
 
1316
1100
  # Step 2: Process mode, init, and browser conditional blocks
1317
- pipeline_mode = replacements.get("{{PIPELINE_MODE}}", "standard")
1318
1101
  init_done = replacements.get("{{INIT_DONE}}", "false") == "true"
1319
- content = process_mode_blocks(content, pipeline_mode, init_done,
1320
- browser_enabled, browser_tool)
1102
+ content = process_template_blocks(
1103
+ content, init_done, browser_enabled, browser_tool,
1104
+ )
1321
1105
 
1322
1106
  # Step 3: Replace all {{PLACEHOLDER}} variables (two passes for nested
1323
1107
  # agent prompt templates that may contain their own placeholders)
@@ -1389,7 +1173,6 @@ def main():
1389
1173
  replacements.update(agent_prompt_replacements)
1390
1174
 
1391
1175
  # Extract state needed for assembly
1392
- pipeline_mode = replacements.get("{{PIPELINE_MODE}}", "lite")
1393
1176
  init_done = replacements.get("{{INIT_DONE}}", "false") == "true"
1394
1177
  is_resume = effective_resume != "null"
1395
1178
  # ── Choose rendering path ──────────────────────────────────────────
@@ -1400,31 +1183,17 @@ def main():
1400
1183
  LOGGER.info("Using section assembly from %s", sections_dir)
1401
1184
  try:
1402
1185
  sections = assemble_sections(
1403
- pipeline_mode, sections_dir, init_done, is_resume,
1404
- browser_enabled,
1405
- retry_count=int(args.retry_count),
1186
+ sections_dir, init_done, browser_enabled,
1406
1187
  browser_tool=browser_tool,
1407
1188
  )
1408
1189
  rendered = render_from_sections(sections, replacements)
1409
1190
  except FileNotFoundError as exc:
1410
- LOGGER.warning(
1411
- "Section assembly failed (%s), falling back to legacy "
1412
- "template", exc,
1413
- )
1414
- use_sections = False
1191
+ emit_failure("Section assembly failed: {}".format(exc))
1415
1192
 
1416
1193
  if not use_sections:
1417
- # Legacy monolithic template path (backward compatible)
1418
- if args.template:
1419
- template_path = args.template
1420
- else:
1421
- tier3_path = os.path.join(templates_dir, "bootstrap-tier3.md")
1422
- if os.path.isfile(tier3_path):
1423
- template_path = tier3_path
1424
- else:
1425
- template_path = os.path.join(
1426
- templates_dir, "bootstrap-prompt.md"
1427
- )
1194
+ if not args.template:
1195
+ emit_failure("Canonical prompt sections are unavailable")
1196
+ template_path = args.template
1428
1197
 
1429
1198
  template_content, err = read_text_file(template_path)
1430
1199
  if err:
@@ -1438,11 +1207,7 @@ def main():
1438
1207
  # ── Validate rendered output ───────────────────────────────────────
1439
1208
  is_valid, warnings, errors = validate_rendered(rendered)
1440
1209
  if not is_valid:
1441
- LOGGER.error(
1442
- "Rendered prompt failed validation: %s",
1443
- "; ".join(errors),
1444
- )
1445
- # Continue anyway — a partially valid prompt is better than none
1210
+ emit_failure("Rendered prompt failed validation: {}".format("; ".join(errors)))
1446
1211
 
1447
1212
  # ── Write output ───────────────────────────────────────────────────
1448
1213
  err = write_output(args.output, rendered)
@@ -1455,10 +1220,13 @@ def main():
1455
1220
  checkpoint_path = ""
1456
1221
  checkpoint = {}
1457
1222
 
1458
- if use_sections and feature_slug:
1223
+ if feature_slug:
1224
+ checkpoint_sections = (
1225
+ sections if use_sections
1226
+ else _compatibility_checkpoint_sections(init_done, browser_enabled)
1227
+ )
1459
1228
  checkpoint = generate_checkpoint_definition(
1460
- sections=sections,
1461
- pipeline_mode=pipeline_mode,
1229
+ sections=checkpoint_sections,
1462
1230
  workflow_type="feature-pipeline",
1463
1231
  item_id=args.feature_id,
1464
1232
  item_slug=feature_slug,
@@ -1469,10 +1237,11 @@ def main():
1469
1237
  checkpoint_dir = os.path.join(
1470
1238
  project_root, ".prizmkit", "specs", feature_slug,
1471
1239
  )
1472
- os.makedirs(checkpoint_dir, exist_ok=True)
1473
1240
  checkpoint_path = os.path.join(
1474
1241
  checkpoint_dir, "workflow-checkpoint.json",
1475
1242
  )
1243
+ if not args.no_checkpoint_write:
1244
+ os.makedirs(checkpoint_dir, exist_ok=True)
1476
1245
 
1477
1246
  # Pipeline metadata remains separate from the skill workflow-state contract.
1478
1247
  checkpoint["feature_state"] = feature_checkpoint_metadata(
@@ -1485,7 +1254,7 @@ def main():
1485
1254
  )
1486
1255
 
1487
1256
  # On resume, merge existing completed state (with artifact validation)
1488
- if (is_resume or is_continuation(args)) and os.path.exists(checkpoint_path):
1257
+ if not args.no_checkpoint_write and (is_resume or is_continuation(args)) and os.path.exists(checkpoint_path):
1489
1258
  try:
1490
1259
  with open(checkpoint_path, "r", encoding="utf-8") as f:
1491
1260
  existing = json.load(f)
@@ -1500,15 +1269,25 @@ def main():
1500
1269
  exc,
1501
1270
  )
1502
1271
 
1503
- with open(checkpoint_path, "w", encoding="utf-8") as f:
1504
- json.dump(checkpoint, f, indent=2, ensure_ascii=False)
1505
- LOGGER.info("Wrote checkpoint to %s", checkpoint_path)
1272
+ if not args.no_checkpoint_write:
1273
+ with open(checkpoint_path, "w", encoding="utf-8") as f:
1274
+ json.dump(checkpoint, f, indent=2, ensure_ascii=False)
1275
+ LOGGER.info("Wrote checkpoint to %s", checkpoint_path)
1506
1276
 
1507
1277
  if is_continuation(args):
1508
1278
  rendered = append_continuation_handoff(
1509
1279
  rendered, args, project_root, args.task_type, args.feature_id,
1510
1280
  feature_slug, checkpoint,
1511
1281
  )
1282
+ final_valid, final_warnings, final_errors = validate_rendered(rendered)
1283
+ if not final_valid:
1284
+ emit_failure(
1285
+ "Rendered continuation prompt failed validation: {}".format(
1286
+ "; ".join(final_errors)
1287
+ )
1288
+ )
1289
+ warnings.extend(final_warnings)
1290
+ errors.extend(final_errors)
1512
1291
  err = write_output(args.output, rendered)
1513
1292
  if err:
1514
1293
  emit_failure(err)
@@ -1519,11 +1298,10 @@ def main():
1519
1298
  "success": True,
1520
1299
  "output_path": os.path.abspath(args.output),
1521
1300
  "model": feature_model,
1522
- "pipeline_mode": pipeline_mode,
1523
1301
  "render_mode": "sections" if use_sections else "legacy",
1524
1302
  "validation_warnings": len(warnings),
1525
1303
  "validation_errors": len(errors),
1526
- "checkpoint_path": checkpoint_path,
1304
+ "checkpoint_path": "" if args.no_checkpoint_write else checkpoint_path,
1527
1305
  }
1528
1306
  print(json.dumps(output, indent=2, ensure_ascii=False))
1529
1307
  sys.exit(0)