prizmkit 1.1.131 → 1.1.135
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/claude/command-adapter.js +0 -2
- package/bundled/dev-pipeline/assets/skill-subagent-integration.md +11 -6
- package/bundled/dev-pipeline/prizmkit_runtime/gitops.py +2 -9
- package/bundled/dev-pipeline/prizmkit_runtime/processes.py +21 -1
- package/bundled/dev-pipeline/prizmkit_runtime/runners.py +104 -17
- package/bundled/dev-pipeline/prizmkit_runtime/sessions.py +3 -2
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +15 -13
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +3 -13
- package/bundled/dev-pipeline/scripts/generate-recovery-prompt.py +5 -4
- package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +1 -1
- package/bundled/dev-pipeline/templates/bootstrap-prompt.md +4 -4
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +9 -9
- package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +4 -7
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +3 -3
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-commit-report.md +2 -2
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-manual-verification.md +5 -10
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-review.md +5 -5
- package/bundled/dev-pipeline/templates/sections/bugfix-session-status.md +1 -1
- package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +1 -1
- package/bundled/dev-pipeline/templates/sections/headless-commit-authorization.md +2 -3
- package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +2 -2
- package/bundled/dev-pipeline/templates/sections/phase-commit.md +2 -2
- package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +5 -5
- package/bundled/dev-pipeline/templates/sections/phase-review-full.md +5 -5
- package/bundled/dev-pipeline/templates/sections/refactor-phase-commit-report.md +1 -1
- package/bundled/dev-pipeline/templates/sections/refactor-phase-review.md +5 -5
- package/bundled/dev-pipeline/templates/sections/refactor-reminders.md +1 -1
- package/bundled/dev-pipeline/templates/sections/subagent-timeout-recovery.md +1 -1
- package/bundled/dev-pipeline/templates/sections/task-contract.md +4 -0
- package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +39 -26
- package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +7 -10
- package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +3 -3
- package/bundled/dev-pipeline/tests/test_python_runner_parity.py +156 -5
- package/bundled/dev-pipeline/tests/test_unified_cli.py +34 -7
- package/bundled/skills/_metadata.json +3 -3
- package/bundled/skills/prizmkit/references/workflow-state-protocol.md +3 -3
- package/bundled/skills/prizmkit-code-review/SKILL.md +22 -6
- package/bundled/skills/prizmkit-code-review/references/independent-code-review.md +243 -0
- package/bundled/skills/prizmkit-code-review/references/review-report-template.md +41 -0
- package/bundled/skills/prizmkit-code-review/references/workflow-state-protocol.md +3 -3
- package/bundled/skills/prizmkit-code-review/scripts/render_review_report.py +93 -1
- package/bundled/skills/prizmkit-committer/SKILL.md +6 -13
- package/bundled/skills/prizmkit-committer/references/workflow-state-protocol.md +3 -3
- package/bundled/skills/prizmkit-implement/references/workflow-state-protocol.md +3 -3
- package/bundled/skills/prizmkit-plan/SKILL.md +17 -3
- package/bundled/skills/prizmkit-plan/assets/plan-template.md +18 -0
- package/bundled/skills/prizmkit-plan/references/independent-plan-review.md +242 -0
- package/bundled/skills/prizmkit-plan/references/review-plan-spec-loop.md +4 -4
- package/bundled/skills/prizmkit-plan/references/workflow-state-protocol.md +3 -3
- package/bundled/skills/prizmkit-retrospective/references/workflow-state-protocol.md +3 -3
- package/bundled/skills/prizmkit-test/SKILL.md +26 -3
- package/bundled/skills/prizmkit-test/assets/authoritative-records.schema.json +147 -14
- package/bundled/skills/prizmkit-test/assets/evidence-manifest.schema.json +1 -1
- package/bundled/skills/prizmkit-test/assets/evidence-package-template.json +15 -0
- package/bundled/skills/prizmkit-test/references/evidence-protocol.md +6 -1
- package/bundled/skills/prizmkit-test/references/evidence-request-protocol.md +8 -1
- package/bundled/skills/prizmkit-test/references/test-generation-steps.md +5 -2
- package/bundled/skills/prizmkit-test/references/trusted-evidence-execution.md +15 -0
- package/bundled/skills/prizmkit-test/references/workflow-state-protocol.md +3 -3
- package/bundled/skills/prizmkit-test/scripts/build_test_evidence.py +1144 -27
- package/bundled/skills/prizmkit-test/scripts/validate_test_evidence.py +336 -18
- package/bundled/skills/prizmkit-workflow/SKILL.md +1 -1
- package/bundled/skills/prizmkit-workflow/references/workflow-state-protocol.md +3 -3
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import json
|
|
4
4
|
import os
|
|
5
5
|
import shutil
|
|
6
|
+
import signal
|
|
6
7
|
import subprocess
|
|
7
8
|
import sys
|
|
8
9
|
from pathlib import Path
|
|
@@ -1959,26 +1960,29 @@ def test_completed_checkout_blocks_rerun_until_explicit_reset(monkeypatch, tmp_p
|
|
|
1959
1960
|
runners._process_item(family, invocation, "F-001", paths, initial_metadata={})
|
|
1960
1961
|
|
|
1961
1962
|
|
|
1962
|
-
def test_no_worktree_interrupt_saves_wip_and_returns_to_base(monkeypatch, tmp_path):
|
|
1963
|
+
def test_no_worktree_interrupt_saves_wip_and_returns_to_base(monkeypatch, tmp_path, capsys):
|
|
1963
1964
|
from prizmkit_runtime import runners
|
|
1965
|
+
from prizmkit_runtime.gitops import current_branch as real_current_branch
|
|
1966
|
+
from prizmkit_runtime.gitops import run_git_command as real_run_git_command
|
|
1964
1967
|
from prizmkit_runtime.runner_models import family_for, parse_invocation
|
|
1965
1968
|
from prizmkit_runtime.task_checkout import load_task_checkout
|
|
1966
1969
|
|
|
1967
1970
|
monkeypatch.setenv("DEV_BRANCH", "dev/F-001-interrupt")
|
|
1968
1971
|
paths = _make_paths(tmp_path)
|
|
1972
|
+
_init_bookkeeping_repo(paths.project_root)
|
|
1969
1973
|
family = family_for("feature", paths)
|
|
1970
1974
|
invocation = parse_invocation(family, "run", ())
|
|
1971
1975
|
invocation = invocation.__class__(**{**invocation.__dict__, "list_path": paths.feature_plan})
|
|
1972
1976
|
_install_runner_session_fakes(monkeypatch, runners)
|
|
1973
|
-
|
|
1974
|
-
monkeypatch.setattr(runners, "
|
|
1975
|
-
monkeypatch.setattr(runners, "branch_ensure_return", lambda project_root, base, branch: ensure_calls.append((base, branch)))
|
|
1977
|
+
monkeypatch.setattr(runners, "current_branch", real_current_branch)
|
|
1978
|
+
monkeypatch.setattr(runners, "run_git_command", real_run_git_command)
|
|
1976
1979
|
|
|
1977
1980
|
class InterruptingLauncher:
|
|
1978
1981
|
def __init__(self, config):
|
|
1979
1982
|
self.config = config
|
|
1980
1983
|
|
|
1981
1984
|
def run(self):
|
|
1985
|
+
(self.config.cwd / "interrupted.txt").write_text("preserved\n", encoding="utf-8")
|
|
1982
1986
|
raise KeyboardInterrupt
|
|
1983
1987
|
|
|
1984
1988
|
monkeypatch.setattr(runners, "AISessionLauncher", InterruptingLauncher)
|
|
@@ -1987,11 +1991,158 @@ def test_no_worktree_interrupt_saves_wip_and_returns_to_base(monkeypatch, tmp_pa
|
|
|
1987
1991
|
runners._process_item(family, invocation, "F-001", paths, initial_metadata={})
|
|
1988
1992
|
|
|
1989
1993
|
checkout = load_task_checkout(family.state_dir, family.task_type, "F-001")
|
|
1994
|
+
captured = capsys.readouterr()
|
|
1990
1995
|
assert checkout is not None
|
|
1991
1996
|
assert checkout.is_active
|
|
1992
1997
|
assert checkout.active_dev_branch == "dev/F-001-interrupt"
|
|
1993
1998
|
assert checkout.base_branch == "main"
|
|
1994
|
-
assert
|
|
1999
|
+
assert real_current_branch(paths.project_root) == "main"
|
|
2000
|
+
assert subprocess.run(
|
|
2001
|
+
["git", "show", "dev/F-001-interrupt:interrupted.txt"],
|
|
2002
|
+
cwd=paths.project_root,
|
|
2003
|
+
check=True,
|
|
2004
|
+
stdout=subprocess.PIPE,
|
|
2005
|
+
text=True,
|
|
2006
|
+
).stdout == "preserved\n"
|
|
2007
|
+
assert "Interrupted task F-001: work preserved and returned to main" in captured.err
|
|
2008
|
+
|
|
2009
|
+
|
|
2010
|
+
def test_interrupt_return_failure_is_reported_without_forcing_checkout(monkeypatch, tmp_path, capsys):
|
|
2011
|
+
from prizmkit_runtime import runners
|
|
2012
|
+
from prizmkit_runtime.runner_models import family_for, parse_invocation
|
|
2013
|
+
|
|
2014
|
+
monkeypatch.setenv("DEV_BRANCH", "dev/F-001-interrupt")
|
|
2015
|
+
paths = _make_paths(tmp_path)
|
|
2016
|
+
family = family_for("feature", paths)
|
|
2017
|
+
invocation = parse_invocation(family, "run", ())
|
|
2018
|
+
invocation = invocation.__class__(**{**invocation.__dict__, "list_path": paths.feature_plan})
|
|
2019
|
+
_install_runner_session_fakes(monkeypatch, runners)
|
|
2020
|
+
monkeypatch.setattr(runners, "run_git_plan", lambda project_root, plan: SimpleNamespace(ok=True, plan=plan, results=()))
|
|
2021
|
+
failure = SimpleNamespace(
|
|
2022
|
+
ok=False,
|
|
2023
|
+
plan=SimpleNamespace(
|
|
2024
|
+
commands=(
|
|
2025
|
+
SimpleNamespace(allow_failure=True),
|
|
2026
|
+
SimpleNamespace(allow_failure=False),
|
|
2027
|
+
)
|
|
2028
|
+
),
|
|
2029
|
+
results=(
|
|
2030
|
+
SimpleNamespace(
|
|
2031
|
+
args=("commit", "--no-verify", "-m", "wip"),
|
|
2032
|
+
return_code=1,
|
|
2033
|
+
stdout="nothing to commit",
|
|
2034
|
+
stderr="",
|
|
2035
|
+
),
|
|
2036
|
+
SimpleNamespace(
|
|
2037
|
+
args=("checkout", "main"),
|
|
2038
|
+
return_code=1,
|
|
2039
|
+
stdout="",
|
|
2040
|
+
stderr="untracked files would be overwritten",
|
|
2041
|
+
),
|
|
2042
|
+
),
|
|
2043
|
+
)
|
|
2044
|
+
monkeypatch.setattr(runners, "branch_ensure_return", lambda project_root, base, branch: failure)
|
|
2045
|
+
|
|
2046
|
+
class InterruptingLauncher:
|
|
2047
|
+
def __init__(self, config):
|
|
2048
|
+
self.config = config
|
|
2049
|
+
|
|
2050
|
+
def run(self):
|
|
2051
|
+
raise KeyboardInterrupt
|
|
2052
|
+
|
|
2053
|
+
monkeypatch.setattr(runners, "AISessionLauncher", InterruptingLauncher)
|
|
2054
|
+
|
|
2055
|
+
with pytest.raises(KeyboardInterrupt):
|
|
2056
|
+
runners._process_item(family, invocation, "F-001", paths, initial_metadata={})
|
|
2057
|
+
|
|
2058
|
+
captured = capsys.readouterr()
|
|
2059
|
+
assert "Could not safely return to main; leaving dev/F-001-interrupt active" in captured.err
|
|
2060
|
+
assert "git checkout main failed: untracked files would be overwritten" in captured.err
|
|
2061
|
+
assert "After resolving the Git blocker, run: git checkout main" in captured.err
|
|
2062
|
+
|
|
2063
|
+
|
|
2064
|
+
def test_worktree_interrupt_preserves_task_worktree_without_returning_caller_checkout(monkeypatch, tmp_path, capsys):
|
|
2065
|
+
from prizmkit_runtime import runners
|
|
2066
|
+
from prizmkit_runtime.runner_models import family_for, parse_invocation
|
|
2067
|
+
|
|
2068
|
+
monkeypatch.setenv("USE_WORKTREE", "1")
|
|
2069
|
+
monkeypatch.setenv("DEV_BRANCH", "dev/F-001-interrupt")
|
|
2070
|
+
paths = _make_paths(tmp_path)
|
|
2071
|
+
family = family_for("feature", paths)
|
|
2072
|
+
invocation = parse_invocation(family, "run", ())
|
|
2073
|
+
invocation = invocation.__class__(**{**invocation.__dict__, "list_path": paths.feature_plan})
|
|
2074
|
+
observed = _install_runner_session_fakes(monkeypatch, runners)
|
|
2075
|
+
monkeypatch.setattr(
|
|
2076
|
+
runners,
|
|
2077
|
+
"ensure_linked_worktree",
|
|
2078
|
+
lambda runtime: SimpleNamespace(ok=True, runtime=runtime, reason=""),
|
|
2079
|
+
)
|
|
2080
|
+
return_calls = []
|
|
2081
|
+
monkeypatch.setattr(
|
|
2082
|
+
runners,
|
|
2083
|
+
"branch_ensure_return",
|
|
2084
|
+
lambda *args: return_calls.append(args),
|
|
2085
|
+
)
|
|
2086
|
+
|
|
2087
|
+
class InterruptingLauncher:
|
|
2088
|
+
def __init__(self, config):
|
|
2089
|
+
self.config = config
|
|
2090
|
+
|
|
2091
|
+
def run(self):
|
|
2092
|
+
raise KeyboardInterrupt
|
|
2093
|
+
|
|
2094
|
+
monkeypatch.setattr(runners, "AISessionLauncher", InterruptingLauncher)
|
|
2095
|
+
|
|
2096
|
+
with pytest.raises(KeyboardInterrupt):
|
|
2097
|
+
runners._process_item(family, invocation, "F-001", paths, initial_metadata={})
|
|
2098
|
+
|
|
2099
|
+
captured = capsys.readouterr()
|
|
2100
|
+
assert observed.wip_calls
|
|
2101
|
+
assert return_calls == []
|
|
2102
|
+
assert "Interrupted task F-001: work preserved in" in captured.err
|
|
2103
|
+
assert "task worktree remains active" in captured.err
|
|
2104
|
+
|
|
2105
|
+
|
|
2106
|
+
def test_run_pipeline_command_bridges_sigterm_and_restores_handler(monkeypatch, tmp_path):
|
|
2107
|
+
from prizmkit_runtime import runners
|
|
2108
|
+
from prizmkit_runtime.runner_models import PipelineRunResult
|
|
2109
|
+
|
|
2110
|
+
paths = _make_paths(tmp_path)
|
|
2111
|
+
paths.feature_plan.write_text("{}", encoding="utf-8")
|
|
2112
|
+
previous = signal.getsignal(signal.SIGTERM)
|
|
2113
|
+
observed = []
|
|
2114
|
+
|
|
2115
|
+
def interrupted_pipeline(*args, **kwargs):
|
|
2116
|
+
installed = signal.getsignal(signal.SIGTERM)
|
|
2117
|
+
observed.append(installed)
|
|
2118
|
+
try:
|
|
2119
|
+
installed(signal.SIGTERM, None)
|
|
2120
|
+
except KeyboardInterrupt:
|
|
2121
|
+
return PipelineRunResult(False, 1, "interrupted", "interrupted")
|
|
2122
|
+
raise AssertionError("SIGTERM handler did not interrupt the pipeline")
|
|
2123
|
+
|
|
2124
|
+
monkeypatch.setattr(runners, "_run_pipeline", interrupted_pipeline)
|
|
2125
|
+
|
|
2126
|
+
result = runners.run_pipeline_command("feature", "run", (), paths)
|
|
2127
|
+
|
|
2128
|
+
assert result.exit_code == 1
|
|
2129
|
+
assert result.message == "processed=1 completed=False stopped_reason=interrupted"
|
|
2130
|
+
assert observed and observed[0] not in {previous, signal.SIG_DFL, signal.SIG_IGN}
|
|
2131
|
+
assert signal.getsignal(signal.SIGTERM) is previous
|
|
2132
|
+
|
|
2133
|
+
|
|
2134
|
+
def test_interruption_cleanup_shield_ignores_and_restores_signals():
|
|
2135
|
+
from prizmkit_runtime.processes import shield_interruption_signals
|
|
2136
|
+
|
|
2137
|
+
previous_sigint = signal.getsignal(signal.SIGINT)
|
|
2138
|
+
previous_sigterm = signal.getsignal(signal.SIGTERM)
|
|
2139
|
+
|
|
2140
|
+
with shield_interruption_signals():
|
|
2141
|
+
assert signal.getsignal(signal.SIGINT) is signal.SIG_IGN
|
|
2142
|
+
assert signal.getsignal(signal.SIGTERM) is signal.SIG_IGN
|
|
2143
|
+
|
|
2144
|
+
assert signal.getsignal(signal.SIGINT) is previous_sigint
|
|
2145
|
+
assert signal.getsignal(signal.SIGTERM) is previous_sigterm
|
|
1995
2146
|
|
|
1996
2147
|
|
|
1997
2148
|
@pytest.mark.parametrize(
|
|
@@ -828,13 +828,12 @@ def test_headless_review_guidance_uses_main_agent_review_loop():
|
|
|
828
828
|
|
|
829
829
|
for path in headless_guidance_files:
|
|
830
830
|
text = path.read_text(encoding="utf-8")
|
|
831
|
-
assert "Main-Agent review
|
|
831
|
+
assert "mandatory Main-Agent review" in text, path
|
|
832
832
|
assert "up to ten completed rounds" in text, path
|
|
833
833
|
assert "text final-verdict" in text, path
|
|
834
|
-
assert "
|
|
835
|
-
assert "
|
|
834
|
+
assert "strict structural capability gate" in text, path
|
|
835
|
+
assert "skill-owned independent Reviewer" in text, path
|
|
836
836
|
assert "low=0" not in text and "Reviewer 3" not in text, path
|
|
837
|
-
assert "REVIEW_BLOCKED" not in text, path
|
|
838
837
|
assert "forced-worktree changed-content fallback" not in text, path
|
|
839
838
|
assert "isolation:" not in text, path
|
|
840
839
|
|
|
@@ -843,9 +842,11 @@ def test_headless_review_guidance_uses_main_agent_review_loop():
|
|
|
843
842
|
assert "untracked, deleted, and renamed files" in skill_text
|
|
844
843
|
assert "accepted = 0" in skill_text
|
|
845
844
|
assert "ten completed review rounds" in skill_text
|
|
845
|
+
assert "## Phase 3: Independent Code Review" in skill_text
|
|
846
|
+
assert "maximum five Reviewer responses" in skill_text
|
|
846
847
|
assert "## Final Result" in skill_text
|
|
847
848
|
assert "PASS | NEEDS_FIXES" in skill_text
|
|
848
|
-
assert "BLOCKED" not in skill_text
|
|
849
|
+
assert "Verdict: <PASS | NEEDS_FIXES | BLOCKED>" not in skill_text
|
|
849
850
|
assert "Reviewer 2" not in skill_text
|
|
850
851
|
assert "reviewer-workspace-protocol.md" not in skill_text
|
|
851
852
|
assert "reviewer-execution-protocol.md" not in skill_text
|
|
@@ -2012,6 +2013,32 @@ def test_branch_return_commits_wip_without_touching_user_stashes(tmp_path):
|
|
|
2012
2013
|
).stdout == "interrupted work\n"
|
|
2013
2014
|
|
|
2014
2015
|
|
|
2016
|
+
def test_branch_return_ignores_installed_runtime_paths_without_blocking_wip_commit(tmp_path):
|
|
2017
|
+
from prizmkit_runtime.gitops import branch_ensure_return
|
|
2018
|
+
|
|
2019
|
+
_init_merge_repo(tmp_path)
|
|
2020
|
+
(tmp_path / ".gitignore").write_text(".prizmkit/*\n.claude/\n", encoding="utf-8")
|
|
2021
|
+
subprocess.run(["git", "add", ".gitignore"], cwd=tmp_path, check=True)
|
|
2022
|
+
subprocess.run(["git", "commit", "-m", "ignore installed runtime"], cwd=tmp_path, check=True, stdout=subprocess.DEVNULL)
|
|
2023
|
+
runtime_file = tmp_path / ".prizmkit" / "dev-pipeline" / "cli.py"
|
|
2024
|
+
runtime_file.parent.mkdir(parents=True)
|
|
2025
|
+
runtime_file.write_text("# installed runtime\n", encoding="utf-8")
|
|
2026
|
+
manifest = tmp_path / ".prizmkit" / "manifest.json"
|
|
2027
|
+
manifest.write_text('{}\n', encoding="utf-8")
|
|
2028
|
+
subprocess.run(["git", "checkout", "-b", "dev/interrupted"], cwd=tmp_path, check=True, stdout=subprocess.DEVNULL)
|
|
2029
|
+
(tmp_path / "interrupted.txt").write_text("preserved\n", encoding="utf-8")
|
|
2030
|
+
|
|
2031
|
+
result = branch_ensure_return(tmp_path, "main", "dev/interrupted")
|
|
2032
|
+
|
|
2033
|
+
assert result.ok is True
|
|
2034
|
+
assert subprocess.run(
|
|
2035
|
+
["git", "branch", "--show-current"], cwd=tmp_path, check=True, stdout=subprocess.PIPE, text=True,
|
|
2036
|
+
).stdout.strip() == "main"
|
|
2037
|
+
assert subprocess.run(
|
|
2038
|
+
["git", "show", "dev/interrupted:interrupted.txt"], cwd=tmp_path, check=True, stdout=subprocess.PIPE, text=True,
|
|
2039
|
+
).stdout == "preserved\n"
|
|
2040
|
+
|
|
2041
|
+
|
|
2015
2042
|
def test_branch_return_commit_failure_does_not_checkout_base(monkeypatch, tmp_path):
|
|
2016
2043
|
from prizmkit_runtime import gitops
|
|
2017
2044
|
|
|
@@ -2200,8 +2227,8 @@ def test_git_status_safe_ignores_worktree_support_assets(monkeypatch, tmp_path):
|
|
|
2200
2227
|
joined = " ".join(status_args)
|
|
2201
2228
|
assert ":(top,exclude).prizmkit-worktree" in status_args
|
|
2202
2229
|
assert ":(top,exclude).claude" in status_args
|
|
2203
|
-
assert ":(top,exclude).prizmkit
|
|
2204
|
-
assert ":(top,exclude,glob).prizmkit
|
|
2230
|
+
assert ":(top,exclude).prizmkit" in status_args
|
|
2231
|
+
assert ":(top,exclude,glob).prizmkit/**" in status_args
|
|
2205
2232
|
assert all(exclude in status_args for exclude in HIDDEN_TOOL_WORKTREE_EXCLUDES)
|
|
2206
2233
|
assert ".prizmkit-worktree" in joined
|
|
2207
2234
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.1.
|
|
2
|
+
"version": "1.1.135",
|
|
3
3
|
"skills": {
|
|
4
4
|
"prizmkit": {
|
|
5
5
|
"description": "Framework introduction and navigation for the formal single-requirement lifecycle, project initialization, Prizm docs, and independent deployment.",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"hasScripts": false
|
|
24
24
|
},
|
|
25
25
|
"prizmkit-plan": {
|
|
26
|
-
"description": "Formal requirement lifecycle entry: natural language →
|
|
26
|
+
"description": "Formal requirement lifecycle entry: natural language → spec.md and plan.md with mandatory Main-Agent planning review, optional capability-gated independent correctness review, stable artifact identity, and workflow-state handoff.",
|
|
27
27
|
"tier": "1",
|
|
28
28
|
"category": "prizmkit-skill",
|
|
29
29
|
"hasAssets": true,
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"hasScripts": false
|
|
38
38
|
},
|
|
39
39
|
"prizmkit-code-review": {
|
|
40
|
-
"description": "
|
|
40
|
+
"description": "Mandatory bounded Main-Agent code review plus optional capability-gated independent correctness review, with evidence-based adjudication, direct repairs, verification, and append-only progress reporting.",
|
|
41
41
|
"tier": "1",
|
|
42
42
|
"category": "prizmkit-skill",
|
|
43
43
|
"hasAssets": false,
|
|
@@ -157,12 +157,12 @@ Trusted headless execution:
|
|
|
157
157
|
```text
|
|
158
158
|
a trusted host explicitly authorizes the current local task commit
|
|
159
159
|
→ host injects mode=<host-defined-headless-mode>, owner=<trusted-host-identifier>,
|
|
160
|
-
local_commit_authorized=true
|
|
160
|
+
local_commit_authorized=true
|
|
161
161
|
→ committer verifies gates and commits automatically
|
|
162
|
-
→ no question
|
|
162
|
+
→ no question or wait is permitted
|
|
163
163
|
```
|
|
164
164
|
|
|
165
|
-
A self-declared or otherwise untrusted headless context does not authorize a commit.
|
|
165
|
+
A self-declared or otherwise untrusted headless context does not authorize a commit. Remote publication remains a separate host-runtime decision.
|
|
166
166
|
|
|
167
167
|
## Recovery
|
|
168
168
|
|
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "prizmkit-code-review"
|
|
3
|
-
description: "Review the complete current change for a formal PrizmKit requirement
|
|
3
|
+
description: "Review the complete current change for a formal PrizmKit requirement with a mandatory bounded Main-Agent loop and optional capability-gated independent correctness review. Directly repair accepted corrections, verify repairs, converge to PASS or stop with NEEDS_FIXES, and hand off to prizmkit-test. (project)"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# PrizmKit Code Review
|
|
7
7
|
|
|
8
|
-
`/prizmkit-code-review` is the mandatory review stage after implementation and before the full test stage. The current Main Agent
|
|
8
|
+
`/prizmkit-code-review` is the mandatory review stage after implementation and before the full test stage. The current Main Agent owns the complete baseline review loop: it discovers findings, adjudicates them, directly repairs accepted findings, verifies repairs, and continues until the review converges or stops safely. After convergence, one strictly capability-gated independent Reviewer may objectively check the complete current implementation without taking mutation or final-decision authority.
|
|
9
9
|
|
|
10
10
|
## Execution Boundary
|
|
11
11
|
|
|
12
|
-
-
|
|
12
|
+
- Main-Agent review remains mandatory and must not be delegated directly or indirectly.
|
|
13
|
+
- After Main-Agent convergence only, this skill may create the single independent Reviewer defined by `${SKILL_DIR}/references/independent-code-review.md` when every structural capability in that reference is proven.
|
|
13
14
|
- Do not invoke another review skill or review workflow from inside this skill.
|
|
14
|
-
- Do not launch review work through a general-purpose execution unit or relabel it as a finder, verifier, audit, compatibility review, verification, or gap sweep.
|
|
15
|
+
- Do not launch any additional review work through a general-purpose execution unit or relabel it as a finder, verifier, audit, compatibility review, verification, or gap sweep.
|
|
16
|
+
- The independent Reviewer cannot mutate, execute arbitrary commands, or create downstream execution units; prompt instructions never substitute for these structural guarantees.
|
|
15
17
|
- The Main Agent may directly read, search, edit, and run targeted verification in the active workspace.
|
|
16
18
|
- Review repairs occur before the full `/prizmkit-test` stage so final test evidence represents the final reviewed workspace.
|
|
17
19
|
- `{artifact_dir}/review-report.md` is the only persisted review artifact for this execution.
|
|
18
20
|
|
|
19
21
|
## Atomic Stage Boundary
|
|
20
22
|
|
|
21
|
-
`prizmkit-code-review` owns
|
|
23
|
+
`prizmkit-code-review` owns the complete mandatory Main-Agent review, the optional independent correctness review, accepted-correction repairs, and review verification. It writes its truthful terminal result and `next_stage`, then returns control. It must not invoke `prizmkit-test` or `prizmkit-implement` itself; the active orchestrator owns outer repair routing and the next-stage invocation.
|
|
22
24
|
|
|
23
25
|
## When to Use
|
|
24
26
|
|
|
@@ -111,7 +113,21 @@ Do not run the full auditable testing protocol as a substitute for this review s
|
|
|
111
113
|
|
|
112
114
|
If a repair is unsafe, incomplete, or unverifiable, record an unresolved finding and finish with `NEEDS_FIXES`.
|
|
113
115
|
|
|
114
|
-
## Phase 3:
|
|
116
|
+
## Phase 3: Independent Code Review
|
|
117
|
+
|
|
118
|
+
Run only after the Main-Agent review and repair loop converges with no unresolved finding. Main-Agent review remains mandatory on every host; this optional check never replaces or weakens it.
|
|
119
|
+
|
|
120
|
+
1. Read `${SKILL_DIR}/references/independent-code-review.md` and follow its complete contract.
|
|
121
|
+
2. Apply its all-or-nothing semantic Host Capability Gate. If any required structural capability is unavailable or unproven, create no Reviewer, append `independent-review-downgrade`, and preserve the valid completed Main-Agent review.
|
|
122
|
+
3. When the gate passes, capture bounded immutable input for the complete current change and create exactly one Code Reviewer with the reference's Initial Reviewer Prompt.
|
|
123
|
+
4. Use maximum five Reviewer responses. Append `independent-review-round` and `independent-adjudication` events. The Main Agent adjudicates every correction as `accepted`, `rejected`, or `unresolved` and retains all mutation authority.
|
|
124
|
+
5. For accepted corrections, repair directly in the active checkout, run targeted verification, and inspect the complete resulting change.
|
|
125
|
+
6. When responses remain, capture the complete fresh state and natively resume the exact same Reviewer. Never create a replacement Reviewer or simulate continuation with a fresh Reviewer plus summary.
|
|
126
|
+
7. If native resume fails after repair, append downgrade and rerun the Main-Agent review over that repair within the existing ten-round safety fuse.
|
|
127
|
+
8. If the fifth response causes a repair, run targeted verification, inspect the complete final change, record `Final State Independently Rechecked: no`, and do not send a sixth response.
|
|
128
|
+
9. `NO_CORRECTION_NEEDED` or all corrections rejected with evidence converges independent review. Any unresolved correction produces `NEEDS_FIXES`.
|
|
129
|
+
|
|
130
|
+
## Phase 4: Final Result
|
|
115
131
|
|
|
116
132
|
Before completing:
|
|
117
133
|
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# Independent Code Review
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Run one optional independent correctness review after the mandatory Main-Agent review and repair loop has converged. The Reviewer determines whether the complete current implementation correctly satisfies the requirement and plan. It is not required to disagree and must return `NO_CORRECTION_NEEDED` when no correction is justified.
|
|
6
|
+
|
|
7
|
+
This reference is complete within `prizmkit-code-review`. Do not depend on another skill's prompt or a platform-generated Reviewer role.
|
|
8
|
+
|
|
9
|
+
## Required Ordering and Budget
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
Implementation complete
|
|
13
|
+
→ mandatory Main-Agent review and repair loop: maximum ten rounds
|
|
14
|
+
→ optional independent Code Reviewer: maximum five responses
|
|
15
|
+
→ PASS or NEEDS_FIXES
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The independent budget does not replace, reduce, or extend the Main-Agent loop. Create at most one Reviewer for this Code Review stage. Never reuse it in another stage.
|
|
19
|
+
|
|
20
|
+
## Host Capability Gate
|
|
21
|
+
|
|
22
|
+
The gate is all-or-nothing. Before creating a Reviewer, the host must prove this semantic execution contract:
|
|
23
|
+
|
|
24
|
+
```yaml
|
|
25
|
+
execution_unit:
|
|
26
|
+
count: 1
|
|
27
|
+
access: read-only
|
|
28
|
+
mutation: unavailable
|
|
29
|
+
arbitrary_command_execution: unavailable
|
|
30
|
+
downstream_execution: structurally-unavailable
|
|
31
|
+
context_continuation: same-unit-native-resume
|
|
32
|
+
workspace_observation: bounded-active-checkout-input
|
|
33
|
+
model_configuration: inherit-current-session
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Rules:
|
|
37
|
+
|
|
38
|
+
- Prompt instructions cannot satisfy a missing structural capability.
|
|
39
|
+
- The decision must not branch on platform identity, tool name, execution-unit type name, adapter output, or a platform allowlist.
|
|
40
|
+
- If any capability is missing or cannot be proven, do not create a Reviewer. Use Strict Downgrade.
|
|
41
|
+
- A general execution unit with a prompt saying "do not mutate or delegate" is not eligible when those capabilities remain available.
|
|
42
|
+
- The Reviewer inherits the current session's model configuration. Do not add a separate model-selection contract.
|
|
43
|
+
|
|
44
|
+
## Review Input
|
|
45
|
+
|
|
46
|
+
Before each response, the Main Agent captures one bounded review input that is immutable for one response:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
review-input
|
|
50
|
+
├── manifest: input identity, response number, exact changed paths, states, and consistency markers
|
|
51
|
+
├── context: requirement, plan decisions, applicable rules, and prior adjudication on resume
|
|
52
|
+
└── payload: complete captured current change plus targeted supporting material
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The Code payload contains a logical representation of:
|
|
56
|
+
|
|
57
|
+
- staged tracked changes;
|
|
58
|
+
- unstaged tracked changes;
|
|
59
|
+
- untracked files;
|
|
60
|
+
- deleted and renamed files;
|
|
61
|
+
- the exact changed-file manifest;
|
|
62
|
+
- requirement goals and acceptance criteria;
|
|
63
|
+
- relevant plan decisions;
|
|
64
|
+
- applicable project rules and Prizm traps;
|
|
65
|
+
- targeted unchanged callers, dependents, contracts, schemas, or tests implicated by changed interfaces.
|
|
66
|
+
|
|
67
|
+
The Main Agent captures authoritative workspace state. The Reviewer does not run Git commands. Do not provide broad repository access as a substitute for complete current-change capture. The representation may use host-native immutable content or a read-only temporary payload outside the project change set; the protocol does not require a particular temporary path or command.
|
|
68
|
+
|
|
69
|
+
Before ordinary review, the Reviewer verifies that manifest, context, and payload agree. Missing paths, unexplained changed files, stale content, or mixed-round input produces `REVIEW_BLOCKED`, never partial success.
|
|
70
|
+
|
|
71
|
+
## Initial Reviewer Prompt
|
|
72
|
+
|
|
73
|
+
Instantiate the bracketed fields and retain every boundary below.
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
You are the sole independent Code Reviewer for this PrizmKit Code Review stage.
|
|
77
|
+
|
|
78
|
+
Purpose:
|
|
79
|
+
Objectively determine whether the Main Agent's complete current implementation correctly satisfies the confirmed requirement and plan. You are not an adversary and are not required to disagree. Return NO_CORRECTION_NEEDED when the current implementation is correct.
|
|
80
|
+
|
|
81
|
+
Response:
|
|
82
|
+
This is response [RESPONSE_NUMBER] of a maximum five responses.
|
|
83
|
+
Review-input identity: [INPUT_ID]
|
|
84
|
+
Manifest: [MANIFEST]
|
|
85
|
+
Context: [CONTEXT]
|
|
86
|
+
Payload: [PAYLOAD]
|
|
87
|
+
Permitted targeted paths, if represented separately: [TARGETED_PATHS_OR_NONE]
|
|
88
|
+
|
|
89
|
+
Execution boundaries:
|
|
90
|
+
- Complete this review personally.
|
|
91
|
+
- Do not create, schedule, resume, continue, request, or coordinate another execution unit.
|
|
92
|
+
- Do not ask the Main Agent to create a helper.
|
|
93
|
+
- Do not re-enter orchestration, delegation, another review workflow, or an equivalent process.
|
|
94
|
+
- Do not modify, create, delete, rename, stage, commit, or otherwise mutate files.
|
|
95
|
+
- Do not execute commands, tests, builds, network calls, or any operation that can change state.
|
|
96
|
+
- Read only the bounded review input and explicitly permitted targeted paths.
|
|
97
|
+
- Do not perform broad repository discovery or a full repository scan.
|
|
98
|
+
- Report only corrections supported by a concrete target and evidence.
|
|
99
|
+
- Do not invent an issue merely to return feedback.
|
|
100
|
+
- Return REVIEW_BLOCKED rather than delegate or provide an incomplete success result.
|
|
101
|
+
- Do not expose private reasoning traces. Return only the required output.
|
|
102
|
+
|
|
103
|
+
First validate input consistency. Then review requirement and acceptance-criteria alignment, implementation completeness, concrete failure scenarios, error handling, security, authorization, data integrity, transaction/concurrency/state-transition behavior, public and internal contracts, compatibility and regression risk, test-boundary or evidence defects that can conceal incorrect behavior, and applicable project-rule compliance.
|
|
104
|
+
|
|
105
|
+
Do not rewrite the plan, modify code, execute tests, or perform broad exploratory repository discovery.
|
|
106
|
+
|
|
107
|
+
Return exactly one result using the Reviewer Output Protocol.
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Resume Prompt
|
|
111
|
+
|
|
112
|
+
Resume the exact same Reviewer; do not create a new Reviewer with this text. Instantiate the bracketed fields.
|
|
113
|
+
|
|
114
|
+
```text
|
|
115
|
+
Continue as the same independent Code Reviewer.
|
|
116
|
+
|
|
117
|
+
Response:
|
|
118
|
+
This is response [RESPONSE_NUMBER] of a maximum five responses.
|
|
119
|
+
New review-input identity: [INPUT_ID]
|
|
120
|
+
New manifest: [MANIFEST]
|
|
121
|
+
Current context: [CONTEXT]
|
|
122
|
+
Current payload: [PAYLOAD]
|
|
123
|
+
Previously accepted corrections: [ACCEPTED_CORRECTIONS_OR_NONE]
|
|
124
|
+
Repairs actually made: [REPAIRS_OR_NONE]
|
|
125
|
+
Main-Agent targeted verification: [VERIFICATION]
|
|
126
|
+
Previously rejected corrections and rejection evidence: [REJECTIONS_OR_NONE]
|
|
127
|
+
Unresolved items: [UNRESOLVED_OR_NONE]
|
|
128
|
+
|
|
129
|
+
All initial execution boundaries and the Reviewer Output Protocol remain mandatory. Review the complete current state, not only the repair and not the superseded payload. Do not repeat a rejected correction unless the new state invalidates the recorded rejection evidence. Validate the new input before ordinary review and return exactly one result.
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Reviewer Output Protocol
|
|
133
|
+
|
|
134
|
+
Return exactly one of these forms. Do not add severity, confidence, dimension, workflow impact, or acceptance fields.
|
|
135
|
+
|
|
136
|
+
### No Correction Needed
|
|
137
|
+
|
|
138
|
+
```markdown
|
|
139
|
+
### Result: NO_CORRECTION_NEEDED
|
|
140
|
+
|
|
141
|
+
### Corrections
|
|
142
|
+
None.
|
|
143
|
+
|
|
144
|
+
### Summary
|
|
145
|
+
<one or two sentences confirming what was reviewed>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Correction Needed
|
|
149
|
+
|
|
150
|
+
```markdown
|
|
151
|
+
### Result: CORRECTION_NEEDED
|
|
152
|
+
|
|
153
|
+
### Corrections
|
|
154
|
+
|
|
155
|
+
#### Correction 1
|
|
156
|
+
- Target: <file and location, contract, or behavior>
|
|
157
|
+
- Problem: <what is currently incorrect>
|
|
158
|
+
- Evidence: <concrete basis or reproducible scenario>
|
|
159
|
+
- Correction: <recommended correction>
|
|
160
|
+
|
|
161
|
+
### Summary
|
|
162
|
+
<one or two sentences describing the current state>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Every correction contains only `Target`, `Problem`, `Evidence`, and `Correction`.
|
|
166
|
+
|
|
167
|
+
### Review Blocked
|
|
168
|
+
|
|
169
|
+
```markdown
|
|
170
|
+
### Result: REVIEW_BLOCKED
|
|
171
|
+
|
|
172
|
+
### Blocker
|
|
173
|
+
- Target: <missing or inconsistent review input>
|
|
174
|
+
- Problem: <why a complete review cannot be performed>
|
|
175
|
+
- Evidence: <concrete mismatch or capability failure>
|
|
176
|
+
- Correction: <what input or host condition would unblock review>
|
|
177
|
+
|
|
178
|
+
### Summary
|
|
179
|
+
No review verdict was produced.
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
`REVIEW_BLOCKED` is an internal independent-review result, not a lifecycle verdict.
|
|
183
|
+
|
|
184
|
+
## Main-Agent Adjudication
|
|
185
|
+
|
|
186
|
+
The Main Agent verifies each proposed correction and records exactly one decision:
|
|
187
|
+
|
|
188
|
+
| Decision | Meaning | Action |
|
|
189
|
+
|---|---|---|
|
|
190
|
+
| `accepted` | Evidence proves an in-scope implementation correction is needed. | Main Agent repairs the current implementation and performs targeted verification. |
|
|
191
|
+
| `rejected` | Current code, contracts, tests, artifacts, or rules disprove the proposed problem. | Record concrete rejection evidence and make no change for it. |
|
|
192
|
+
| `unresolved` | Correctness or a safe repair cannot be established. | Record the item and return `NEEDS_FIXES`. |
|
|
193
|
+
|
|
194
|
+
The Reviewer never modifies files and cannot overrule adjudication.
|
|
195
|
+
|
|
196
|
+
Independent review converges normally when:
|
|
197
|
+
|
|
198
|
+
1. the Reviewer returns `NO_CORRECTION_NEEDED`; or
|
|
199
|
+
2. every correction in the current response is rejected with concrete evidence and no unresolved item remains.
|
|
200
|
+
|
|
201
|
+
## Response Algorithm
|
|
202
|
+
|
|
203
|
+
1. Run only after the Main-Agent review and repair loop converges with no unresolved finding.
|
|
204
|
+
2. Apply the Host Capability Gate.
|
|
205
|
+
3. If eligible, capture response 1 input and create exactly one Reviewer with the Initial Reviewer Prompt.
|
|
206
|
+
4. Validate the result against the Reviewer Output Protocol and append an independent-review round event.
|
|
207
|
+
5. Adjudicate every correction and append independent-adjudication events. Any unresolved item returns `NEEDS_FIXES`.
|
|
208
|
+
6. For accepted corrections, the Main Agent repairs the active checkout, runs targeted verification, and inspects the complete resulting change.
|
|
209
|
+
7. If one or more responses remain, capture the complete fresh current change and resume the exact same Reviewer with the Resume Prompt. Do not restart the complete ten-round Main-Agent loop after every ordinary independent correction.
|
|
210
|
+
8. If the fifth response causes a repair, no sixth response is allowed. Run targeted verification, inspect the complete final change, record final-budget handling and `Final State Independently Rechecked: no`, and do not exceed the response budget.
|
|
211
|
+
9. End the Reviewer when review converges, reaches the response limit, fails irrecoverably, or the stage becomes blocked. Explicitly terminate it when the host safely supports that operation; otherwise stop sending messages.
|
|
212
|
+
10. Complete the existing final verification and append exactly one `## Final Result` with `PASS` or `NEEDS_FIXES`.
|
|
213
|
+
|
|
214
|
+
## Strict Downgrade
|
|
215
|
+
|
|
216
|
+
Use strict downgrade in any of these cases:
|
|
217
|
+
|
|
218
|
+
- a required capability is unavailable or unproven before creation;
|
|
219
|
+
- Reviewer creation fails;
|
|
220
|
+
- the exact same Reviewer cannot be resumed or resume fails;
|
|
221
|
+
- execution-unit integrity becomes uncertain.
|
|
222
|
+
|
|
223
|
+
Behavior:
|
|
224
|
+
|
|
225
|
+
1. Never create a weaker or replacement Reviewer.
|
|
226
|
+
2. Never create a fresh Reviewer with a summary of the prior conversation; a summary is context, not native continuation.
|
|
227
|
+
3. When no Reviewer is created, record the downgrade and continue from the completed Main-Agent review if it remains valid.
|
|
228
|
+
4. When creation fails before any response, record the failure and preserve the completed Main-Agent review.
|
|
229
|
+
5. When resume fails after an accepted repair, Never create a replacement Reviewer; rerun the Main-Agent review over the repair, within the existing ten-round safety fuse, record the downgrade and fallback, and return `NEEDS_FIXES` if review cannot establish convergence.
|
|
230
|
+
6. Reviewer input problems may be corrected and sent to the same Reviewer only while response budget and native continuation remain available. Otherwise downgrade.
|
|
231
|
+
7. Report temporary input-cleanup failures honestly; cleanup failure does not change an otherwise verified review result.
|
|
232
|
+
|
|
233
|
+
Strict downgrade is visible reduced assurance, not a new lifecycle verdict and not permission to weaken the gate.
|
|
234
|
+
|
|
235
|
+
## Report Recording
|
|
236
|
+
|
|
237
|
+
Use the existing append-only `review-report.md` lifecycle and renderer events:
|
|
238
|
+
|
|
239
|
+
- `independent-review-round`: response number `1..5`, result, correction count, adjudication counts, and next action;
|
|
240
|
+
- `independent-adjudication`: correction summary, `accepted | rejected | unresolved`, evidence, and actual modification;
|
|
241
|
+
- `independent-review-downgrade`: reason, Main-Agent fallback, and whether the final state was independently rechecked.
|
|
242
|
+
|
|
243
|
+
The report remains the only persisted Code Review artifact. It ends with exactly one `## Final Result`; valid final verdicts remain `PASS | NEEDS_FIXES`.
|