prizmkit 1.1.119 → 1.1.121

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 (91) hide show
  1. package/bin/create-prizmkit.js +1 -5
  2. package/bundled/VERSION.json +3 -3
  3. package/bundled/dev-pipeline/README.md +41 -38
  4. package/bundled/dev-pipeline/assets/skill-subagent-integration.md +76 -0
  5. package/bundled/dev-pipeline/prizmkit_runtime/config.py +2 -8
  6. package/bundled/dev-pipeline/prizmkit_runtime/interoperability.py +1 -1
  7. package/bundled/dev-pipeline/prizmkit_runtime/platform_detection.py +3 -3
  8. package/bundled/dev-pipeline/prizmkit_runtime/runner_classification.py +23 -25
  9. package/bundled/dev-pipeline/prizmkit_runtime/runner_models.py +8 -2
  10. package/bundled/dev-pipeline/prizmkit_runtime/runner_prompts.py +10 -1
  11. package/bundled/dev-pipeline/prizmkit_runtime/runners.py +88 -32
  12. package/bundled/dev-pipeline/prizmkit_runtime/sessions.py +28 -6
  13. package/bundled/dev-pipeline/scripts/continuation.py +51 -6
  14. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +60 -102
  15. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +1 -19
  16. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +1 -19
  17. package/bundled/dev-pipeline/scripts/{init-dev-team.py → init-change-artifact.py} +6 -16
  18. package/bundled/dev-pipeline/scripts/parse-stream-progress.py +364 -76
  19. package/bundled/dev-pipeline/scripts/update-bug-status.py +57 -14
  20. package/bundled/dev-pipeline/scripts/update-feature-status.py +54 -5
  21. package/bundled/dev-pipeline/scripts/update-refactor-status.py +57 -14
  22. package/bundled/dev-pipeline/scripts/utils.py +1 -1
  23. package/bundled/dev-pipeline/templates/bootstrap-prompt.md +2 -2
  24. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +9 -11
  25. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +2 -1
  26. package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +2 -2
  27. package/bundled/dev-pipeline/templates/sections/bugfix-phase-review.md +3 -3
  28. package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +1 -1
  29. package/bundled/dev-pipeline/templates/sections/critical-paths-agent.md +0 -1
  30. package/bundled/dev-pipeline/templates/sections/critical-paths-full.md +0 -2
  31. package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +8 -1
  32. package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +6 -7
  33. package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +6 -7
  34. package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +4 -2
  35. package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +3 -3
  36. package/bundled/dev-pipeline/templates/sections/phase-review-full.md +5 -3
  37. package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +20 -0
  38. package/bundled/dev-pipeline/templates/sections/refactor-phase-review.md +3 -3
  39. package/bundled/dev-pipeline/tests/test_auto_skip.py +5 -5
  40. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +214 -144
  41. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +25 -12
  42. package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +11 -14
  43. package/bundled/dev-pipeline/tests/test_python_runner_parity.py +235 -32
  44. package/bundled/dev-pipeline/tests/test_unified_cli.py +219 -16
  45. package/bundled/skills/_metadata.json +4 -4
  46. package/bundled/skills/app-planner/SKILL.md +2 -2
  47. package/bundled/skills/app-planner/references/architecture-decisions.md +1 -3
  48. package/bundled/skills/prizmkit-code-review/SKILL.md +50 -47
  49. package/bundled/skills/prizmkit-code-review/references/review-report-template.md +13 -8
  50. package/bundled/skills/prizmkit-code-review/references/reviewer-agent-prompt.md +47 -33
  51. package/bundled/skills/prizmkit-code-review/references/reviewer-workspace-protocol.md +90 -0
  52. package/bundled/skills/prizmkit-implement/SKILL.md +21 -1
  53. package/bundled/skills/prizmkit-implement/references/implementation-subagent-procedure.md +67 -0
  54. package/bundled/skills/prizmkit-test/SKILL.md +159 -155
  55. package/bundled/skills/prizmkit-test/assets/authoritative-records.schema.json +420 -0
  56. package/bundled/skills/prizmkit-test/assets/behavior-risk-matrix.schema.json +116 -0
  57. package/bundled/skills/prizmkit-test/assets/evidence-manifest.schema.json +112 -0
  58. package/bundled/skills/prizmkit-test/assets/evidence-package-template.json +97 -0
  59. package/bundled/skills/prizmkit-test/references/boundary-coverage-protocol.md +76 -192
  60. package/bundled/skills/prizmkit-test/references/contract-mock-protocol.md +65 -0
  61. package/bundled/skills/prizmkit-test/references/evidence-protocol.md +194 -0
  62. package/bundled/skills/prizmkit-test/references/evidence-request-protocol.md +78 -0
  63. package/bundled/skills/prizmkit-test/references/examples.md +65 -108
  64. package/bundled/skills/prizmkit-test/references/service-boundary-test-catalog.md +10 -7
  65. package/bundled/skills/prizmkit-test/references/test-generation-steps.md +90 -82
  66. package/bundled/skills/prizmkit-test/references/test-report-template.md +77 -98
  67. package/bundled/skills/prizmkit-test/references/trusted-evidence-execution.md +97 -0
  68. package/bundled/skills/prizmkit-test/scripts/build_test_evidence.py +723 -0
  69. package/bundled/skills/prizmkit-test/scripts/validate_test_evidence.py +1426 -0
  70. package/package.json +1 -1
  71. package/src/clean.js +12 -8
  72. package/src/config.js +24 -42
  73. package/src/index.js +1 -10
  74. package/src/manifest.js +3 -9
  75. package/src/metadata.js +0 -26
  76. package/src/prompts.js +0 -13
  77. package/src/scaffold.js +76 -201
  78. package/src/upgrade.js +16 -33
  79. package/bundled/adapters/claude/agent-adapter.js +0 -96
  80. package/bundled/adapters/claude/team-adapter.js +0 -183
  81. package/bundled/adapters/codebuddy/agent-adapter.js +0 -42
  82. package/bundled/adapters/codebuddy/team-adapter.js +0 -46
  83. package/bundled/adapters/codex/agent-adapter.js +0 -38
  84. package/bundled/adapters/codex/team-adapter.js +0 -37
  85. package/bundled/agents/prizm-dev-team-dev.md +0 -123
  86. package/bundled/agents/prizm-dev-team-reviewer.md +0 -113
  87. package/bundled/dev-pipeline/assets/prizm-dev-team-integration.md +0 -65
  88. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +0 -436
  89. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +0 -510
  90. package/bundled/skills/prizmkit-test/scripts/validate_boundary_report.py +0 -347
  91. package/bundled/team/prizm-dev-team.json +0 -27
@@ -41,6 +41,17 @@ def run_cli(*args):
41
41
  )
42
42
 
43
43
 
44
+ def _load_progress_parser_module():
45
+ import importlib.util
46
+
47
+ parser_path = PIPELINE_ROOT / "scripts" / "parse-stream-progress.py"
48
+ spec = importlib.util.spec_from_file_location("parse_stream_progress", parser_path)
49
+ module = importlib.util.module_from_spec(spec)
50
+ assert spec.loader is not None
51
+ spec.loader.exec_module(module)
52
+ return module
53
+
54
+
44
55
  def test_cli_help_exposes_python_runtime_command_groups():
45
56
  result = run_cli("--help")
46
57
 
@@ -791,24 +802,28 @@ def test_session_preamble_writes_redacted_start_command_for_all_launch_profiles(
791
802
  assert str(prompt) not in "\n".join(lines[:6])
792
803
 
793
804
 
794
- def test_headless_subagent_prompt_guidance_keeps_no_worktree_boundary_visible():
805
+ def test_headless_review_guidance_uses_workspace_equivalence_protocol():
795
806
  guidance_files = [
796
- REPO_ROOT / "dev-pipeline" / "templates" / "bootstrap-tier2.md",
807
+ REPO_ROOT / "dev-pipeline" / "templates" / "sections" / "phase-review-full.md",
797
808
  REPO_ROOT / "dev-pipeline" / "templates" / "bootstrap-tier3.md",
798
809
  REPO_ROOT / "core" / "skills" / "prizmkit-skill" / "prizmkit-code-review" / "SKILL.md",
799
810
  ]
800
811
 
801
812
  for path in guidance_files:
802
813
  text = path.read_text(encoding="utf-8")
803
- assert (
804
- "default/no worktree" in text
805
- or "current-workspace / active-checkout / no-worktree" in text
806
- or "current workspace / active checkout / no worktree" in text
807
- ), path
808
- assert "do not request or create" in text.lower() or "do not request worktree isolation" in text.lower(), path
809
- assert ".claude/worktrees/..." in text, path
810
- assert ".prizmkit/state/worktrees/..." in text, path
811
- assert "USE_WORKTREE" in text, path
814
+ assert "platform-supported" in text, path
815
+ assert "snapshot" in text and "equivalent" in text, path
816
+ assert "Main-Agent self-review" in text, path
817
+ assert "current-workspace / active-checkout / no-worktree" not in text, path
818
+ assert ".claude/worktrees/..." not in text, path
819
+ assert ".prizmkit/state/worktrees/..." not in text, path
820
+ assert "USE_WORKTREE" not in text, path
821
+ assert "isolation:" not in text, path
822
+
823
+ skill_text = guidance_files[-1].read_text(encoding="utf-8")
824
+ assert "reviewer-workspace-protocol.md" in skill_text
825
+ assert "staged, unstaged, untracked, deleted, and renamed" in skill_text
826
+ assert "WORKSPACE_MISMATCH" in skill_text
812
827
 
813
828
  for path in guidance_files[:-1]:
814
829
  text = path.read_text(encoding="utf-8")
@@ -840,6 +855,145 @@ def test_progress_parser_adds_required_metadata(tmp_path):
840
855
  assert data["permission_denial_count"] == 1
841
856
 
842
857
 
858
+
859
+ def test_progress_parser_normalizes_claude_subagents_without_double_counting(tmp_path):
860
+ module = _load_progress_parser_module()
861
+ tracker = module.ProgressTracker()
862
+
863
+ tracker.process_event({"type": "system", "subtype": "init", "session_id": "claude-session", "cwd": str(tmp_path)})
864
+ tracker.process_event({
865
+ "type": "assistant",
866
+ "message": {"content": [{
867
+ "type": "tool_use",
868
+ "id": "tool-1",
869
+ "name": "Agent",
870
+ "input": {"description": "review code", "prompt": "check", "subagent_type": "reviewer"},
871
+ }]},
872
+ })
873
+ tracker.process_event({
874
+ "type": "system",
875
+ "subtype": "task_started",
876
+ "task_id": "task-1",
877
+ "tool_use_id": "tool-1",
878
+ "task_type": "in_process_teammate",
879
+ "subagent_type": "reviewer",
880
+ "description": "review code",
881
+ })
882
+ tracker.process_event({"type": "assistant", "parent_tool_use_id": "tool-1", "message": {"content": [{"type": "text", "text": "child activity"}]}})
883
+ tracker.process_event({"type": "system", "subtype": "task_started", "task_id": "bash-1", "task_type": "local_bash", "description": "ls"})
884
+ tracker.process_event({"type": "system", "subtype": "task_notification", "task_id": "task-1", "tool_use_id": "tool-1", "status": "completed", "summary": "done"})
885
+
886
+ data = tracker.to_dict()
887
+
888
+ assert data["subagent_stats_source"] == "session_log"
889
+ assert data["subagent_spawn_count"] == 1
890
+ assert data["active_subagent_count"] == 0
891
+ assert data["subagent_states"] == [{"status": "completed", "count": 1}]
892
+ assert "task-1" in data["subagent_observed_ids"]
893
+ assert "tool-1" in data["subagent_statistics"]["parent_activity_ids"]
894
+ assert all("bash" not in record["id"] for record in data["subagent_statistics"]["records"])
895
+
896
+
897
+ def test_progress_parser_normalizes_codebuddy_agent_tools_with_deduplication():
898
+ module = _load_progress_parser_module()
899
+ tracker = module.ProgressTracker()
900
+ args = {"prompt": "inspect", "description": "inspect", "subagent_type": "Explore"}
901
+
902
+ tracker.process_event({
903
+ "type": "message",
904
+ "sessionId": "cb-session",
905
+ "cwd": "/tmp/project",
906
+ "role": "assistant",
907
+ "content": [{"type": "tool_use", "id": "call-1", "name": "Agent", "input": args}],
908
+ })
909
+ tracker.process_event({
910
+ "type": "function_call",
911
+ "sessionId": "cb-session",
912
+ "cwd": "/tmp/project",
913
+ "id": "call-1",
914
+ "name": "Agent",
915
+ "arguments": json.dumps(args),
916
+ })
917
+ tracker.process_event({
918
+ "type": "function_call",
919
+ "sessionId": "cb-session",
920
+ "cwd": "/tmp/project",
921
+ "id": "task-call",
922
+ "name": "TaskCreate",
923
+ "arguments": json.dumps({"description": "background", "subject": "status"}),
924
+ })
925
+
926
+ data = tracker.to_dict()
927
+
928
+ assert data["cb_session_id"] == "cb-session"
929
+ assert data["subagent_provider"] == "codebuddy"
930
+ assert data["subagent_spawn_count"] == 2
931
+ assert data["active_subagent_count"] == 2
932
+ assert {item["status"] for item in data["subagent_states"]} == {"running"}
933
+ assert len(data["subagent_statistics"]["records"]) == 2
934
+
935
+
936
+ def test_progress_parser_normalizes_codex_collab_metadata_with_missing_fields():
937
+ module = _load_progress_parser_module()
938
+ tracker = module.ProgressTracker()
939
+
940
+ tracker.process_event({"type": "thread.started", "thread_id": "parent"})
941
+ tracker.process_event({
942
+ "type": "item.started",
943
+ "item": {
944
+ "type": "collab_tool_call",
945
+ "tool": "delegate",
946
+ "receiver_thread_ids": ["thread-a", "thread-b"],
947
+ "agents_states": {
948
+ "thread-a": {"status": "running", "message": "working"},
949
+ "thread-b": {"status": "completed", "message": "done"},
950
+ },
951
+ },
952
+ })
953
+ tracker.process_event({"type": "item.completed", "item": {"type": "collab_tool_call", "tool": "delegate"}})
954
+
955
+ data = tracker.to_dict()
956
+
957
+ assert data["event_format"] == "codex-json"
958
+ assert data["child_thread_ids"] == ["thread-a", "thread-b"]
959
+ assert data["subagent_spawn_count"] == 2
960
+ assert data["active_subagent_count"] == 1
961
+ assert {state["status"]: state["count"] for state in data["subagent_states"]} == {"running": 1, "completed": 1}
962
+ assert data["subagent_source_metadata"]["child_activity_source"] == "filesystem_liveness_only"
963
+
964
+
965
+ def test_progress_parser_keeps_child_files_liveness_only(tmp_path, monkeypatch):
966
+ module = _load_progress_parser_module()
967
+ claude_home = tmp_path / "claude"
968
+ project_key = str(tmp_path).replace("\\", "-").replace("/", "-").replace(":", "")
969
+ subagents_dir = claude_home / "projects" / project_key / "parent-session" / "subagents"
970
+ subagents_dir.mkdir(parents=True)
971
+ child_log = subagents_dir / "agent-child.jsonl"
972
+ child_log.write_text("child activity", encoding="utf-8")
973
+ monkeypatch.setenv("CLAUDE_HOME", str(claude_home))
974
+
975
+ tracker = module.ProgressTracker()
976
+ tracker.process_event({"type": "system", "subtype": "init", "session_id": "parent-session", "cwd": str(tmp_path)})
977
+ tracker.process_event({
978
+ "type": "system",
979
+ "subtype": "task_started",
980
+ "task_id": "task-1",
981
+ "tool_use_id": "tool-1",
982
+ "task_type": "in_process_teammate",
983
+ "description": "agent",
984
+ })
985
+ first = tracker.to_dict()
986
+ child_log.write_text("child activity grew", encoding="utf-8")
987
+ tracker.refresh_child_session_activity(force=True)
988
+ second = tracker.to_dict()
989
+
990
+ assert first["subagent_spawn_count"] == 1
991
+ assert second["subagent_spawn_count"] == 1
992
+ assert second["child_total_bytes"] > first["child_total_bytes"]
993
+ assert second["child_session_files"]
994
+ assert second["child_activity_source"] == "filesystem_liveness_only"
995
+ assert second["subagent_statistics"]["source"] == "session_log"
996
+
843
997
  def test_session_dual_writes_progress_and_recovers_backup(tmp_path):
844
998
  from prizmkit_runtime.sessions import AISessionConfig, AISessionLauncher, recover_session_log
845
999
 
@@ -935,6 +1089,10 @@ def test_custom_session_launch_writes_existing_logs_and_progress(tmp_path):
935
1089
  progress_data = json.loads(progress.read_text(encoding="utf-8"))
936
1090
  assert progress_data["event_type_counts"]["result"] == 1
937
1091
  assert progress_data["has_usage"] is True
1092
+ assert progress_data["subagent_stats_source"] == "session_log"
1093
+ assert progress_data["subagent_spawn_count"] == 0
1094
+ assert progress_data["subagent_statistics"]["providers"] == []
1095
+ assert progress_data["child_activity_source"] == "filesystem_liveness_only"
938
1096
 
939
1097
 
940
1098
  @pytest.mark.parametrize("platform", ["claude", "codex", "codebuddy"])
@@ -1031,7 +1189,10 @@ def test_compact_progress_line_hides_stale_until_no_progress(tmp_path):
1031
1189
  json.dumps(
1032
1190
  {
1033
1191
  "child_total_bytes": 2 * 1024 * 1024,
1192
+ "child_session_files": [{"path": "a"}, {"path": "b"}],
1034
1193
  "subagent_spawn_count": 5,
1194
+ "active_subagent_count": 2,
1195
+ "subagent_states": [{"status": "running", "count": 2}, {"status": "completed", "count": 3}],
1035
1196
  "current_phase": "stream-derived-phase",
1036
1197
  "current_tool": "Read",
1037
1198
  "message_count": 465,
@@ -1059,7 +1220,9 @@ def test_compact_progress_line_hides_stale_until_no_progress(tmp_path):
1059
1220
 
1060
1221
  assert "▶ [HEARTBEAT]" in running_line
1061
1222
  assert "log: 4MB" in running_line
1062
- assert "child: 2MB/5" in running_line
1223
+ assert "subagents: spawned=5 active=2 states:running=2,completed=3" in running_line
1224
+ assert "child logs: 2MB/2 files" in running_line
1225
+ assert "child: 2MB/5" not in running_line
1063
1226
  assert "phase: Retrospective" in running_line
1064
1227
  assert "stream-derived-phase" not in running_line
1065
1228
  assert "tool: Read" in running_line
@@ -1417,6 +1580,46 @@ def test_recovery_sessions_receive_live_heartbeat_configuration(tmp_path, monkey
1417
1580
  assert config.suppress_stream_output is True
1418
1581
 
1419
1582
 
1583
+
1584
+ def test_session_summary_reports_normalized_subagents_and_child_liveness(tmp_path, capsys):
1585
+ import prizmkit_runtime.runners as runners
1586
+ from prizmkit_runtime.runner_models import SessionPaths
1587
+
1588
+ logs = tmp_path / "sessions" / "s1" / "logs"
1589
+ logs.mkdir(parents=True)
1590
+ session_log = logs / "session.log"
1591
+ progress = logs / "progress.json"
1592
+ session_log.write_text("one\ntwo\n", encoding="utf-8")
1593
+ progress.write_text(
1594
+ json.dumps({
1595
+ "subagent_spawn_count": 2,
1596
+ "active_subagent_count": 1,
1597
+ "subagent_states": [{"status": "running", "count": 1}, {"status": "completed", "count": 1}],
1598
+ "subagent_statistics": {"spawned": 2, "active": 1, "providers": ["claude"], "source": "session_log"},
1599
+ "child_total_bytes": 2048,
1600
+ "child_session_files": [{"path": "child-a"}],
1601
+ }),
1602
+ encoding="utf-8",
1603
+ )
1604
+ paths = SessionPaths(
1605
+ session_dir=logs.parent,
1606
+ prompt_path=logs.parent / "bootstrap-prompt.md",
1607
+ logs_dir=logs,
1608
+ session_log=session_log,
1609
+ progress_json=progress,
1610
+ heartbeat_json=logs / "heartbeat.json",
1611
+ session_status_json=logs / "session-status.json",
1612
+ )
1613
+ result = type("Result", (), {"exit_code": 0})()
1614
+ classification = type("Classification", (), {"session_status": "success"})()
1615
+
1616
+ runners._emit_session_summary(result, paths, classification)
1617
+
1618
+ captured = capsys.readouterr()
1619
+ assert "Subagents: spawned=2, active=1, states: running=1, completed=1 (claude; source=session.log)" in captured.err
1620
+ assert "Child log activity: 2KB across 1 files (heartbeat liveness only)" in captured.err
1621
+ assert "Subagent calls detected" not in captured.err
1622
+
1420
1623
  def test_session_live_output_does_not_forward_cli_output_without_verbose(tmp_path, capsys):
1421
1624
  from prizmkit_runtime.sessions import AISessionConfig, AISessionLauncher
1422
1625
 
@@ -1995,8 +2198,8 @@ def test_materialize_worktree_support_assets_copies_ignored_assets_without_retir
1995
2198
  subprocess.run(["git", "add", ".gitignore"], cwd=repo, check=True)
1996
2199
  subprocess.run(["git", "commit", "-m", "ignore support"], cwd=repo, check=True, stdout=subprocess.DEVNULL)
1997
2200
 
1998
- (repo / ".claude" / "agents").mkdir(parents=True)
1999
- (repo / ".claude" / "agents" / "prizm-dev-team-dev.md").write_text("dev", encoding="utf-8")
2201
+ (repo / ".claude" / "commands").mkdir(parents=True)
2202
+ (repo / ".claude" / "commands" / "prizmkit.md").write_text("skill", encoding="utf-8")
2000
2203
  (repo / ".prizmkit" / "prizm-docs").mkdir(parents=True)
2001
2204
  (repo / ".prizmkit" / "prizm-docs" / "root.prizm").write_text("PRIZM_VERSION: 1\n", encoding="utf-8")
2002
2205
  (repo / ".prizmkit" / "config.json").write_text("{}", encoding="utf-8")
@@ -2014,12 +2217,12 @@ def test_materialize_worktree_support_assets_copies_ignored_assets_without_retir
2014
2217
  )
2015
2218
  setup = ensure_linked_worktree(runtime)
2016
2219
  assert setup.ok
2017
- assert not (runtime.worktree_path / ".claude" / "agents" / "prizm-dev-team-dev.md").exists()
2220
+ assert not (runtime.worktree_path / ".claude" / "commands" / "prizmkit.md").exists()
2018
2221
 
2019
2222
  result = materialize_worktree_support_assets(runtime)
2020
2223
 
2021
2224
  assert result.ok
2022
- assert (runtime.worktree_path / ".claude" / "agents" / "prizm-dev-team-dev.md").is_file()
2225
+ assert (runtime.worktree_path / ".claude" / "commands" / "prizmkit.md").is_file()
2023
2226
  assert (runtime.worktree_path / ".prizmkit" / "prizm-docs" / "root.prizm").is_file()
2024
2227
  assert (runtime.worktree_path / ".prizmkit" / "config.json").is_file()
2025
2228
  assert (runtime.worktree_path / ".prizmkit" / "manifest.json").is_file()
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.119",
2
+ "version": "1.1.121",
3
3
  "skills": {
4
4
  "prizmkit": {
5
5
  "description": "Full-lifecycle dev toolkit. Covers spec-driven development, Prizm context docs, code quality, debugging, deployment, and knowledge management.",
@@ -65,11 +65,11 @@
65
65
  "hasScripts": false
66
66
  },
67
67
  "prizmkit-test": {
68
- "description": "Full-stack test generation and orchestration. Detects architecture, discovers/runs existing tests, analyzes coverage gaps, generates missing tests (unit/integration/E2E), outputs unified report.",
68
+ "description": "Auditable project-native test evidence with request-driven execution, runner-generated receipts, differential proof, replay, and deterministic validation.",
69
69
  "tier": "1",
70
70
  "category": "prizmkit-skill",
71
- "hasAssets": false,
72
- "hasScripts": false
71
+ "hasAssets": true,
72
+ "hasScripts": true
73
73
  },
74
74
  "feature-workflow": {
75
75
  "description": "One-stop entry point for feature development. Orchestrates feature-planner → feature-pipeline-launcher → background execution. Handles multi-feature batch development from a single request.",
@@ -47,7 +47,7 @@ If you believe the task is better suited for a different workflow, you MUST:
47
47
  - Claude Code → `CLAUDE.md`
48
48
  - CodeBuddy → `CODEBUDDY.md`
49
49
  - `all` → all three files.
50
- - Only when the manifest is missing, fall back to installed PrizmKit-owned platform files such as `.codex/agents/*.toml`, `.claude/commands/prizmkit.md`, or `.codebuddy/skills/prizmkit/SKILL.md`. Do not treat a generic `.agents/` directory as Codex.
50
+ - Only when the manifest is missing, fall back to installed PrizmKit-owned platform files such as `.claude/commands/prizmkit.md`, `.agents/skills/prizmkit/SKILL.md`, or `.codebuddy/skills/prizmkit/SKILL.md`. Do not treat a generic `.agents/` directory as Codex.
51
51
 
52
52
  **After planning is complete**, you MUST:
53
53
  1. Present the summary of captured project-level context (vision, conventions, architecture decisions, project brief)
@@ -126,7 +126,7 @@ Before questions, check optional context files (never block if absent):
126
126
  Note:
127
127
  - This skill **reads** `.prizmkit/config.json` if present.
128
128
  - This skill does **not** create `.prizmkit/config.json` directly.
129
- - Creation/update is handled by bootstrap/init flows (e.g., `prizmkit-init`, `.prizmkit/dev-pipeline/scripts/init-dev-team.py`).
129
+ - Creation/update is handled by bootstrap/init flows (e.g., `prizmkit-init`, `.prizmkit/dev-pipeline/scripts/init-change-artifact.py`).
130
130
 
131
131
  ## Interaction Style (Hard Rule)
132
132
 
@@ -29,9 +29,7 @@ After Phase 2 (Confirm constraints and tech assumptions), before Phase 3 (Captur
29
29
  - `codex` → append to `AGENTS.md`
30
30
  - `claude` → append to `CLAUDE.md`
31
31
  - `codebuddy` → append to `CODEBUDDY.md`
32
- - `all` → append to all three files. Legacy manifests may contain `both`; treat it as read-only compatibility and append to `CLAUDE.md` and `CODEBUDDY.md` only when encountered.
33
- - Only when the manifest is missing, fall back to PrizmKit-owned install artifacts: `.codex/agents/*.toml`, `.claude/commands/prizmkit.md`, `.codebuddy/skills/prizmkit/SKILL.md`.
34
- - Do not treat a generic `.agents/` directory as Codex; it may contain unrelated third-party skills.
32
+ - `all` → append to all three files.
35
33
  - If no platform can be determined, skip (no project instruction file).
36
34
 
37
35
  2. **Check for existing section** — read the target file and look for `### Architecture Decisions` heading:
@@ -1,55 +1,53 @@
1
1
  ---
2
2
  name: "prizmkit-code-review"
3
- description: "Iterative review-fix loop against spec and plan. Always uses the dedicated prizm-dev-team-reviewer agent in the active checkout with current-workspace / active-checkout / no-worktree launch; the Main Agent filters findings and applies accepted fixes directly. If the current platform cannot start an active-checkout reviewer, stop with tool incompatibility instead of falling back to Main-Agent self-review. Loops until PASS or max 3 rounds. Use after /prizmkit-implement for Full path quality gate or when the user says 'review', 'check code', 'code review', or 'is it ready to commit'. (project)"
3
+ description: "Iterative independent review-fix loop against spec, plan, workspace changes, and test evidence. Establishes a verified review snapshot using any platform-supported subagent strategy while keeping review judgment separate from Main-Agent filtering and fixes. Use after /prizmkit-implement as a Full path quality gate or when the user asks to review, check code, validate implementation, or decide whether changes are ready to commit. Loops until PASS or max 3 rounds. (project)"
4
4
  ---
5
5
 
6
6
  # PrizmKit Code Review
7
7
 
8
- An iterative review-fix loop that checks workspace changes against the task spec and plan. It separates review judgment from fix application by requiring a dedicated `prizm-dev-team-reviewer` subagent in the active checkout. Main Agent applies accepted fixes directly after filtering reviewer findings.
8
+ Run an iterative review-fix loop against the current change. Keep review judgment independent from fix application: an independent read-only Reviewer evaluates a verified snapshot, then the Main Agent filters findings and applies accepted fixes.
9
9
 
10
10
  Review modes:
11
- - `reviewer-agent-active-checkout`: required mode. Always spawn `prizm-dev-team-reviewer` in the current active checkout with no worktree or remote isolation.
11
+ - `independent-reviewer-verified-snapshot`: an independent Reviewer verified that its review snapshot is equivalent to the Main Agent's current change.
12
12
  - `not-run-no-changes`: no workspace changes were detected.
13
13
 
14
- If the platform cannot launch `prizm-dev-team-reviewer` in current-workspace / active-checkout / no-worktree mode, stop with this tool incompatibility message:
14
+ The skill defines review invariants rather than platform tool parameters. Choose any platform-supported subagent launch and snapshot transport strategy that satisfies `${SKILL_DIR}/references/reviewer-workspace-protocol.md`.
15
15
 
16
- ```text
17
- Cannot run /prizmkit-code-review because this platform cannot start prizm-dev-team-reviewer in the active checkout without worktree isolation.
18
- ```
16
+ If no independent Reviewer can receive and verify an equivalent snapshot, stop normal review and report the workspace verification failure. Do not replace the independent review with Main-Agent self-review because that would remove the separation between judgment and implementation.
19
17
 
20
18
  ### When to Use
21
19
  - After `/prizmkit-implement` as the Full path quality gate
22
- - For Fast path only when risk, scope, or user request warrants review
23
- - User says "review", "check code", "review my implementation", or "is it ready to commit"
20
+ - For Fast path when risk, scope, or the user warrants review
21
+ - When the user says "review", "check code", "review my implementation", or "is it ready to commit"
24
22
  - Before `/prizmkit-committer` when the chosen lifecycle path requires review
25
23
 
26
24
  ### When NOT to Use
27
25
  - Direct edit or low-risk Fast path where review is not required
28
- - No spec.md or plan.md exists and there is no clear task goal to review against
26
+ - No `spec.md` or `plan.md` exists and there is no clear task goal to review against
29
27
  - Trivial typo, formatting, or config-only changes that the user wants committed directly
30
28
 
31
29
  ## Input
32
30
 
33
31
  | Parameter | Required | Description |
34
32
  |-----------|----------|-------------|
35
- | `artifact_dir` | No | Directory containing `spec.md` + `plan.md`. If omitted, scan `.prizmkit/` subdirectories for the most recently modified directory with a completed `plan.md`. When invoked as a handoff step, reuse the caller's `artifact_dir` rather than re-detecting. |
33
+ | `artifact_dir` | No | Directory containing `spec.md` and `plan.md`. If omitted, scan `.prizmkit/` subdirectories for the most recently modified directory with a completed `plan.md`. When invoked as a handoff step, reuse the caller's `artifact_dir` rather than re-detecting. |
36
34
 
37
- ## Phase 0: Context Loading
35
+ ## Phase 0: Context and Snapshot
38
36
 
39
37
  1. Read `spec.md` from the artifact directory and extract goals plus acceptance criteria.
40
38
  2. Read `plan.md` from the artifact directory and extract architecture decisions plus completed tasks.
41
- 3. Read scoped `/prizmkit-test` report when present:
39
+ 3. Read a scoped `/prizmkit-test` report when present:
42
40
  - If `{artifact_dir}/test-report-path.txt` exists, read the pointed report.
43
41
  - Extract Scope, Generated / Updated Tests, In-Scope Failures, Baseline Failures, Out of Scope Gaps, Boundary Matrix / Boundary Completion Gate, and Verdict when present.
44
- - If no test report exists, pass `No scoped /prizmkit-test report found` as informational context. Do not treat missing tests as a review finding unless the current lifecycle path explicitly required testing.
42
+ - If no report exists, pass `No scoped /prizmkit-test report found` as informational context. Treat missing tests as a finding only when the lifecycle path required testing before review.
45
43
  4. Read dev rules when configured: load `.prizmkit/prizm-docs/root.prizm`, then referenced `.prizmkit/rules/<layer>-rules.md` files if any exist.
46
- 5. Capture active checkout workspace context:
47
- - `git status`
48
- - `git diff`
49
- - `git diff --cached`
50
- - full paths for untracked and renamed files
51
- - relevant root.prizm RULES and plan decisions
52
- 6. If no changes are detected, skip Phase 1 and write `review-report.md` with verdict PASS, rounds 0, and review mode `not-run-no-changes`.
44
+ 5. Capture the current workspace manifest and review payload according to `${SKILL_DIR}/references/reviewer-workspace-protocol.md`. Include:
45
+ - baseline repository and revision identity
46
+ - `git status`, `git diff`, and `git diff --cached` evidence
47
+ - staged, unstaged, untracked, deleted, and renamed path inventory
48
+ - changed content and stable content identities sufficient to detect missing, stale, or mixed snapshots
49
+ - relevant root Prizm rules and plan decisions
50
+ 6. If no changes are detected, skip Phase 1 and write `review-report.md` with verdict PASS, rounds 0, review mode `not-run-no-changes`, and snapshot verification `NOT_APPLICABLE`.
53
51
 
54
52
  ## Phase 1: Review-Fix Loop
55
53
 
@@ -69,41 +67,43 @@ python3 --version 2>/dev/null && echo "SCRIPT_MODE" || echo "TEXT_MODE"
69
67
  - `round = 1`
70
68
  - `max_rounds = 3`
71
69
  - `findings_history = []`
72
- - `review_mode = reviewer-agent-active-checkout` after confirming the dedicated reviewer can launch in the active checkout
70
+ - `review_mode = independent-reviewer-verified-snapshot` after snapshot verification succeeds
73
71
 
74
- ### Step 1: Launch Required Reviewer
72
+ ### Step 1: Establish Independent Review
75
73
 
76
- Always spawn `prizm-dev-team-reviewer` using the dedicated subagent contract:
74
+ Use the skill-owned review contract:
77
75
 
78
76
  ```yaml
79
- subagent_type: prizm-dev-team-reviewer
80
- isolation: current-workspace / active-checkout / no-worktree
77
+ prompt_reference: ${SKILL_DIR}/references/reviewer-agent-prompt.md
78
+ workspace_protocol: ${SKILL_DIR}/references/reviewer-workspace-protocol.md
79
+ reviewer_contract: independent, read-only, workspace-equivalent
81
80
  ```
82
81
 
83
- 1. Pass the active-checkout context from Phase 0 and the prompt template from `${SKILL_DIR}/references/reviewer-agent-prompt.md`.
84
- 2. The captured git diff, staged diff, untracked files, spec, plan, dev rules, and scoped test report are the primary review scope.
85
- 3. Never use `worktree`, remote isolation, copied checkouts, `Explore`, or a generic code explorer as a substitute for the PrizmKit reviewer. Do not request or create worktree isolation for this review path, including tool-created `.claude/worktrees/...` directories or pipeline-managed `.prizmkit/state/worktrees/...` directories. Pipeline `USE_WORKTREE` controls implementation infrastructure only; it does not change `/prizmkit-code-review` active-checkout review location.
86
- 4. Never perform Main-Agent self-review or fallback review; the Main Agent's job is filtering and fixing, not acting as the reviewer.
87
- 5. If the platform cannot launch the reviewer in the active checkout without worktree isolation, stop with the tool incompatibility message from this skill's introduction.
82
+ 1. Read both references and fill the Reviewer prompt with Phase 0 context plus the workspace manifest and payload.
83
+ 2. Choose a subagent launch and snapshot transport strategy supported by the current platform. Strategy choice belongs to the Main Agent because platforms expose different capabilities; do not treat a particular tool parameter, checkout layout, branch name, or transport as part of the skill contract.
84
+ 3. Require the Reviewer to verify snapshot equivalence before reviewing. Different physical paths or execution environments are acceptable when the verified review view is content-equivalent to the captured Main-Agent workspace.
85
+ 4. If the Reviewer returns `WORKSPACE_MISMATCH`, repair or replace the strategy only when equivalence can be established safely. Otherwise write a `NEEDS_FIXES` report with the verification failure unresolved and stop; do not perform Main-Agent self-review.
86
+ 5. After the Main Agent applies fixes, capture and verify a fresh snapshot for the next round because the previous snapshot is stale by definition.
88
87
 
89
88
  ### Step 2: Run Review
90
89
 
91
90
  Round context:
92
91
  - Round 1: examine all current changes comprehensively.
93
- - Round 2+: focus on whether prior fixes are correct, whether fixes introduced new issues, and whether accepted findings remain.
92
+ - Round 2+: verify prior fixes, look for regressions introduced by the fixes, and identify accepted findings that remain.
94
93
 
95
94
  Review result:
96
95
  - `PASS`: no findings.
97
96
  - `NEEDS_FIXES`: one or more findings with severity, dimension, location, problem, and suggested fix.
97
+ - `WORKSPACE_MISMATCH`: snapshot equivalence was not established; this is a review transport failure, not a code verdict.
98
98
 
99
99
  ### Step 3: Loop Exit Gate
100
100
 
101
- Call the gate only in these cases:
101
+ Call the gate only when:
102
102
 
103
103
  1. Review returned `PASS`.
104
- 2. Main Agent has filtered `NEEDS_FIXES` findings.
104
+ 2. The Main Agent has filtered `NEEDS_FIXES` findings.
105
105
 
106
- Do not call the gate for `NEEDS_FIXES` before filtering because `accepted_count` is not known yet.
106
+ Do not call the gate for `NEEDS_FIXES` before filtering because `accepted_count` is not known. Handle `WORKSPACE_MISMATCH` through Step 1 rather than passing it to the code-verdict gate.
107
107
 
108
108
  Script mode invocation:
109
109
 
@@ -111,7 +111,7 @@ Script mode invocation:
111
111
  echo '{"reviewer_result":"NEEDS_FIXES","accepted_count":2,"findings_count":3,"round":1,"findings_history":[],"max_rounds":3,"filtering_done":true}' | python3 ${SKILL_DIR}/scripts/check_loop.py
112
112
  ```
113
113
 
114
- Gate output determines whether to end the loop. If `divergenceWarning` is true, warn the user that the loop may not be converging.
114
+ The gate output determines whether to end the loop. If `divergenceWarning` is true, warn the user that the loop may not be converging.
115
115
 
116
116
  ### Text Fallback Constraints
117
117
 
@@ -128,36 +128,39 @@ When Python is unavailable, apply these rules manually:
128
128
 
129
129
  For each finding, decide whether it is reasonable:
130
130
 
131
- - Is this relevant to the current changes?
132
- - Is this a real problem rather than subjective style preference?
133
- - Would fixing this improve the code without broad out-of-scope refactoring?
134
- - Does it conflict with spec, plan, dev rules, or current test evidence?
131
+ - Is the finding relevant to the current changes?
132
+ - Is it a real problem rather than a subjective style preference?
133
+ - Would the fix improve the code without broad out-of-scope refactoring?
134
+ - Does the finding conflict with the spec, plan, dev rules, or current test evidence?
135
135
 
136
136
  Output per finding:
137
137
  - Accepted: queue for direct Main Agent fix work.
138
- - Rejected: record a short reason such as out of scope, not a defect, or too risky for current task.
138
+ - Rejected: record a short reason such as out of scope, not a defect, or too risky for the current task.
139
139
 
140
140
  After filtering, call the Loop Exit Gate. If `endLoop=true`, proceed to Phase 2.
141
141
 
142
142
  ### Step 5: Main Agent Applies Accepted Fixes
143
143
 
144
- The Main Agent applies accepted findings directly in the active checkout. Do not spawn a separate Dev Agent for fixes.
144
+ The Main Agent applies accepted findings directly in its current workspace. Keeping fix ownership with the Main Agent prevents the read-only Reviewer from becoming a second, conflicting implementation authority.
145
145
 
146
- If an accepted finding cannot be safely fixed within scope, record the reason and carry it into `review-report.md` as unresolved.
146
+ If an accepted finding cannot be fixed safely within scope, record the reason and carry the finding into `review-report.md` as unresolved.
147
147
 
148
- After fixes are complete, record results, increment the round, and return to Step 2.
148
+ After fixes are complete, record results, increment the round, capture a fresh workspace snapshot, and return to Step 1.
149
149
 
150
150
  ## Phase 2: Output
151
151
 
152
- Always write `review-report.md` to the artifact directory, including no-change PASS results. Read `${SKILL_DIR}/references/review-report-template.md` for the full output format.
152
+ Write `review-report.md` to the artifact directory, including no-change PASS and workspace-verification failure results. Read `${SKILL_DIR}/references/review-report-template.md` for the full output format.
153
153
 
154
154
  Required report fields:
155
155
  - Verdict: `PASS` or `NEEDS_FIXES`
156
- - Review Mode: `reviewer-agent-active-checkout` or `not-run-no-changes`
156
+ - Review Mode: `independent-reviewer-verified-snapshot` or `not-run-no-changes`
157
+ - Reviewer Strategy: concise strategy summary without relying on platform-specific parameter names
158
+ - Snapshot Verification: `VERIFIED`, `FAILED`, or `NOT_APPLICABLE`
159
+ - Snapshot Identity: manifest identity or failure reason
157
160
  - Rounds and total findings
158
161
  - Fixed, rejected, and unresolved findings
159
162
  - Final summary
160
163
 
161
164
  Completion summary:
162
165
  - `PASS`: hand off to `/prizmkit-retrospective` when docs or durable knowledge changed, otherwise `/prizmkit-committer`.
163
- - `NEEDS_FIXES`: inform the caller of remaining unresolved findings.
166
+ - `NEEDS_FIXES`: inform the caller of unresolved code findings or snapshot-verification blockers.
@@ -1,13 +1,16 @@
1
1
  # Review Report Output Template
2
2
 
3
- Used in Phase 2 of `/prizmkit-code-review`. Always write `review-report.md` to the artifact directory using this format.
3
+ Used in Phase 2 of `/prizmkit-code-review`. Write `review-report.md` to the artifact directory using this format.
4
4
 
5
5
  ```markdown
6
6
  # Review Report
7
7
 
8
8
  ## Verdict: <PASS|NEEDS_FIXES>
9
- ## Review Mode: <reviewer-agent-active-checkout|not-run-no-changes>
10
- ## Rounds: <number of review rounds completed; use 0 for no-change PASS>
9
+ ## Review Mode: <independent-reviewer-verified-snapshot|not-run-no-changes>
10
+ ## Reviewer Strategy: <platform-selected strategy summary|not-applicable>
11
+ ## Snapshot Verification: <VERIFIED|FAILED|NOT_APPLICABLE>
12
+ ## Snapshot Identity: <manifest identity or failure reason>
13
+ ## Rounds: <number of completed review rounds; use 0 for no-change PASS or pre-review snapshot failure>
11
14
  ## Total findings: <total> → Fixed: <fixed>, Rejected: <rejected>, Unresolved: <unresolved>
12
15
 
13
16
  ## Round <N>
@@ -15,18 +18,20 @@ Findings: <count> | Accepted: <count>, Rejected: <count>
15
18
 
16
19
  ### Finding <N>: <short title>
17
20
  - Severity: <high|medium|low>
18
- - Dimension: <goal-alignment|defect|completeness|consistency|security|rules-compliance>
21
+ - Dimension: <goal-alignment|defect|completeness|consistency|security|test-quality|rules-compliance>
19
22
  - Location: <filepath:line or project-level>
20
23
  - Problem: <what was wrong and why it mattered>
21
24
  - Status: <fixed (round N)|rejected — reason|unresolved — reason>
22
25
 
23
26
  ## Final Summary
24
- <One to three sentences summarizing the review outcome, including no-change PASS when applicable.>
27
+ <One to three sentences summarizing the review outcome, snapshot verification, and any remaining blocker.>
25
28
  ```
26
29
 
27
- For `PASS` with no findings, write `Total findings: 0 → Fixed: 0, Rejected: 0, Unresolved: 0` and `## Round 0: PASS — no workspace changes to review` or `## Round N: PASS — no issues found`.
30
+ For `PASS` with no findings, write `Total findings: 0 → Fixed: 0, Rejected: 0, Unresolved: 0` and either `## Round 0: PASS — no workspace changes to review` or `## Round N: PASS — no issues found`.
31
+
32
+ For snapshot verification failure, use verdict `NEEDS_FIXES`, snapshot verification `FAILED`, and record the mismatch as an unresolved review blocker rather than an ordinary code finding.
28
33
 
29
34
  ## Verdict Rules
30
35
 
31
- - `PASS`: Reviewer returned no findings, no workspace changes existed, or all remaining findings were rejected as unreasonable.
32
- - `NEEDS_FIXES`: Max rounds completed but accepted findings remain unresolved.
36
+ - `PASS`: Reviewer returned no findings from a verified snapshot, no workspace changes existed, or all findings from a verified snapshot were rejected as unreasonable.
37
+ - `NEEDS_FIXES`: Max rounds completed with accepted findings unresolved, or no independent Reviewer could verify an equivalent current snapshot.