prizmkit 1.1.159 → 1.1.161
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.
- package/bundled/VERSION.json +3 -3
- package/bundled/adapters/codebuddy/settings-adapter.js +76 -25
- package/bundled/dev-pipeline/prizmkit_runtime/gitops.py +9 -2
- package/bundled/dev-pipeline/prizmkit_runtime/heartbeat.py +9 -6
- package/bundled/dev-pipeline/prizmkit_runtime/runtime_commit.py +155 -93
- package/bundled/dev-pipeline/templates/bootstrap-prompt.md +1 -1
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +2 -2
- package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +1 -1
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +1 -1
- package/bundled/dev-pipeline/templates/sections/runtime-commit-handoff.md +9 -15
- package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +9 -5
- package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +4 -2
- package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +4 -2
- package/bundled/dev-pipeline/tests/test_runtime_commit.py +228 -69
- package/bundled/dev-pipeline/tests/test_unified_cli.py +182 -10
- package/bundled/rules/prizm/prizm-commit-workflow.md +14 -7
- package/bundled/rules/prizm/prizm-documentation.md +24 -65
- package/bundled/rules/prizm/prizm-progressive-loading.md +9 -8
- package/bundled/skills/_metadata.json +1 -1
- package/bundled/skills/prizmkit-code-review/SKILL.md +5 -5
- package/bundled/skills/prizmkit-code-review/references/independent-code-review.md +4 -5
- package/bundled/skills/prizmkit-code-review/references/review-report-template.md +4 -6
- package/bundled/skills/prizmkit-code-review/scripts/render_review_report.py +1 -4
- package/bundled/skills/prizmkit-committer/SKILL.md +50 -59
- package/bundled/skills/prizmkit-deploy/SKILL.md +172 -198
- package/bundled/skills/prizmkit-deploy/references/capability-contract.md +137 -0
- package/bundled/skills/prizmkit-deploy/references/deploy-record-schema.json +1053 -0
- package/bundled/skills/prizmkit-deploy/references/deployment-declaration-schema.json +291 -0
- package/bundled/skills/prizmkit-deploy/references/legacy-migration.md +90 -0
- package/bundled/skills/prizmkit-deploy/references/policy-and-execution.md +170 -0
- package/bundled/skills/prizmkit-deploy/references/real-resource-test-policy.md +73 -0
- package/bundled/skills/prizmkit-deploy/references/verification-and-recovery.md +164 -0
- package/bundled/skills/prizmkit-deploy/scripts/validate-deploy-artifact.py +371 -0
- package/bundled/skills/prizmkit-implement/SKILL.md +2 -2
- package/bundled/skills/prizmkit-init/SKILL.md +17 -17
- package/bundled/skills/prizmkit-init/references/update-supplement.md +5 -5
- package/bundled/skills/prizmkit-prizm-docs/SKILL.md +17 -11
- package/bundled/skills/prizmkit-prizm-docs/assets/prizm-docs-format.md +95 -155
- package/bundled/skills/prizmkit-prizm-docs/references/op-init.md +6 -5
- package/bundled/skills/prizmkit-prizm-docs/references/op-rebuild.md +4 -2
- package/bundled/skills/prizmkit-prizm-docs/references/op-status.md +9 -10
- package/bundled/skills/prizmkit-prizm-docs/references/op-update.md +6 -5
- package/bundled/skills/prizmkit-prizm-docs/references/op-validate.md +13 -12
- package/bundled/skills/prizmkit-retrospective/SKILL.md +3 -3
- package/bundled/skills/prizmkit-test/SKILL.md +28 -15
- package/bundled/skills/prizmkit-test/references/boundary-contract-and-test-double-guidance.md +8 -4
- package/bundled/skills/prizmkit-test/references/independent-test-review.md +7 -3
- package/bundled/skills/prizmkit-test/references/test-coverage-model.md +34 -11
- package/bundled/skills/prizmkit-test/references/test-report-template.md +33 -11
- package/bundled/skills/prizmkit-workflow/SKILL.md +4 -8
- package/bundled/skills/prizmkit-workflow/references/workflow-state-protocol.md +10 -9
- package/bundled/templates/hooks/commit-intent-status.py +9 -41
- package/bundled/templates/hooks/commit-intent.json +3 -3
- package/bundled/templates/hooks/diff-prizm-docs.py +3 -1
- package/bundled/templates/hooks/prizm-pre-commit.py +32 -6
- package/bundled/templates/hooks/run-python-hook.cjs +44 -0
- package/bundled/templates/hooks/validate-prizm-docs.py +399 -173
- package/bundled/templates/project-memory-template.md +19 -19
- package/package.json +1 -1
- package/src/clean.js +6 -7
- package/src/gitignore-template.js +8 -12
- package/src/scaffold.js +125 -71
- package/bundled/skills/prizmkit-deploy/assets/deploy-document-template.md +0 -89
- package/bundled/skills/prizmkit-deploy/references/ci-cd-workflows.md +0 -145
- package/bundled/skills/prizmkit-deploy/references/cloud-platform-deploy.md +0 -109
- package/bundled/skills/prizmkit-deploy/references/data-safety-examples.md +0 -120
- package/bundled/skills/prizmkit-deploy/references/database-setup.md +0 -65
- package/bundled/skills/prizmkit-deploy/references/deploy-config-schema.md +0 -150
- package/bundled/skills/prizmkit-deploy/references/deploy-history-schema.md +0 -78
- package/bundled/skills/prizmkit-deploy/references/deploy-metadata-schema.json +0 -49
- package/bundled/skills/prizmkit-deploy/references/deployment-modes.md +0 -50
- package/bundled/skills/prizmkit-deploy/references/direct-upload.md +0 -26
- package/bundled/skills/prizmkit-deploy/references/dns-setup.md +0 -42
- package/bundled/skills/prizmkit-deploy/references/docker-deploy.md +0 -31
- package/bundled/skills/prizmkit-deploy/references/firewall-setup.md +0 -37
- package/bundled/skills/prizmkit-deploy/references/live-validation-notes.md +0 -21
- package/bundled/skills/prizmkit-deploy/references/nginx-blue-green.md +0 -59
- package/bundled/skills/prizmkit-deploy/references/pending-input-schema.json +0 -164
- package/bundled/skills/prizmkit-deploy/references/ssh-adapter-flow.md +0 -221
- package/bundled/skills/prizmkit-deploy/references/ssh-bootstrap-flow.md +0 -49
- package/bundled/skills/prizmkit-deploy/references/ssh-execution-flow.md +0 -41
- package/bundled/skills/prizmkit-deploy/references/ssh-takeover.md +0 -20
- package/bundled/skills/prizmkit-deploy/references/ssl-setup.md +0 -56
|
@@ -1313,8 +1313,9 @@ def test_headless_review_guidance_maps_stage_local_skill_result():
|
|
|
1313
1313
|
|
|
1314
1314
|
skill_text = skill_path.read_text(encoding="utf-8")
|
|
1315
1315
|
assert "the staged diff, and the unstaged diff" in skill_text
|
|
1316
|
-
assert "untracked, deleted, and
|
|
1317
|
-
assert "
|
|
1316
|
+
assert "non-ignored untracked, deleted, renamed, and copied paths" in skill_text
|
|
1317
|
+
assert "Do not maintain excluded-path metadata" in skill_text
|
|
1318
|
+
assert "complete current Git-visible workspace" in skill_text
|
|
1318
1319
|
assert "accepted = 0" in skill_text
|
|
1319
1320
|
assert "ten completed review rounds" in skill_text
|
|
1320
1321
|
assert "## Phase 3: Independent Code Review" in skill_text
|
|
@@ -2391,7 +2392,7 @@ def test_heartbeat_observation_stale_accumulates_by_elapsed_time_and_resets_on_p
|
|
|
2391
2392
|
session_log = tmp_path / "session.log"
|
|
2392
2393
|
progress = tmp_path / "progress.json"
|
|
2393
2394
|
session_log.write_text("initial\n", encoding="utf-8")
|
|
2394
|
-
progress.write_text('{"current_phase":"plan","current_tool":
|
|
2395
|
+
progress.write_text('{"current_phase":"plan","current_tool":null,"message_count":1,"total_tool_calls":1}\n', encoding="utf-8")
|
|
2395
2396
|
config = HeartbeatConfig(
|
|
2396
2397
|
heartbeat_file=tmp_path / "heartbeat.json",
|
|
2397
2398
|
session_log=session_log,
|
|
@@ -2419,6 +2420,72 @@ def test_heartbeat_observation_stale_accumulates_by_elapsed_time_and_resets_on_p
|
|
|
2419
2420
|
assert reset.last_seen_epoch == 1095.0
|
|
2420
2421
|
|
|
2421
2422
|
|
|
2423
|
+
def test_heartbeat_observation_active_tool_resets_stale_until_tool_clears(tmp_path, monkeypatch):
|
|
2424
|
+
import prizmkit_runtime.heartbeat as heartbeat
|
|
2425
|
+
from prizmkit_runtime.heartbeat import HeartbeatConfig, observe_heartbeat_state
|
|
2426
|
+
|
|
2427
|
+
progress = tmp_path / "progress.json"
|
|
2428
|
+
progress.write_text(
|
|
2429
|
+
'{"current_tool":"bash","message_count":1,"total_tool_calls":1}\n',
|
|
2430
|
+
encoding="utf-8",
|
|
2431
|
+
)
|
|
2432
|
+
config = HeartbeatConfig(
|
|
2433
|
+
heartbeat_file=tmp_path / "heartbeat.json",
|
|
2434
|
+
progress_file=progress,
|
|
2435
|
+
stale_after_seconds=60,
|
|
2436
|
+
)
|
|
2437
|
+
ticks = iter([1000.0, 1100.0, 1200.0, 1205.0, 1230.0])
|
|
2438
|
+
monkeypatch.setattr(heartbeat.time, "time", lambda: next(ticks))
|
|
2439
|
+
|
|
2440
|
+
first = observe_heartbeat_state(config)
|
|
2441
|
+
active = observe_heartbeat_state(config, first)
|
|
2442
|
+
still_active = observe_heartbeat_state(config, active)
|
|
2443
|
+
progress.write_text(
|
|
2444
|
+
'{"current_tool":null,"message_count":1,"total_tool_calls":1}\n',
|
|
2445
|
+
encoding="utf-8",
|
|
2446
|
+
)
|
|
2447
|
+
tool_finished = observe_heartbeat_state(config, still_active)
|
|
2448
|
+
idle = observe_heartbeat_state(config, tool_finished)
|
|
2449
|
+
|
|
2450
|
+
assert active.details == "progress"
|
|
2451
|
+
assert active.stale_seconds == 0
|
|
2452
|
+
assert active.last_seen_epoch == 1100.0
|
|
2453
|
+
assert still_active.details == "progress"
|
|
2454
|
+
assert still_active.stale_seconds == 0
|
|
2455
|
+
assert still_active.last_seen_epoch == 1200.0
|
|
2456
|
+
assert tool_finished.details == "progress"
|
|
2457
|
+
assert tool_finished.stale_seconds == 0
|
|
2458
|
+
assert tool_finished.last_seen_epoch == 1205.0
|
|
2459
|
+
assert idle.details == "no progress"
|
|
2460
|
+
assert idle.stale_seconds == 25.0
|
|
2461
|
+
|
|
2462
|
+
|
|
2463
|
+
@pytest.mark.parametrize("current_tool", [None, "", " ", 0, ["bash"]])
|
|
2464
|
+
def test_heartbeat_observation_rejects_inactive_or_malformed_tool_values(
|
|
2465
|
+
tmp_path,
|
|
2466
|
+
monkeypatch,
|
|
2467
|
+
current_tool,
|
|
2468
|
+
):
|
|
2469
|
+
import prizmkit_runtime.heartbeat as heartbeat
|
|
2470
|
+
from prizmkit_runtime.heartbeat import HeartbeatConfig, observe_heartbeat_state
|
|
2471
|
+
|
|
2472
|
+
progress = tmp_path / "progress.json"
|
|
2473
|
+
progress.write_text(json.dumps({"current_tool": current_tool}), encoding="utf-8")
|
|
2474
|
+
config = HeartbeatConfig(
|
|
2475
|
+
heartbeat_file=tmp_path / "heartbeat.json",
|
|
2476
|
+
progress_file=progress,
|
|
2477
|
+
stale_after_seconds=60,
|
|
2478
|
+
)
|
|
2479
|
+
ticks = iter([1000.0, 1070.0])
|
|
2480
|
+
monkeypatch.setattr(heartbeat.time, "time", lambda: next(ticks))
|
|
2481
|
+
|
|
2482
|
+
first = observe_heartbeat_state(config)
|
|
2483
|
+
stale = observe_heartbeat_state(config, first)
|
|
2484
|
+
|
|
2485
|
+
assert stale.details == "no progress"
|
|
2486
|
+
assert stale.stale is True
|
|
2487
|
+
assert stale.stale_seconds == 70.0
|
|
2488
|
+
|
|
2422
2489
|
|
|
2423
2490
|
def test_heartbeat_state_tracks_progress_json_child_activity(tmp_path, monkeypatch):
|
|
2424
2491
|
import prizmkit_runtime.heartbeat as heartbeat
|
|
@@ -2495,6 +2562,104 @@ def test_heartbeat_monitor_stale_kill_uses_elapsed_no_progress_threshold(tmp_pat
|
|
|
2495
2562
|
assert marker_data["stale_seconds"] >= 0
|
|
2496
2563
|
|
|
2497
2564
|
|
|
2565
|
+
def test_heartbeat_monitor_active_tool_defers_stale_kill_until_tool_clears(tmp_path):
|
|
2566
|
+
from prizmkit_runtime.heartbeat import HeartbeatConfig, HeartbeatMonitor
|
|
2567
|
+
from prizmkit_runtime.processes import ProcessSpec, is_process_running, launch_process
|
|
2568
|
+
|
|
2569
|
+
sleeper = tmp_path / "active_tool_sleep.py"
|
|
2570
|
+
sleeper.write_text("import time\ntime.sleep(5)\n", encoding="utf-8")
|
|
2571
|
+
progress = tmp_path / "progress.json"
|
|
2572
|
+
progress.write_text('{"current_tool":"bash"}\n', encoding="utf-8")
|
|
2573
|
+
handle = launch_process(ProcessSpec(command=(sys.executable, str(sleeper)), cwd=tmp_path))
|
|
2574
|
+
monitor = HeartbeatMonitor(
|
|
2575
|
+
handle,
|
|
2576
|
+
HeartbeatConfig(
|
|
2577
|
+
heartbeat_file=tmp_path / "heartbeat.json",
|
|
2578
|
+
session_log=tmp_path / "session.log",
|
|
2579
|
+
progress_file=progress,
|
|
2580
|
+
marker_dir=tmp_path,
|
|
2581
|
+
interval_seconds=0.05,
|
|
2582
|
+
stale_after_seconds=0.1,
|
|
2583
|
+
kill_after_seconds=0.2,
|
|
2584
|
+
grace_seconds=0.1,
|
|
2585
|
+
),
|
|
2586
|
+
)
|
|
2587
|
+
monitor.start()
|
|
2588
|
+
|
|
2589
|
+
time.sleep(0.5)
|
|
2590
|
+
assert is_process_running(handle)
|
|
2591
|
+
assert not (tmp_path / "stale-kill.json").exists()
|
|
2592
|
+
|
|
2593
|
+
progress.write_text('{"current_tool":null}\n', encoding="utf-8")
|
|
2594
|
+
deadline = time.time() + 3
|
|
2595
|
+
while time.time() < deadline and not (tmp_path / "stale-kill.json").exists():
|
|
2596
|
+
time.sleep(0.05)
|
|
2597
|
+
result = monitor.stop()
|
|
2598
|
+
|
|
2599
|
+
marker = json.loads((tmp_path / "stale-kill.json").read_text(encoding="utf-8"))
|
|
2600
|
+
assert result.killed is True
|
|
2601
|
+
assert result.reason == "stale_session"
|
|
2602
|
+
assert marker["reason"] == "stale_session"
|
|
2603
|
+
|
|
2604
|
+
|
|
2605
|
+
def test_pi_session_active_tool_stream_survives_stale_threshold(tmp_path, monkeypatch):
|
|
2606
|
+
import prizmkit_runtime.sessions as sessions
|
|
2607
|
+
from prizmkit_runtime.sessions import AISessionConfig, AISessionLauncher
|
|
2608
|
+
|
|
2609
|
+
parser_classes = sessions._load_stream_parser_classes()
|
|
2610
|
+
monkeypatch.setattr(sessions, "_load_stream_parser_classes", lambda: parser_classes)
|
|
2611
|
+
|
|
2612
|
+
fake_cli = tmp_path / "pi_active_tool_cli.py"
|
|
2613
|
+
fake_cli.write_text(
|
|
2614
|
+
"#!/usr/bin/env python3\n"
|
|
2615
|
+
"import json, sys, time\n"
|
|
2616
|
+
"_prompt = sys.stdin.read(5)\n"
|
|
2617
|
+
"for event in [\n"
|
|
2618
|
+
" {'type':'session','id':'active-tool-session'},\n"
|
|
2619
|
+
" {'type':'agent_start'},\n"
|
|
2620
|
+
" {'type':'turn_start'},\n"
|
|
2621
|
+
" {'type':'tool_execution_start','toolCallId':'call-1','toolName':'long-running-tool','args':{}},\n"
|
|
2622
|
+
"]:\n"
|
|
2623
|
+
" print(json.dumps(event), flush=True)\n"
|
|
2624
|
+
"time.sleep(3.0)\n"
|
|
2625
|
+
"for event in [\n"
|
|
2626
|
+
" {'type':'tool_execution_end','toolCallId':'call-1','toolName':'long-running-tool','result':{'content':[]},'isError':False},\n"
|
|
2627
|
+
" {'type':'message_end','message':{'role':'assistant','content':[{'type':'text','text':'done'}],'stopReason':'stop'}},\n"
|
|
2628
|
+
" {'type':'agent_end','willRetry':False,'messages':[{'role':'assistant','content':[{'type':'text','text':'done'}],'stopReason':'stop'}]},\n"
|
|
2629
|
+
"]:\n"
|
|
2630
|
+
" print(json.dumps(event), flush=True)\n",
|
|
2631
|
+
encoding="utf-8",
|
|
2632
|
+
)
|
|
2633
|
+
fake_cli.chmod(0o755)
|
|
2634
|
+
prompt = tmp_path / "prompt.md"
|
|
2635
|
+
prompt.write_text("hello", encoding="utf-8")
|
|
2636
|
+
session_log = tmp_path / "state" / "sessions" / "active-tool" / "logs" / "session.log"
|
|
2637
|
+
progress = session_log.with_name("progress.json")
|
|
2638
|
+
|
|
2639
|
+
result = AISessionLauncher(
|
|
2640
|
+
AISessionConfig(
|
|
2641
|
+
cli_command=str(fake_cli),
|
|
2642
|
+
platform="pi",
|
|
2643
|
+
model=None,
|
|
2644
|
+
prompt_path=prompt,
|
|
2645
|
+
cwd=tmp_path,
|
|
2646
|
+
log_path=session_log,
|
|
2647
|
+
progress_path=progress,
|
|
2648
|
+
heartbeat_path=session_log.with_name("heartbeat.json"),
|
|
2649
|
+
stale_kill_threshold_seconds=1.5,
|
|
2650
|
+
heartbeat_stale_threshold_seconds=1.0,
|
|
2651
|
+
stale_kill_grace_seconds=0.1,
|
|
2652
|
+
live_progress_interval_seconds=0.05,
|
|
2653
|
+
)
|
|
2654
|
+
).run()
|
|
2655
|
+
|
|
2656
|
+
final_progress = json.loads(progress.read_text(encoding="utf-8"))
|
|
2657
|
+
assert result.exit_code == 0
|
|
2658
|
+
assert result.termination_reason is None
|
|
2659
|
+
assert final_progress["current_tool"] is None
|
|
2660
|
+
assert not (session_log.parent / "stale-kill.json").exists()
|
|
2661
|
+
|
|
2662
|
+
|
|
2498
2663
|
def test_stale_marker_preserves_subsecond_threshold(tmp_path):
|
|
2499
2664
|
from prizmkit_runtime.heartbeat import write_stale_marker
|
|
2500
2665
|
|
|
@@ -2913,7 +3078,10 @@ def test_heartbeat_fatal_error_writes_shell_compatible_markers(tmp_path):
|
|
|
2913
3078
|
sleeper = tmp_path / "fatal_sleep.py"
|
|
2914
3079
|
sleeper.write_text("import time\ntime.sleep(5)\n", encoding="utf-8")
|
|
2915
3080
|
progress = tmp_path / "progress.json"
|
|
2916
|
-
progress.write_text(
|
|
3081
|
+
progress.write_text(
|
|
3082
|
+
'{"current_tool":"bash","fatal_error_code":"context_overflow"}\n',
|
|
3083
|
+
encoding="utf-8",
|
|
3084
|
+
)
|
|
2917
3085
|
handle = launch_process(ProcessSpec(command=(sys.executable, str(sleeper)), cwd=tmp_path))
|
|
2918
3086
|
monitor = HeartbeatMonitor(
|
|
2919
3087
|
handle,
|
|
@@ -3621,8 +3789,11 @@ def test_git_status_safe_ignores_worktree_support_assets(monkeypatch, tmp_path):
|
|
|
3621
3789
|
joined = " ".join(status_args)
|
|
3622
3790
|
assert ":(top,exclude).prizmkit-worktree" in status_args
|
|
3623
3791
|
assert ":(top,exclude).claude" in status_args
|
|
3624
|
-
assert ":(top,exclude).prizmkit" in status_args
|
|
3625
|
-
assert ":(top,exclude,glob).prizmkit/**" in status_args
|
|
3792
|
+
assert ":(top,exclude).prizmkit" not in status_args
|
|
3793
|
+
assert ":(top,exclude,glob).prizmkit/**" not in status_args
|
|
3794
|
+
assert ":(top,exclude,glob).prizmkit/dev-pipeline/**" in status_args
|
|
3795
|
+
assert ":(top,exclude,glob).prizmkit/state/**" in status_args
|
|
3796
|
+
assert ":(top,exclude,glob).prizmkit/specs/**/workflow-checkpoint.json" in status_args
|
|
3626
3797
|
assert all(exclude in status_args for exclude in HIDDEN_TOOL_WORKTREE_EXCLUDES)
|
|
3627
3798
|
assert ".prizmkit-worktree" in joined
|
|
3628
3799
|
|
|
@@ -3883,7 +4054,7 @@ def test_materialize_worktree_support_assets_copies_ignored_assets_without_retir
|
|
|
3883
4054
|
assert guarded_worktree_remove(runtime, delete_branch=False).ok
|
|
3884
4055
|
|
|
3885
4056
|
|
|
3886
|
-
def
|
|
4057
|
+
def test_linked_worktree_rejects_dirty_tracked_prizmkit_config(tmp_path):
|
|
3887
4058
|
from prizmkit_runtime.gitops import (
|
|
3888
4059
|
BranchContext,
|
|
3889
4060
|
WorktreePolicy,
|
|
@@ -3930,10 +4101,11 @@ def test_linked_worktree_fast_forwards_with_dirty_prizmkit_internal_state(tmp_pa
|
|
|
3930
4101
|
assert branch_fast_forward_possible(repo, runtime.context) is True
|
|
3931
4102
|
result = merge_linked_worktree(runtime)
|
|
3932
4103
|
|
|
3933
|
-
assert result.ok is
|
|
3934
|
-
assert
|
|
3935
|
-
assert (repo / "feature.txt").
|
|
4104
|
+
assert result.ok is False
|
|
4105
|
+
assert result.reason == "dirty_task_checkout"
|
|
4106
|
+
assert not (repo / "feature.txt").exists()
|
|
3936
4107
|
assert json.loads(worktree_config.read_text(encoding="utf-8"))["mode"] == "session-local"
|
|
4108
|
+
worktree_config.write_text('{"mode":"base"}\n', encoding="utf-8")
|
|
3937
4109
|
assert guarded_worktree_remove(runtime, delete_branch=True).ok
|
|
3938
4110
|
|
|
3939
4111
|
|
|
@@ -2,10 +2,17 @@
|
|
|
2
2
|
description: "PrizmKit commit workflow rules"
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
# Commit Workflow
|
|
6
|
+
|
|
7
|
+
Do not commit after implementation alone.
|
|
8
|
+
|
|
9
|
+
For a formal requirement:
|
|
10
|
+
1. Complete `/prizmkit-retrospective` after Test and before Committer; it synchronizes durable documentation or records `NO_DOC_CHANGE` but never stages or commits.
|
|
11
|
+
2. Use `/prizmkit-committer` for one local commit operation and one truthful Conventional Commit message.
|
|
12
|
+
3. The commit candidate is the complete current Git-visible workspace: staged, unstaged, added, deleted, renamed, copied, and non-ignored untracked content, regardless of when or where each valid change originated.
|
|
13
|
+
4. Final Code Review and Test authority must cover every behavior-affecting candidate. Committer inspects the complete final workspace, blocks stale or unsafe evidence, previews every visible change, and waits for explicit interactive confirmation.
|
|
14
|
+
5. Interactive Committer stages the confirmed complete workspace. Headless preparation writes a schema-v2 pathless request, and Python Runtime re-enumerates and stages the complete validated workspace after `COMMIT_PENDING`.
|
|
15
|
+
6. Ignored paths remain local, never block, and are never force-added. Path provenance or namespace alone never admits or excludes content.
|
|
16
|
+
7. Merge conflicts, Secrets, sensitive local content, known incorrect or incoherent changes, and unverifiable content still block. Only the exact active interactive workflow state or Runtime request/checkpoint and post-commit receipt writes may remain outside the snapshot because their causal finalization follows the commit.
|
|
17
|
+
8. Runtime verifies the base, parent, message, non-empty commit, recovery receipt, and checkpoint finalization before integration.
|
|
18
|
+
9. Remote publication and deployment remain separate.
|
|
@@ -11,68 +11,27 @@ globs:
|
|
|
11
11
|
- "**/*.java"
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
-
WHEN TO UPDATE
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
- L1
|
|
31
|
-
- L2
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
|
|
39
|
-
REQUIRED FIELDS PER LEVEL:
|
|
40
|
-
|
|
41
|
-
L0 root.prizm:
|
|
42
|
-
- PRIZM_VERSION
|
|
43
|
-
- PROJECT
|
|
44
|
-
- LANG
|
|
45
|
-
- MODULE_INDEX or MODULE_GROUPS (with -> pointers to L1 files)
|
|
46
|
-
- RULES (top-level project rules)
|
|
47
|
-
|
|
48
|
-
L1 module.prizm (structural index only):
|
|
49
|
-
- MODULE
|
|
50
|
-
- FILES
|
|
51
|
-
- RESPONSIBILITY
|
|
52
|
-
- DEPENDENCIES
|
|
53
|
-
- L1 does NOT contain: INTERFACES, DATA_FLOW, TRAPS, DECISIONS (those belong in L2)
|
|
54
|
-
|
|
55
|
-
L2 detail.prizm:
|
|
56
|
-
- MODULE
|
|
57
|
-
- FILES
|
|
58
|
-
- KEY_FILES
|
|
59
|
-
- DEPENDENCIES
|
|
60
|
-
- INTERFACES
|
|
61
|
-
- TRAPS (with severity prefix: [CRITICAL], [HIGH], or [LOW])
|
|
62
|
-
|
|
63
|
-
L2 GENERATION TEMPLATE (use when AI first touches a sub-module with no L2 doc):
|
|
64
|
-
|
|
65
|
-
MODULE: <path>
|
|
66
|
-
FILES: <comma-separated file list>
|
|
67
|
-
RESPONSIBILITY: <one-line>
|
|
68
|
-
KEY_FILES:
|
|
69
|
-
- <file>: <role, line count, complexity note>
|
|
70
|
-
DEPENDENCIES:
|
|
71
|
-
- uses: <lib>: <why>
|
|
72
|
-
- imports: <module>: <what>
|
|
73
|
-
INTERFACES:
|
|
74
|
-
- <exported function/class>: <signature and purpose>
|
|
75
|
-
TRAPS:
|
|
76
|
-
- [LOW] <gotcha, race condition, or non-obvious coupling> | FIX: <approach>
|
|
77
|
-
|
|
78
|
-
TRAPS is critical — always record gotchas, race conditions, non-obvious behavior, and surprising coupling between modules. Every TRAP must have a severity prefix ([CRITICAL], [HIGH], or [LOW]).
|
|
14
|
+
WHEN TO UPDATE `.prizmkit/prizm-docs/`:
|
|
15
|
+
- Use `/prizmkit-retrospective` after a validated change affects structure, interfaces, dependencies, behavior, or durable TRAPS/RULES/DECISIONS.
|
|
16
|
+
- Skip documentation writes when no current durable non-obvious fact passes the Value Gate.
|
|
17
|
+
- Before source modification, read exact root, the relevant direct-child L1, the complete relevant nested L2, and complete resolving pointer documents.
|
|
18
|
+
- If relevant L2 is absent, inspect bounded relevant source without creating a placeholder.
|
|
19
|
+
|
|
20
|
+
FRAMEWORK DIRECTORY AND GIT POLICY:
|
|
21
|
+
- `.prizmkit/**` is framework-owned capability/artifact space; an owner may read/write only its managed paths.
|
|
22
|
+
- The project decides whether framework paths are ignored, untracked, or tracked. Do not add, remove, force-add, stage, commit, or interpret `.gitignore` entries as part of documentation maintenance.
|
|
23
|
+
- Validation/generation/reconciliation behavior is identical across tracking states apart from ordinary Git visibility; Git history is not required.
|
|
24
|
+
|
|
25
|
+
FORMAT RULES:
|
|
26
|
+
- New roots use `PRIZM_VERSION: 4`.
|
|
27
|
+
- Only exact `.prizmkit/prizm-docs/root.prizm` is L0; direct `.prizm` children other than root are L1; every nested `.prizm` document is L2.
|
|
28
|
+
- ALL CAPS section headers, KEY: value pairs, and dash-prefixed lists only.
|
|
29
|
+
- PROHIBITED: CHANGELOG sections/files, prose paragraphs, markdown headers, code blocks, horizontal rules, UPDATED/date metadata, feature/bug/refactor/task/session/run/pipeline/workflow IDs, branch names, absolute worktree paths, and `.prizmkit/specs` / `.prizmkit/dev-pipeline` artifact paths.
|
|
30
|
+
- L1 is structural and must not contain INTERFACES, DATA_FLOW, TRAPS, DECISIONS, CONCERN, or full RULES.
|
|
31
|
+
- Mirrored L2 requires MODULE, FILES, RESPONSIBILITY, INTERFACES, KEY_FILES, DEPENDENCIES, and TRAPS. Semantic L2 also requires deterministic CONCERN/SLUG, DATA_FLOW, RULES, DECISIONS, exact parent DETAILS pointer, and non-overlapping FILES ownership.
|
|
32
|
+
|
|
33
|
+
CAPACITY AND WRITES:
|
|
34
|
+
- Raw UTF-8 hard limits: L0 4096B, L1 4096B, L2 5120B. Existing warning bands remain advisory; hard-limit violations fail.
|
|
35
|
+
- Apply Value/Cleanup gates and protect still-valid contracts, constraints, dependencies, traps, decisions, side effects, and safety/integrity rules.
|
|
36
|
+
- Build complete candidates and write bottom-up. Skip byte-identical replacements, re-read actual bytes/pointers, and restore exact prior bytes or remove invalid new targets after any failed post-write check.
|
|
37
|
+
- Never add L3, a documentation state machine, task-named shards, or placeholder L2 documents.
|
|
@@ -3,11 +3,12 @@ description: "PrizmKit progressive context loading protocol"
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
This project uses PrizmKit's progressive loading protocol:
|
|
6
|
-
- ON SESSION START: Read `.prizmkit/prizm-docs/root.prizm` (L0
|
|
7
|
-
- ON
|
|
8
|
-
- ON
|
|
9
|
-
-
|
|
10
|
-
- NEVER load all
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
6
|
+
- ON SESSION START: Read exact `.prizmkit/prizm-docs/root.prizm` (L0 project map) when it exists.
|
|
7
|
+
- ON TASK: Read only relevant direct-child L1 documents (`.prizmkit/prizm-docs/<module>.prizm`) selected through root MODULE_INDEX/MODULE_GROUPS pointers.
|
|
8
|
+
- ON FILE EDIT: Read the complete relevant nested L2 document and complete parent/child documents needed to resolve its SUBDIRS or DETAILS pointer before modification. Grep-only fragments are insufficient modification context.
|
|
9
|
+
- IF L2 IS ABSENT: Inspect only bounded target source and narrowly implicated contracts; proceed without creating a placeholder. Documentation creation belongs to Retrospective or explicit documentation repair and requires complete Value-Gate-qualified content.
|
|
10
|
+
- NEVER load all L1/L2 documents at session start, create L3, or load unrelated modules.
|
|
11
|
+
- PATH LEVELS: only exact `root.prizm` is L0; every other direct `.prizm` child is L1; every nested `.prizm` document is L2.
|
|
12
|
+
- Arrow notation (`->`) identifies resolving documentation pointers.
|
|
13
|
+
- Memory files do not contain CHANGELOG sections/files, UPDATED/date metadata, feature/bug/refactor/task/session/run/pipeline/workflow IDs, branch names, absolute worktree paths, or `.prizmkit/specs` / `.prizmkit/dev-pipeline` artifact paths.
|
|
14
|
+
- `.prizmkit/**` is the framework directory. Its owning capabilities may read/write managed artifacts, but project Git tracking/ignore policy is independent and must not alter documentation behavior.
|
|
@@ -55,19 +55,19 @@ Resolve a compatible Python 3 interpreter through the current Host's executable
|
|
|
55
55
|
|
|
56
56
|
Review only the caller-supplied `artifact_dir`; never discover a different recent artifact. Missing or inconsistent stage input produces `NEEDS_FIXES` with the exact input blocker.
|
|
57
57
|
|
|
58
|
-
##
|
|
58
|
+
## Complete Git-Visible Correctness Scope
|
|
59
59
|
|
|
60
|
-
The current
|
|
60
|
+
The complete current Git-visible workspace is the correctness scope: staged and unstaged tracked changes, additions, deletions, renames, copies, and non-ignored untracked files. Correct changes that predate the active requirement or implementation session remain in scope. Do not exclude, specially admit, or require a separate support contract solely because a path is under `.prizmkit/**`, generated, an instruction or lock file, a platform directory, local support, or otherwise outside the original requirement namespace.
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
Inspect each visible path through the applicable contract: production behavior through code and callers, tests through assertion and boundary quality, instructions through readable structure and referenced-project consistency, lock/generated content through parse or deterministic parity, and binary or specialized content through the available project-native validator. Block when correctness cannot be established safely. Ignored paths remain naturally absent and are not review findings. Artifact files read or written by this stage are evidence/output, but any such file that is Git-visible in the final workspace is still disclosed to the final commit inspection rather than hidden by provenance.
|
|
63
63
|
|
|
64
64
|
## Phase 0: Initialize Report and Reuse Current Context
|
|
65
65
|
|
|
66
66
|
1. Resolve `{artifact_dir}` and `{artifact_dir}/review-report.md` from the active requirement context.
|
|
67
67
|
2. At the start of each execution, initialize a replacement report through the Report Renderer Contract and `${SKILL_DIR}/references/review-report-template.md`.
|
|
68
68
|
3. Within that execution, append every review round, repair batch, independent-review event, final verification, and exactly one `## Final Result` through the renderer or its visible equivalent fallback.
|
|
69
|
-
4. Start from the Main Agent's current requirement context and inspect the complete workspace inventory first: `git status --short`, the staged diff, and the unstaged diff. Include untracked, deleted,
|
|
70
|
-
5. Append one validated `scope-classification` renderer event containing exact in-scope paths
|
|
69
|
+
4. Start from the Main Agent's current requirement context and inspect the complete workspace inventory first: `git status --short`, the staged diff, and the unstaged diff. Include all non-ignored untracked, deleted, renamed, and copied paths in the correctness scope before producing findings.
|
|
70
|
+
5. Append one validated `scope-classification` renderer event containing the exact complete Git-visible in-scope paths. Do not maintain excluded-path metadata or claim ignored content was reviewed.
|
|
71
71
|
6. Reuse current context and load only missing or potentially stale material required to resolve a concrete ambiguity, verify an acceptance criterion, or understand a changed contract.
|
|
72
72
|
7. Inspect unchanged callers, dependents, contracts, or tests only when the in-scope diff changes or may violate an interface, shared behavior, or regression boundary. Do not perform an unconditional repository-wide dependency sweep.
|
|
73
73
|
8. For `review_scope=delta`, focus on in-scope files and behavior affected since the prior review pass and expand only across contracts implicated by that delta.
|
|
@@ -62,15 +62,14 @@ The Main Agent supplies:
|
|
|
62
62
|
|
|
63
63
|
- original requirement and confirmed clarifications;
|
|
64
64
|
- exact artifact, spec, and plan paths plus current contents;
|
|
65
|
-
-
|
|
66
|
-
- staged and unstaged tracked changes
|
|
67
|
-
-
|
|
68
|
-
- exact default-excluded changed paths as visible exclusion metadata, never as reviewed content;
|
|
65
|
+
- the complete current Git-visible workspace status;
|
|
66
|
+
- all staged and unstaged tracked changes;
|
|
67
|
+
- all non-ignored untracked, deleted, renamed, and copied content;
|
|
69
68
|
- implementation task completion and targeted verification results;
|
|
70
69
|
- response number and total budget;
|
|
71
70
|
- prior adjudication, actual repairs, and repair verification on continuation or replacement.
|
|
72
71
|
|
|
73
|
-
The Main Agent runs Git and captures authoritative
|
|
72
|
+
The Main Agent runs Git and captures the authoritative complete Git-visible change without namespace or provenance exclusions. Correct pre-existing, `.prizmkit/**`, generated, instruction, lock, and host-support content remains reviewable. The Reviewer may use structurally read-only checkout access to inspect unchanged callers, consumers, contracts, schemas, types, configurations, fixtures, or tests only when concrete coupling to a visible change justifies it. It must not run commands or perform an unconditional repository-wide scan. Ignored content is absent. Missing or inconsistent required input produces `REVIEW_BLOCKED`, never partial success.
|
|
74
73
|
|
|
75
74
|
## Initial Reviewer Prompt
|
|
76
75
|
|
|
@@ -18,18 +18,16 @@ Within that execution, append sections only. Never edit or replace an earlier pr
|
|
|
18
18
|
|
|
19
19
|
### Review Scope
|
|
20
20
|
|
|
21
|
-
Append once after workspace inventory
|
|
21
|
+
Append once after complete workspace inventory and before the first review round:
|
|
22
22
|
|
|
23
23
|
```markdown
|
|
24
24
|
## Review Scope
|
|
25
25
|
|
|
26
|
-
-
|
|
27
|
-
- <exact
|
|
28
|
-
- Default-Excluded Changed Paths:
|
|
29
|
-
- <exact .prizmkit/support path or None.>
|
|
26
|
+
- Git-Visible Paths:
|
|
27
|
+
- <exact staged, unstaged, deleted, renamed, copied, or non-ignored untracked path or None.>
|
|
30
28
|
```
|
|
31
29
|
|
|
32
|
-
|
|
30
|
+
Every Git-visible path is review scope regardless of provenance. Ignored paths remain absent rather than becoming exclusions.
|
|
33
31
|
|
|
34
32
|
### Main-Agent Review Round
|
|
35
33
|
|
|
@@ -115,15 +115,12 @@ def _render_event(data: dict[str, Any]) -> str:
|
|
|
115
115
|
|
|
116
116
|
if event == "scope-classification":
|
|
117
117
|
in_scope = _require_text_list(data, "in_scope_paths")
|
|
118
|
-
excluded = _require_text_list(data, "excluded_paths")
|
|
119
118
|
return "\n".join(
|
|
120
119
|
[
|
|
121
120
|
"## Review Scope",
|
|
122
121
|
"",
|
|
123
|
-
"-
|
|
122
|
+
"- Git-Visible Paths:",
|
|
124
123
|
*_render_path_list(in_scope),
|
|
125
|
-
"- Default-Excluded Changed Paths:",
|
|
126
|
-
*_render_path_list(excluded),
|
|
127
124
|
]
|
|
128
125
|
)
|
|
129
126
|
|