prizmkit 1.1.105 → 1.1.107

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 (36) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/dev-pipeline/prizmkit_runtime/gitops.py +0 -1
  3. package/bundled/dev-pipeline/prizmkit_runtime/runner_bookkeeping.py +83 -12
  4. package/bundled/dev-pipeline/prizmkit_runtime/runner_classification.py +93 -6
  5. package/bundled/dev-pipeline/prizmkit_runtime/runner_models.py +0 -8
  6. package/bundled/dev-pipeline/prizmkit_runtime/runner_recovery.py +9 -1
  7. package/bundled/dev-pipeline/prizmkit_runtime/runners.py +421 -61
  8. package/bundled/dev-pipeline/prizmkit_runtime/sessions.py +102 -17
  9. package/bundled/dev-pipeline/scripts/continuation.py +0 -4
  10. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +7 -39
  11. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +1 -31
  12. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +1 -31
  13. package/bundled/dev-pipeline/templates/agent-prompts/reviewer-review.md +5 -6
  14. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +28 -28
  15. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +36 -52
  16. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +34 -54
  17. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +1 -1
  18. package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +3 -3
  19. package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +2 -3
  20. package/bundled/dev-pipeline/templates/sections/log-size-awareness.md +2 -2
  21. package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +4 -9
  22. package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +4 -10
  23. package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +3 -3
  24. package/bundled/dev-pipeline/templates/sections/phase-review-full.md +3 -3
  25. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +49 -2
  26. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +17 -0
  27. package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +50 -1
  28. package/bundled/dev-pipeline/tests/test_python_runner_parity.py +560 -1
  29. package/bundled/dev-pipeline/tests/test_unified_cli.py +208 -0
  30. package/bundled/skills/_metadata.json +1 -1
  31. package/bundled/skills/prizmkit-code-review/SKILL.md +12 -13
  32. package/bundled/skills/prizmkit-code-review/references/reviewer-agent-prompt.md +10 -10
  33. package/package.json +1 -1
  34. package/bundled/dev-pipeline/templates/agent-prompts/dev-fix.md +0 -7
  35. package/bundled/dev-pipeline/templates/agent-prompts/dev-resume.md +0 -5
  36. package/bundled/skills/prizmkit-code-review/references/dev-agent-prompt.md +0 -30
@@ -28,6 +28,20 @@ from generate_bootstrap_prompt import (
28
28
  )
29
29
  from continuation import append_continuation_handoff, checkpoint_cursor
30
30
 
31
+ REMOVED_MAX_LOG_ENV = "MAX_" + "LOG_SIZE"
32
+ REMOVED_MAX_LOG_HUMAN = REMOVED_MAX_LOG_ENV + "_HUMAN"
33
+
34
+ FORBIDDEN_DEV_FIX_PROMPT = "dev-" + "fix.md"
35
+ FORBIDDEN_DEV_RESUME_PROMPT = "dev-" + "resume.md"
36
+ FORBIDDEN_DEV_FIX_PLACEHOLDER = "{{AGENT_PROMPT_DEV_" + "FIX}}"
37
+ FORBIDDEN_DEV_RESUME_PLACEHOLDER = "{{AGENT_PROMPT_DEV_" + "RESUME}}"
38
+ FORBIDDEN_REVIEW_DEV_FIX = "Reviewer Agent → filter → " + "Dev Agent fix"
39
+ FORBIDDEN_REVIEWER_DEV_SPAWN = "Reviewer/" + "Dev agent spawn"
40
+ FORBIDDEN_EXPLORE_SUBAGENT = "subagent_type: " + "Explore"
41
+ FORBIDDEN_TEST_CMD_PLACEHOLDER = "(" + "$TEST_CMD" + ")"
42
+ FORBIDDEN_THREE_STRIKE = "3-" + "strike"
43
+ FORBIDDEN_TWENTY_STEP = "20-" + "step window"
44
+
31
45
 
32
46
  def scoped_report_text(verdict="PASS", boundary_missing=0,
33
47
  happy_path_only=0, completion_gate="yes",
@@ -222,6 +236,11 @@ class TestExplicitProjectRoot:
222
236
  assert not replacements["{{SESSION_STATUS_PATH}}"].startswith(str(execution_root.resolve()))
223
237
  assert replacements["{{PROJECT_BRIEF}}"] == "worktree brief"
224
238
  assert replacements["{{DEV_SUBAGENT_PATH}}"].startswith(str(execution_root.resolve()))
239
+ assert replacements["{{SESSION_LOG_PATH}}"].endswith(
240
+ ".prizmkit/state/features/F-001/sessions/session-1/logs/session.log"
241
+ )
242
+ assert "{{" + REMOVED_MAX_LOG_ENV + "}}" not in replacements
243
+ assert "{{" + REMOVED_MAX_LOG_HUMAN + "}}" not in replacements
225
244
 
226
245
 
227
246
  def test_main_writes_checkpoint_under_cli_project_root_and_status_under_state_dir(self, tmp_path, monkeypatch):
@@ -779,11 +798,14 @@ class TestHeadlessRecoveryReframing:
779
798
  def test_log_size_awareness_is_passive_checkpoint_guidance(self):
780
799
  content = load_log_size_section(str(Path("dev-pipeline/scripts").resolve()))
781
800
 
782
- assert "Session Log Budget Awareness" in content
801
+ assert "Session Checkpoint Awareness" in content
783
802
  assert "passive checkpoint guidance" in content
784
803
  assert "durable checkpoints and artifacts" in content
785
804
  assert "fresh continuation session" in content
786
805
  assert "optional interactive convenience only" in content
806
+ assert REMOVED_MAX_LOG_ENV not in content
807
+ assert ("maximum-" + "log-size") not in content
808
+ assert ("log size " + "limit") not in content.lower()
787
809
  assert "COMPACT_NEEDED" not in content
788
810
  assert "monitor-log" not in content
789
811
  assert "background monitoring subagent" not in content
@@ -802,6 +824,10 @@ class TestHeadlessRecoveryReframing:
802
824
  )
803
825
  assert "Headless recovery must rely on durable checkpoints" in rendered
804
826
  assert "fresh continuation session" in rendered
827
+ assert REMOVED_MAX_LOG_ENV not in rendered
828
+ assert REMOVED_MAX_LOG_HUMAN not in rendered
829
+ assert ("209" + "7152") not in rendered
830
+ assert ("2" + "MB") not in rendered
805
831
  assert "monitor-log" not in rendered
806
832
  assert "COMPACT_NEEDED" not in rendered
807
833
  assert "log-size monitor" not in rendered
@@ -818,9 +844,16 @@ class TestDirectOrchestratorImplementationPrompts:
818
844
  replacements = load_active_agent_prompts(str(templates_dir))
819
845
 
820
846
  assert "dev-implement.md" not in ACTIVE_AGENT_PROMPTS
847
+ assert FORBIDDEN_DEV_FIX_PROMPT not in ACTIVE_AGENT_PROMPTS
848
+ assert FORBIDDEN_DEV_RESUME_PROMPT not in ACTIVE_AGENT_PROMPTS
821
849
  assert "{{AGENT_PROMPT_DEV_IMPLEMENT}}" not in replacements
850
+ assert FORBIDDEN_DEV_FIX_PLACEHOLDER not in replacements
851
+ assert FORBIDDEN_DEV_RESUME_PLACEHOLDER not in replacements
822
852
  assert "{{AGENT_PROMPT_CRITIC_PLAN_CHALLENGE}}" in replacements
853
+ assert "{{AGENT_PROMPT_REVIEWER_REVIEW}}" in replacements
823
854
  assert (templates_dir / "agent-prompts" / "dev-implement.md").exists() is False
855
+ assert (templates_dir / "agent-prompts" / FORBIDDEN_DEV_FIX_PROMPT).exists() is False
856
+ assert (templates_dir / "agent-prompts" / FORBIDDEN_DEV_RESUME_PROMPT).exists() is False
824
857
 
825
858
  def test_sections_all_modes_use_direct_orchestrator_implementation(self):
826
859
  sections_dir = Path("dev-pipeline/templates/sections").resolve()
@@ -840,7 +873,13 @@ class TestDirectOrchestratorImplementationPrompts:
840
873
  assert "Implement — Dev" not in rendered
841
874
  assert "{{AGENT_PROMPT_DEV_IMPLEMENT}}" not in rendered
842
875
  assert "dev-implement.md" not in rendered
843
- assert "Reviewer Agent → filter → Dev Agent fix" in rendered
876
+ assert FORBIDDEN_REVIEW_DEV_FIX not in rendered
877
+ assert FORBIDDEN_REVIEWER_DEV_SPAWN not in rendered
878
+ assert FORBIDDEN_EXPLORE_SUBAGENT not in rendered
879
+ assert FORBIDDEN_TEST_CMD_PLACEHOLDER not in rendered
880
+ assert FORBIDDEN_THREE_STRIKE not in rendered
881
+ assert FORBIDDEN_TWENTY_STEP not in rendered
882
+ assert "Reviewer Agent → filter → orchestrator fix" in rendered
844
883
 
845
884
  def test_legacy_tier_templates_use_direct_orchestrator_implementation(self):
846
885
  for template_name in ("bootstrap-tier2.md", "bootstrap-tier3.md"):
@@ -853,6 +892,12 @@ class TestDirectOrchestratorImplementationPrompts:
853
892
  assert "Implement — Dev" not in rendered
854
893
  assert "{{AGENT_PROMPT_DEV_IMPLEMENT}}" not in rendered
855
894
  assert "dev-implement.md" not in rendered
895
+ assert FORBIDDEN_REVIEW_DEV_FIX not in rendered
896
+ assert FORBIDDEN_REVIEWER_DEV_SPAWN not in rendered
897
+ assert FORBIDDEN_EXPLORE_SUBAGENT not in rendered
898
+ assert FORBIDDEN_TEST_CMD_PLACEHOLDER not in rendered
899
+ assert FORBIDDEN_THREE_STRIKE not in rendered
900
+ assert FORBIDDEN_TWENTY_STEP not in rendered
856
901
 
857
902
 
858
903
  # ---------------------------------------------------------------------------
@@ -898,6 +943,8 @@ class TestContinuationHandoff:
898
943
  assert ".prizmkit/state/features/F-123/sessions/F-123-new/logs/session.log" in rendered
899
944
  assert ".prizmkit/state/features/F-123/sessions/F-123-new/logs/progress.json" in rendered
900
945
  assert ".prizmkit/state/features/F-123/sessions/F-123-new/logs/ai.pid" in rendered
946
+ assert ("Log " + "monitor") not in rendered
947
+ assert ("log-" + "monitor") not in rendered
901
948
 
902
949
  summary = tmp_path / ".prizmkit/specs/123-continuation/continuation-summary.md"
903
950
  assert summary.exists()
@@ -16,6 +16,9 @@ from generate_bugfix_prompt import (
16
16
  )
17
17
  from continuation import append_continuation_handoff
18
18
 
19
+ REMOVED_MAX_LOG_ENV = "MAX_" + "LOG_SIZE"
20
+ REMOVED_MAX_LOG_HUMAN = REMOVED_MAX_LOG_ENV + "_HUMAN"
21
+
19
22
 
20
23
  # ---------------------------------------------------------------------------
21
24
  # find_bug
@@ -193,6 +196,11 @@ class TestExplicitProjectRoot:
193
196
  )
194
197
  assert not replacements["{{SESSION_STATUS_PATH}}"].startswith(str(execution_root.resolve()))
195
198
  assert replacements["{{DEV_SUBAGENT_PATH}}"].startswith(str(execution_root.resolve()))
199
+ assert replacements["{{SESSION_LOG_PATH}}"].endswith(
200
+ ".prizmkit/state/bugfix/B-001/sessions/session-1/logs/session.log"
201
+ )
202
+ assert "{{" + REMOVED_MAX_LOG_ENV + "}}" not in replacements
203
+ assert "{{" + REMOVED_MAX_LOG_HUMAN + "}}" not in replacements
196
204
 
197
205
 
198
206
  # ---------------------------------------------------------------------------
@@ -225,6 +233,9 @@ class TestHeadlessRecoveryReframing:
225
233
  assert "Headless recovery must rely on durable checkpoints" in content
226
234
  assert "fresh continuation session" in content
227
235
  assert "optional interactive convenience only" in content
236
+ assert REMOVED_MAX_LOG_ENV not in content
237
+ assert ("maximum-" + "log-size") not in content
238
+ assert ("log size " + "limit") not in content.lower()
228
239
  assert "COMPACT_NEEDED" not in content
229
240
  assert "monitor-log" not in content
230
241
  assert "background monitoring subagent" not in content
@@ -235,6 +246,10 @@ class TestHeadlessRecoveryReframing:
235
246
  content = Path("dev-pipeline/templates/bugfix-bootstrap-prompt.md").read_text(encoding="utf-8")
236
247
 
237
248
  assert "Do not spawn persistent background subagents for headless recovery" in content
249
+ assert REMOVED_MAX_LOG_ENV not in content
250
+ assert REMOVED_MAX_LOG_HUMAN not in content
251
+ assert ("209" + "7152") not in content
252
+ assert ("2" + "MB") not in content
238
253
  assert "log-size monitor" not in content
239
254
  assert "monitor-log" not in content
240
255
  assert "COMPACT_NEEDED" not in content
@@ -264,5 +279,7 @@ class TestBugfixContinuationHandoff:
264
279
  assert prompt.startswith("BUGFIX PROMPT")
265
280
  assert "This is an automatic continuation after context overflow." in prompt
266
281
  assert "Do not attempt `/compact` as the recovery mechanism." in prompt
282
+ assert ("Log " + "monitor") not in prompt
283
+ assert ("log-" + "monitor") not in prompt
267
284
  assert (tmp_path / ".prizmkit/specs/B-007/continuation-summary.md").exists()
268
285
  assert (tmp_path / ".prizmkit/bugfix/B-007/continuation-summary.md").exists()
@@ -1,9 +1,18 @@
1
1
  """Tests for generate-refactor-prompt.py continuation behavior."""
2
2
 
3
3
  from argparse import Namespace
4
+ from pathlib import Path
4
5
 
5
6
  from continuation import append_continuation_handoff
6
- from generate_refactor_prompt import generate_refactor_checkpoint, merge_refactor_checkpoint_state
7
+ from generate_refactor_prompt import (
8
+ build_replacements,
9
+ generate_refactor_checkpoint,
10
+ load_log_size_section,
11
+ merge_refactor_checkpoint_state,
12
+ )
13
+
14
+ REMOVED_MAX_LOG_ENV = "MAX_" + "LOG_SIZE"
15
+ REMOVED_MAX_LOG_HUMAN = REMOVED_MAX_LOG_ENV + "_HUMAN"
7
16
 
8
17
 
9
18
  class TestRefactorContinuationHandoff:
@@ -27,6 +36,8 @@ class TestRefactorContinuationHandoff:
27
36
  assert prompt.startswith("REFACTOR PROMPT")
28
37
  assert "This is a fresh headless AI CLI session for the same task." in prompt
29
38
  assert "Do not attempt `/compact` as the recovery mechanism." in prompt
39
+ assert ("Log " + "monitor") not in prompt
40
+ assert ("log-" + "monitor") not in prompt
30
41
  assert (tmp_path / ".prizmkit/specs/R-007/continuation-summary.md").exists()
31
42
  assert (tmp_path / ".prizmkit/refactor/R-007/continuation-summary.md").exists()
32
43
 
@@ -41,3 +52,41 @@ class TestRefactorCheckpointMerge:
41
52
 
42
53
  assert merged["steps"][0]["status"] == "skipped"
43
54
  assert merged["steps"][1]["status"] == "pending"
55
+
56
+
57
+ class TestRefactorPromptMaxLogRemoval:
58
+ def test_refactor_log_size_section_is_checkpoint_guidance_without_max_log_env(self):
59
+ content = load_log_size_section(str(Path("dev-pipeline/scripts").resolve()))
60
+
61
+ assert "passive checkpoint guidance" in content
62
+ assert "Headless recovery must rely on durable checkpoints" in content
63
+ assert "fresh continuation session" in content
64
+ assert REMOVED_MAX_LOG_ENV not in content
65
+ assert REMOVED_MAX_LOG_HUMAN not in content
66
+ assert ("maximum-" + "log-size") not in content
67
+ assert ("log size " + "limit") not in content.lower()
68
+
69
+ def test_refactor_replacements_keep_session_log_without_max_log_placeholders(self):
70
+ args = Namespace(
71
+ refactor_id="R-001",
72
+ session_id="session-1",
73
+ run_id="run-1",
74
+ retry_count="0",
75
+ resume_phase="null",
76
+ state_dir=None,
77
+ output="out.md",
78
+ template=None,
79
+ mode=None,
80
+ critic=None,
81
+ )
82
+ refactor = {"id": "R-001", "title": "Restructure", "description": "d"}
83
+
84
+ replacements = build_replacements(
85
+ args, refactor, [refactor], {}, str(Path("dev-pipeline/scripts").resolve())
86
+ )
87
+
88
+ assert replacements["{{SESSION_LOG_PATH}}"].endswith(
89
+ ".prizmkit/state/refactor/R-001/sessions/session-1/logs/session.log"
90
+ )
91
+ assert "{{" + REMOVED_MAX_LOG_ENV + "}}" not in replacements
92
+ assert "{{" + REMOVED_MAX_LOG_HUMAN + "}}" not in replacements