prizmkit 1.1.130 → 1.1.134
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/.env.example +1 -1
- package/bundled/dev-pipeline/assets/skill-subagent-integration.md +11 -6
- package/bundled/dev-pipeline/prizmkit_runtime/checkpoint_state.py +445 -8
- 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/runner_classification.py +87 -66
- package/bundled/dev-pipeline/prizmkit_runtime/runner_models.py +53 -3
- package/bundled/dev-pipeline/prizmkit_runtime/runner_recovery.py +55 -25
- package/bundled/dev-pipeline/prizmkit_runtime/runner_status.py +4 -0
- package/bundled/dev-pipeline/prizmkit_runtime/runners.py +119 -18
- package/bundled/dev-pipeline/prizmkit_runtime/sessions.py +3 -2
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +411 -17
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +57 -14
- package/bundled/dev-pipeline/scripts/generate-recovery-prompt.py +5 -4
- package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +55 -2
- package/bundled/dev-pipeline/scripts/prompt_framework.py +152 -1
- package/bundled/dev-pipeline/scripts/update-bug-status.py +53 -0
- package/bundled/dev-pipeline/scripts/update-checkpoint.py +294 -69
- package/bundled/dev-pipeline/scripts/update-feature-status.py +57 -0
- package/bundled/dev-pipeline/scripts/update-refactor-status.py +53 -0
- package/bundled/dev-pipeline/templates/bootstrap-prompt.md +5 -5
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +28 -22
- package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +24 -10
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +20 -2
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-commit-report.md +2 -2
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-diagnose-plan.md +1 -1
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-manual-verification.md +5 -10
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-review.md +9 -19
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-test.md +21 -0
- package/bundled/dev-pipeline/templates/sections/bugfix-session-status.md +1 -1
- package/bundled/dev-pipeline/templates/sections/checkpoint-system.md +10 -10
- package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +1 -1
- package/bundled/dev-pipeline/templates/sections/headless-commit-authorization.md +15 -0
- 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-prizmkit-test.md +26 -23
- package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +5 -5
- package/bundled/dev-pipeline/templates/sections/phase-review-full.md +15 -11
- package/bundled/dev-pipeline/templates/sections/refactor-phase-commit-report.md +1 -1
- package/bundled/dev-pipeline/templates/sections/refactor-phase-review.md +6 -6
- package/bundled/dev-pipeline/templates/sections/refactor-phase-test.md +21 -0
- 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_checkpoint_state.py +362 -3
- package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +349 -48
- package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +129 -0
- package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +91 -0
- package/bundled/dev-pipeline/tests/test_python_runner_parity.py +567 -23
- package/bundled/dev-pipeline/tests/test_unified_cli.py +37 -10
- package/bundled/skills/_metadata.json +63 -26
- package/bundled/skills/app-planner/SKILL.md +4 -3
- package/bundled/skills/bug-fix-workflow/SKILL.md +89 -180
- package/bundled/skills/bug-planner/SKILL.md +12 -27
- package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +131 -220
- package/bundled/skills/bugfix-pipeline-launcher/references/configuration.md +36 -90
- package/bundled/skills/feature-pipeline-launcher/SKILL.md +129 -271
- package/bundled/skills/feature-pipeline-launcher/references/configuration.md +35 -76
- package/bundled/skills/feature-planner/SKILL.md +27 -22
- package/bundled/skills/feature-planner/assets/planning-guide.md +4 -4
- package/bundled/skills/feature-workflow/SKILL.md +94 -121
- package/bundled/skills/prizmkit/SKILL.md +130 -94
- package/bundled/skills/prizmkit/references/workflow-state-protocol.md +181 -0
- package/bundled/skills/prizmkit-code-review/SKILL.md +132 -86
- package/bundled/skills/prizmkit-code-review/references/independent-code-review.md +243 -0
- package/bundled/skills/prizmkit-code-review/references/review-report-template.md +42 -1
- package/bundled/skills/prizmkit-code-review/references/workflow-state-protocol.md +181 -0
- package/bundled/skills/prizmkit-code-review/scripts/render_review_report.py +93 -1
- package/bundled/skills/prizmkit-committer/SKILL.md +125 -48
- package/bundled/skills/prizmkit-committer/references/workflow-state-protocol.md +181 -0
- package/bundled/skills/prizmkit-implement/SKILL.md +99 -73
- package/bundled/skills/prizmkit-implement/references/implementation-subagent-procedure.md +1 -1
- package/bundled/skills/prizmkit-implement/references/workflow-state-protocol.md +181 -0
- package/bundled/skills/prizmkit-init/SKILL.md +5 -5
- package/bundled/skills/prizmkit-plan/SKILL.md +146 -105
- 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 +181 -0
- package/bundled/skills/prizmkit-retrospective/SKILL.md +111 -53
- package/bundled/skills/prizmkit-retrospective/references/knowledge-injection-steps.md +7 -6
- package/bundled/skills/prizmkit-retrospective/references/structural-sync-steps.md +5 -4
- package/bundled/skills/prizmkit-retrospective/references/workflow-state-protocol.md +181 -0
- package/bundled/skills/prizmkit-test/SKILL.md +52 -6
- package/bundled/skills/prizmkit-test/assets/authoritative-records.schema.json +63 -12
- package/bundled/skills/prizmkit-test/assets/evidence-manifest.schema.json +1 -1
- package/bundled/skills/prizmkit-test/assets/evidence-package-template.json +13 -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/examples.md +1 -1
- package/bundled/skills/prizmkit-test/references/test-generation-steps.md +4 -1
- package/bundled/skills/prizmkit-test/references/test-report-template.md +1 -1
- package/bundled/skills/prizmkit-test/references/trusted-evidence-execution.md +15 -0
- package/bundled/skills/prizmkit-test/references/workflow-state-protocol.md +181 -0
- package/bundled/skills/prizmkit-test/scripts/build_test_evidence.py +744 -23
- package/bundled/skills/prizmkit-test/scripts/validate_test_evidence.py +194 -15
- package/bundled/skills/prizmkit-workflow/SKILL.md +266 -0
- package/bundled/skills/prizmkit-workflow/references/workflow-state-protocol.md +181 -0
- package/bundled/skills/recovery-workflow/SKILL.md +62 -241
- package/bundled/skills/recovery-workflow/evals/evals.json +17 -33
- package/bundled/skills/recovery-workflow/references/detection.md +28 -52
- package/bundled/skills/recovery-workflow/scripts/detect-recovery-state.py +105 -439
- package/bundled/skills/refactor-pipeline-launcher/SKILL.md +136 -275
- package/bundled/skills/refactor-pipeline-launcher/references/configuration.md +53 -88
- package/bundled/skills/refactor-planner/SKILL.md +12 -57
- package/bundled/skills/refactor-planner/references/behavior-preservation.md +111 -230
- package/bundled/skills/refactor-planner/references/error-recovery.md +37 -0
- package/bundled/skills/refactor-planner/references/planning-phases.md +11 -17
- package/bundled/skills/refactor-planner/scripts/validate-and-generate-refactor.py +1 -1
- package/bundled/skills/refactor-workflow/SKILL.md +98 -139
- package/bundled/templates/project-memory-template.md +4 -4
- package/package.json +1 -1
- package/src/index.js +4 -0
- package/src/prompts.js +10 -3
- package/src/scaffold.js +1 -1
- package/bundled/dev-pipeline/tests/test-deploy-safety.sh +0 -223
- package/bundled/skills/feature-pipeline-launcher/scripts/preflight-check.py +0 -462
|
@@ -97,10 +97,11 @@ Implement the minimal fix (red → green):
|
|
|
97
97
|
"""\
|
|
98
98
|
Verify fix quality:
|
|
99
99
|
1. Run `/prizmkit-code-review` with the current bugfix artifact directory.
|
|
100
|
-
2.
|
|
101
|
-
3.
|
|
102
|
-
4.
|
|
103
|
-
5.
|
|
100
|
+
2. Run the mandatory Main-Agent review over the complete current change for up to ten rounds; directly repair accepted findings and verify repairs.
|
|
101
|
+
3. After Main-Agent convergence, allow only the one skill-owned independent Reviewer under the strict structural capability gate. If any capability is unavailable or unproven, record downgrade and create none.
|
|
102
|
+
4. Converge only when accepted and unresolved findings are both zero; missing required evidence or round-ten non-convergence produces NEEDS_FIXES.
|
|
103
|
+
5. Do not invoke another review skill or add review execution outside the skill contract.
|
|
104
|
+
6. `review-report.md` is the only persisted review artifact. Continue only after its last Final Result is valid; preserve append-only progress for recovery.""",
|
|
104
105
|
),
|
|
105
106
|
6: (
|
|
106
107
|
"User Verification",
|
|
@@ -22,9 +22,11 @@ from prompt_framework import (
|
|
|
22
22
|
merge_checkpoint_state,
|
|
23
23
|
mode_agent_count,
|
|
24
24
|
normalize_mode,
|
|
25
|
+
pipeline_checkpoint_metadata,
|
|
25
26
|
read_text_file,
|
|
26
27
|
render_from_sections,
|
|
27
28
|
replace_placeholders,
|
|
29
|
+
route_pipeline_repair,
|
|
28
30
|
validate_rendered,
|
|
29
31
|
write_output,
|
|
30
32
|
)
|
|
@@ -34,6 +36,30 @@ from utils import enrich_global_context, helper_replacements, load_json_file, re
|
|
|
34
36
|
LOGGER = setup_logging("generate-refactor-prompt")
|
|
35
37
|
|
|
36
38
|
|
|
39
|
+
def route_refactor_repair(stage_result, repair_scope=None, repair_round=0):
|
|
40
|
+
"""Map Refactor review/test outcomes to the shared safe route contract."""
|
|
41
|
+
return route_pipeline_repair(stage_result, repair_scope, repair_round)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def refactor_checkpoint_metadata(artifact_dir, evidence=None, stage="plan",
|
|
45
|
+
status="PLAN_READY", stage_result=None,
|
|
46
|
+
repair_scope=None, repair_round=0,
|
|
47
|
+
next_stage="prizmkit-implement",
|
|
48
|
+
resume_from="prizmkit-implement"):
|
|
49
|
+
"""Build Refactor L4 handoff metadata while preserving Refactor L1 state."""
|
|
50
|
+
return pipeline_checkpoint_metadata(
|
|
51
|
+
artifact_dir,
|
|
52
|
+
evidence=evidence,
|
|
53
|
+
stage=stage,
|
|
54
|
+
status=status,
|
|
55
|
+
stage_result=stage_result,
|
|
56
|
+
repair_scope=repair_scope,
|
|
57
|
+
repair_round=repair_round,
|
|
58
|
+
next_stage=next_stage,
|
|
59
|
+
resume_from=resume_from,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
37
63
|
REFACTOR_SECTION_TO_SKILL = {
|
|
38
64
|
"refactor-phase-init": checkpoint_step("prizmkit-init", "Initialize", [".prizmkit/refactor/{slug}"]),
|
|
39
65
|
"refactor-phase-plan": checkpoint_step(
|
|
@@ -48,6 +74,14 @@ REFACTOR_SECTION_TO_SKILL = {
|
|
|
48
74
|
"prizmkit-code-review", "Review — Code Review & Behavior Verification",
|
|
49
75
|
[".prizmkit/refactor/{slug}/review-report.md"],
|
|
50
76
|
),
|
|
77
|
+
"refactor-phase-test": checkpoint_step(
|
|
78
|
+
"prizmkit-test", "Post-Review Test Gate",
|
|
79
|
+
[
|
|
80
|
+
".prizmkit/test/evidence/*/manifest.json",
|
|
81
|
+
".prizmkit/test/evidence/*/verdict.json",
|
|
82
|
+
".prizmkit/test/evidence/*/validation.json",
|
|
83
|
+
],
|
|
84
|
+
),
|
|
51
85
|
"phase-browser": checkpoint_step("browser-verification", "Browser Verification", []),
|
|
52
86
|
"refactor-phase-commit-report": checkpoint_group([
|
|
53
87
|
("prizmkit-retrospective", "Retrospective", []),
|
|
@@ -377,7 +411,7 @@ def _refactor_header(pipeline_mode):
|
|
|
377
411
|
title = "# Dev-Pipeline Refactor Session Bootstrap — {}\n".format(pipeline_mode.title())
|
|
378
412
|
desc = {
|
|
379
413
|
"lite": "**Tier 1 — Single Agent**: direct behavior-preserving refactor by the main orchestrator.",
|
|
380
|
-
"standard": "**Tier 2 — Main-Agent Review Gates**: direct refactor with Main-Agent-
|
|
414
|
+
"standard": "**Tier 2 — Main-Agent Review Gates**: direct refactor with mandatory Main-Agent review and optional strict capability-gated independent correctness review.",
|
|
381
415
|
"full": "**Tier 3 — Full Refactor Guardrails**: direct refactor with stronger behavior-preservation evidence.",
|
|
382
416
|
}.get(pipeline_mode, "**Refactor pipeline**")
|
|
383
417
|
return title + "\n" + desc + "\n"
|
|
@@ -399,6 +433,7 @@ def assemble_refactor_sections(pipeline_mode, sections_dir, browser_enabled, bro
|
|
|
399
433
|
sections.extend([
|
|
400
434
|
("refactor-phase-implement", load_section(sections_dir, "refactor-phase-implement.md")),
|
|
401
435
|
("refactor-phase-review", load_section(sections_dir, "refactor-phase-review.md")),
|
|
436
|
+
("refactor-phase-test", load_section(sections_dir, "refactor-phase-test.md")),
|
|
402
437
|
])
|
|
403
438
|
if browser_enabled:
|
|
404
439
|
browser_section_file = {
|
|
@@ -407,6 +442,7 @@ def assemble_refactor_sections(pipeline_mode, sections_dir, browser_enabled, bro
|
|
|
407
442
|
}.get(browser_tool, "phase-browser-verification-auto.md")
|
|
408
443
|
sections.append(("phase-browser", load_section(sections_dir, browser_section_file)))
|
|
409
444
|
sections.extend([
|
|
445
|
+
("headless-commit-authorization", load_section(sections_dir, "headless-commit-authorization.md")),
|
|
410
446
|
("refactor-phase-commit-report", load_section(sections_dir, "refactor-phase-commit-report.md")),
|
|
411
447
|
("refactor-session-status", load_section(sections_dir, "refactor-session-status.md")),
|
|
412
448
|
("refactor-critical-paths", load_section(sections_dir, "refactor-critical-paths.md")),
|
|
@@ -423,6 +459,7 @@ def generate_refactor_checkpoint(refactor_id, session_id, pipeline_mode="standar
|
|
|
423
459
|
("refactor-phase-plan", ""),
|
|
424
460
|
("refactor-phase-implement", ""),
|
|
425
461
|
("refactor-phase-review", ""),
|
|
462
|
+
("refactor-phase-test", ""),
|
|
426
463
|
("refactor-phase-commit-report", ""),
|
|
427
464
|
]
|
|
428
465
|
return generate_checkpoint_from_sections(
|
|
@@ -438,7 +475,11 @@ def generate_refactor_checkpoint(refactor_id, session_id, pipeline_mode="standar
|
|
|
438
475
|
|
|
439
476
|
|
|
440
477
|
def merge_refactor_checkpoint_state(existing, fresh, project_root):
|
|
441
|
-
|
|
478
|
+
merged = merge_checkpoint_state(existing, fresh, project_root, logger=LOGGER)
|
|
479
|
+
existing_state = existing.get("refactor_state")
|
|
480
|
+
if isinstance(existing_state, dict):
|
|
481
|
+
merged["refactor_state"] = existing_state
|
|
482
|
+
return merged
|
|
442
483
|
|
|
443
484
|
|
|
444
485
|
def emit_failure(message):
|
|
@@ -511,6 +552,18 @@ def main():
|
|
|
511
552
|
checkpoint = generate_refactor_checkpoint(
|
|
512
553
|
args.refactor_id, args.session_id, pipeline_mode, sections if use_sections else None,
|
|
513
554
|
)
|
|
555
|
+
if not any(step.get("skill") == "prizmkit-test" for step in checkpoint["steps"]):
|
|
556
|
+
emit_failure("Refactor checkpoint is missing the mandatory prizmkit-test stage")
|
|
557
|
+
checkpoint["refactor_state"] = refactor_checkpoint_metadata(
|
|
558
|
+
replacements["{{ARTIFACT_DIR}}"],
|
|
559
|
+
stage="plan",
|
|
560
|
+
status="PLAN_READY",
|
|
561
|
+
stage_result=None,
|
|
562
|
+
repair_scope=None,
|
|
563
|
+
repair_round=0,
|
|
564
|
+
next_stage="prizmkit-implement",
|
|
565
|
+
resume_from="prizmkit-implement",
|
|
566
|
+
)
|
|
514
567
|
|
|
515
568
|
if (args.resume_phase != "null" or is_continuation(args)) and os.path.exists(checkpoint_path):
|
|
516
569
|
try:
|
|
@@ -10,6 +10,137 @@ import os
|
|
|
10
10
|
import re
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
MAX_OUTER_REPAIR_ROUNDS = 3
|
|
14
|
+
REPAIR_SCOPES_REQUIRING_REVIEW = {
|
|
15
|
+
"production",
|
|
16
|
+
"runtime",
|
|
17
|
+
"schema",
|
|
18
|
+
"dependency",
|
|
19
|
+
"public-interface",
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def route_pipeline_repair(stage_result, repair_scope=None, repair_round=0):
|
|
24
|
+
"""Map review/test outcomes to bounded, safe L4 continuation routes."""
|
|
25
|
+
try:
|
|
26
|
+
current_round = int(repair_round)
|
|
27
|
+
except (TypeError, ValueError):
|
|
28
|
+
current_round = MAX_OUTER_REPAIR_ROUNDS
|
|
29
|
+
if current_round < 0:
|
|
30
|
+
current_round = MAX_OUTER_REPAIR_ROUNDS
|
|
31
|
+
|
|
32
|
+
result = {
|
|
33
|
+
"stage_result": stage_result,
|
|
34
|
+
"repair_scope": repair_scope,
|
|
35
|
+
"repair_round": current_round,
|
|
36
|
+
"blocked": False,
|
|
37
|
+
"resumable": False,
|
|
38
|
+
"next_stage": None,
|
|
39
|
+
"resume_from": None,
|
|
40
|
+
"route": [],
|
|
41
|
+
"reason": "",
|
|
42
|
+
"blocked_reason": None,
|
|
43
|
+
"terminal_status": None,
|
|
44
|
+
}
|
|
45
|
+
if stage_result == "TEST_PASS":
|
|
46
|
+
result.update(
|
|
47
|
+
next_stage="prizmkit-retrospective",
|
|
48
|
+
resume_from="prizmkit-retrospective",
|
|
49
|
+
reason="authoritative test evidence passed",
|
|
50
|
+
)
|
|
51
|
+
return result
|
|
52
|
+
if stage_result == "TEST_BLOCKED":
|
|
53
|
+
result.update(
|
|
54
|
+
blocked=True,
|
|
55
|
+
resumable=False,
|
|
56
|
+
reason="bounded automatic recovery cannot safely edit production",
|
|
57
|
+
blocked_reason="test_blocked",
|
|
58
|
+
terminal_status="WORKFLOW_BLOCKED",
|
|
59
|
+
)
|
|
60
|
+
return result
|
|
61
|
+
if stage_result not in {"REVIEW_NEEDS_FIXES", "TEST_FAIL"}:
|
|
62
|
+
result.update(
|
|
63
|
+
blocked=True,
|
|
64
|
+
reason="unknown stage result is unsafe",
|
|
65
|
+
blocked_reason="unknown_stage_result",
|
|
66
|
+
terminal_status="WORKFLOW_BLOCKED",
|
|
67
|
+
)
|
|
68
|
+
return result
|
|
69
|
+
if current_round >= MAX_OUTER_REPAIR_ROUNDS:
|
|
70
|
+
result.update(
|
|
71
|
+
blocked=True,
|
|
72
|
+
reason="maximum outer repair rounds reached",
|
|
73
|
+
blocked_reason="repair_round_limit",
|
|
74
|
+
terminal_status="WORKFLOW_BLOCKED",
|
|
75
|
+
)
|
|
76
|
+
return result
|
|
77
|
+
|
|
78
|
+
result["repair_round"] = current_round + 1
|
|
79
|
+
if stage_result == "REVIEW_NEEDS_FIXES":
|
|
80
|
+
result.update(
|
|
81
|
+
next_stage="prizmkit-implement",
|
|
82
|
+
resume_from="prizmkit-implement",
|
|
83
|
+
route=["prizmkit-implement", "prizmkit-code-review", "prizmkit-test"],
|
|
84
|
+
reason="review findings require implementation and fresh review",
|
|
85
|
+
)
|
|
86
|
+
return result
|
|
87
|
+
if repair_scope == "test-infrastructure":
|
|
88
|
+
result.update(
|
|
89
|
+
next_stage="prizmkit-implement",
|
|
90
|
+
resume_from="prizmkit-implement",
|
|
91
|
+
route=["prizmkit-implement", "prizmkit-test"],
|
|
92
|
+
reason="test infrastructure failure must not edit production speculatively",
|
|
93
|
+
)
|
|
94
|
+
return result
|
|
95
|
+
if repair_scope in REPAIR_SCOPES_REQUIRING_REVIEW:
|
|
96
|
+
result.update(
|
|
97
|
+
next_stage="prizmkit-implement",
|
|
98
|
+
resume_from="prizmkit-implement",
|
|
99
|
+
route=["prizmkit-implement", "prizmkit-code-review", "prizmkit-test"],
|
|
100
|
+
reason="production-facing failure requires review before retesting",
|
|
101
|
+
)
|
|
102
|
+
return result
|
|
103
|
+
result.update(
|
|
104
|
+
blocked=True,
|
|
105
|
+
reason="unknown repair scope has no safe automatic route",
|
|
106
|
+
blocked_reason="unsafe_repair_scope",
|
|
107
|
+
terminal_status="WORKFLOW_BLOCKED",
|
|
108
|
+
)
|
|
109
|
+
return result
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def pipeline_checkpoint_metadata(artifact_dir, evidence=None, stage="plan",
|
|
113
|
+
status="PLAN_READY", stage_result=None,
|
|
114
|
+
repair_scope=None, repair_round=0,
|
|
115
|
+
next_stage="prizmkit-implement",
|
|
116
|
+
resume_from="prizmkit-implement",
|
|
117
|
+
blocked_reason=None, terminal_status=None):
|
|
118
|
+
"""Build family-neutral semantic L4 metadata without replacing L1 state."""
|
|
119
|
+
evidence = evidence or {}
|
|
120
|
+
current_stage = None if terminal_status else stage
|
|
121
|
+
semantic_next_stage = None if terminal_status else next_stage
|
|
122
|
+
return {
|
|
123
|
+
"schema_version": 1,
|
|
124
|
+
"artifact_dir": artifact_dir,
|
|
125
|
+
"orchestrator": "prizmkit-l4",
|
|
126
|
+
"stage": stage,
|
|
127
|
+
"current_stage": current_stage,
|
|
128
|
+
"status": status,
|
|
129
|
+
"stage_result": stage_result,
|
|
130
|
+
"repair_scope": repair_scope,
|
|
131
|
+
"repair_round": repair_round,
|
|
132
|
+
"authoritative_evidence_paths": {
|
|
133
|
+
"manifest": evidence.get("manifest_path"),
|
|
134
|
+
"verdict": evidence.get("verdict_path"),
|
|
135
|
+
"validation": evidence.get("validation_path"),
|
|
136
|
+
},
|
|
137
|
+
"next_stage": semantic_next_stage,
|
|
138
|
+
"resume_from": resume_from,
|
|
139
|
+
"blocked_reason": blocked_reason,
|
|
140
|
+
"terminal_status": terminal_status,
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
|
|
13
144
|
def read_text_file(path):
|
|
14
145
|
"""Read and return the text content of a file, plus an error string."""
|
|
15
146
|
abs_path = os.path.abspath(path)
|
|
@@ -257,8 +388,19 @@ def merge_checkpoint_state(existing, fresh, project_root, validator=None, logger
|
|
|
257
388
|
previous_status = previous.get("status", "pending") if isinstance(previous, dict) else "pending"
|
|
258
389
|
if previous_status == "completed":
|
|
259
390
|
artifacts = step.get("required_artifacts", [])
|
|
260
|
-
|
|
391
|
+
skill = step.get("skill", "")
|
|
392
|
+
stage_result = previous.get("stage_result") if isinstance(previous, dict) else None
|
|
393
|
+
verdict_valid = (
|
|
394
|
+
(skill != "prizmkit-code-review" or stage_result == "REVIEW_PASS")
|
|
395
|
+
and (skill != "prizmkit-test" or stage_result == "TEST_PASS")
|
|
396
|
+
)
|
|
397
|
+
if verdict_valid and validator(skill, artifacts):
|
|
261
398
|
step["status"] = "completed"
|
|
399
|
+
if stage_result:
|
|
400
|
+
step["stage_result"] = stage_result
|
|
401
|
+
evidence = previous.get("authoritative_evidence_paths")
|
|
402
|
+
if isinstance(evidence, dict):
|
|
403
|
+
step["authoritative_evidence_paths"] = evidence
|
|
262
404
|
continue
|
|
263
405
|
if logger is not None:
|
|
264
406
|
logger.warning(
|
|
@@ -271,6 +413,15 @@ def merge_checkpoint_state(existing, fresh, project_root, validator=None, logger
|
|
|
271
413
|
chain_broken = True
|
|
272
414
|
step["status"] = "pending"
|
|
273
415
|
|
|
416
|
+
workflow_type = fresh.get("workflow_type", "")
|
|
417
|
+
state_key = {
|
|
418
|
+
"feature-pipeline": "feature_state",
|
|
419
|
+
"bugfix-pipeline": "bugfix_state",
|
|
420
|
+
"refactor-pipeline": "refactor_state",
|
|
421
|
+
}.get(workflow_type)
|
|
422
|
+
if state_key and isinstance(existing.get(state_key), dict):
|
|
423
|
+
fresh[state_key] = dict(existing[state_key])
|
|
424
|
+
|
|
274
425
|
return fresh
|
|
275
426
|
|
|
276
427
|
|
|
@@ -46,6 +46,7 @@ SESSION_STATUS_VALUES = [
|
|
|
46
46
|
"infra_error",
|
|
47
47
|
"context_overflow",
|
|
48
48
|
"stalled_context_continuation",
|
|
49
|
+
"workflow_blocked",
|
|
49
50
|
"commit_missing",
|
|
50
51
|
"docs_missing",
|
|
51
52
|
"merge_conflict",
|
|
@@ -88,6 +89,7 @@ def parse_args():
|
|
|
88
89
|
parser.add_argument("--continuation-summary-path", default=None, help="Optional continuation summary artifact path.")
|
|
89
90
|
parser.add_argument("--no-progress-count", type=int, default=None, help="Consecutive context-overflow sessions without objective progress.")
|
|
90
91
|
parser.add_argument("--progress-fingerprint", default=None, help="JSON progress fingerprint captured after the session.")
|
|
92
|
+
parser.add_argument("--checkpoint-state", default=None, help="JSON semantic L4 checkpoint snapshot captured after the session.")
|
|
91
93
|
return parser.parse_args()
|
|
92
94
|
|
|
93
95
|
|
|
@@ -253,6 +255,37 @@ def _load_progress_fingerprint(raw):
|
|
|
253
255
|
return {"unparsed": str(raw)}
|
|
254
256
|
|
|
255
257
|
|
|
258
|
+
SEMANTIC_CHECKPOINT_FIELDS = (
|
|
259
|
+
"current_stage",
|
|
260
|
+
"next_stage",
|
|
261
|
+
"stage_result",
|
|
262
|
+
"repair_scope",
|
|
263
|
+
"repair_round",
|
|
264
|
+
"authoritative_evidence_paths",
|
|
265
|
+
"blocked_reason",
|
|
266
|
+
"terminal_status",
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def _load_checkpoint_state(raw):
|
|
271
|
+
if not raw:
|
|
272
|
+
return {}
|
|
273
|
+
try:
|
|
274
|
+
data = json.loads(raw)
|
|
275
|
+
except (TypeError, ValueError):
|
|
276
|
+
return {}
|
|
277
|
+
if not isinstance(data, dict):
|
|
278
|
+
return {}
|
|
279
|
+
return {key: data.get(key) for key in SEMANTIC_CHECKPOINT_FIELDS}
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def _sync_semantic_checkpoint(status_data, args):
|
|
283
|
+
semantic = _load_checkpoint_state(getattr(args, "checkpoint_state", None))
|
|
284
|
+
if semantic:
|
|
285
|
+
status_data.update(semantic)
|
|
286
|
+
return {key: status_data.get(key) for key in SEMANTIC_CHECKPOINT_FIELDS}
|
|
287
|
+
|
|
288
|
+
|
|
256
289
|
def _set_continuation_common(status_data, args, session_id):
|
|
257
290
|
if args.active_dev_branch:
|
|
258
291
|
status_data["active_dev_branch"] = args.active_dev_branch
|
|
@@ -494,6 +527,7 @@ def action_update(args, bug_list_path, state_dir):
|
|
|
494
527
|
fingerprint = _load_progress_fingerprint(args.progress_fingerprint)
|
|
495
528
|
if fingerprint is not None:
|
|
496
529
|
bs["last_progress_fingerprint"] = fingerprint
|
|
530
|
+
semantic_checkpoint = _sync_semantic_checkpoint(bs, args)
|
|
497
531
|
|
|
498
532
|
|
|
499
533
|
if session_status == "success":
|
|
@@ -560,6 +594,19 @@ def action_update(args, bug_list_path, state_dir):
|
|
|
560
594
|
if err:
|
|
561
595
|
error_out("Failed to update .prizmkit/plans/bug-fix-list.json: {}".format(err))
|
|
562
596
|
return
|
|
597
|
+
elif session_status == "workflow_blocked":
|
|
598
|
+
# Semantic terminal state: preserve partial work without consuming any retry budget.
|
|
599
|
+
new_status = "needs_info"
|
|
600
|
+
bs["continuation_pending"] = False
|
|
601
|
+
bs["needs_attention"] = True
|
|
602
|
+
bs["terminal_status"] = "WORKFLOW_BLOCKED"
|
|
603
|
+
bs["blocked_reason"] = (
|
|
604
|
+
semantic_checkpoint.get("blocked_reason") or "workflow_blocked"
|
|
605
|
+
)
|
|
606
|
+
err = update_bug_in_list(bug_list_path, bug_id, new_status)
|
|
607
|
+
if err:
|
|
608
|
+
error_out("Failed to update .prizmkit/plans/bug-fix-list.json: {}".format(err))
|
|
609
|
+
return
|
|
563
610
|
elif session_status == "stalled_context_continuation":
|
|
564
611
|
# No-progress context-overflow stall pauses automation without consuming retry budgets.
|
|
565
612
|
set_stalled_context_continuation_metadata(bs, args, session_id)
|
|
@@ -616,6 +663,7 @@ def action_update(args, bug_list_path, state_dir):
|
|
|
616
663
|
"infra_error_count": bs.get("infra_error_count", 0),
|
|
617
664
|
"max_infra_retries": max_infra_retries,
|
|
618
665
|
"resume_from_phase": bs.get("resume_from_phase"),
|
|
666
|
+
"checkpoint_state": semantic_checkpoint,
|
|
619
667
|
"updated_at": bs["updated_at"],
|
|
620
668
|
}
|
|
621
669
|
if session_status in ("commit_missing", "docs_missing", "merge_conflict"):
|
|
@@ -630,6 +678,11 @@ def action_update(args, bug_list_path, state_dir):
|
|
|
630
678
|
summary["restart_policy"] = "context_overflow_continuation"
|
|
631
679
|
summary.update(continuation_metadata_summary(bs))
|
|
632
680
|
summary["artifacts_preserved"] = True
|
|
681
|
+
elif session_status == "workflow_blocked":
|
|
682
|
+
summary["restart_policy"] = "terminal_blocked"
|
|
683
|
+
summary.update(continuation_metadata_summary(bs))
|
|
684
|
+
summary["checkpoint_state"] = semantic_checkpoint
|
|
685
|
+
summary["artifacts_preserved"] = True
|
|
633
686
|
elif session_status == "stalled_context_continuation":
|
|
634
687
|
summary["restart_policy"] = "needs_attention"
|
|
635
688
|
summary.update(continuation_metadata_summary(bs))
|