prizmkit 1.1.99 → 1.1.101
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/bin/create-prizmkit.js +4 -4
- package/bundled/VERSION.json +3 -3
- package/bundled/dev-pipeline/.env.example +3 -3
- package/bundled/dev-pipeline/README.md +110 -90
- package/bundled/dev-pipeline/assets/prizm-dev-team-integration.md +1 -1
- package/bundled/dev-pipeline/cli.py +27 -0
- package/bundled/dev-pipeline/prizmkit_runtime/__init__.py +13 -0
- package/bundled/dev-pipeline/prizmkit_runtime/__main__.py +9 -0
- package/bundled/dev-pipeline/prizmkit_runtime/cli.py +193 -0
- package/bundled/dev-pipeline/prizmkit_runtime/commands.py +313 -0
- package/bundled/dev-pipeline/prizmkit_runtime/compat.py +32 -0
- package/bundled/dev-pipeline/prizmkit_runtime/config.py +410 -0
- package/bundled/dev-pipeline/prizmkit_runtime/daemon.py +478 -0
- package/bundled/dev-pipeline/prizmkit_runtime/gitops.py +734 -0
- package/bundled/dev-pipeline/prizmkit_runtime/heartbeat.py +256 -0
- package/bundled/dev-pipeline/prizmkit_runtime/interoperability.py +109 -0
- package/bundled/dev-pipeline/prizmkit_runtime/paths.py +110 -0
- package/bundled/dev-pipeline/prizmkit_runtime/processes.py +373 -0
- package/bundled/dev-pipeline/prizmkit_runtime/reset.py +389 -0
- package/bundled/dev-pipeline/prizmkit_runtime/runner_bookkeeping.py +51 -0
- package/bundled/dev-pipeline/prizmkit_runtime/runner_classification.py +179 -0
- package/bundled/dev-pipeline/prizmkit_runtime/runner_models.py +345 -0
- package/bundled/dev-pipeline/prizmkit_runtime/runner_prompts.py +118 -0
- package/bundled/dev-pipeline/prizmkit_runtime/runner_recovery.py +187 -0
- package/bundled/dev-pipeline/prizmkit_runtime/runner_status.py +147 -0
- package/bundled/dev-pipeline/prizmkit_runtime/runners.py +422 -0
- package/bundled/dev-pipeline/prizmkit_runtime/sessions.py +552 -0
- package/bundled/dev-pipeline/prizmkit_runtime/status.py +71 -0
- package/bundled/dev-pipeline/scripts/check-session-status.py +74 -1
- package/bundled/dev-pipeline/scripts/continuation.py +374 -0
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +64 -52
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +35 -25
- package/bundled/dev-pipeline/scripts/generate-recovery-prompt.py +2 -2
- package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +15 -20
- package/bundled/dev-pipeline/scripts/parse-stream-progress.py +185 -16
- package/bundled/dev-pipeline/scripts/update-bug-status.py +214 -6
- package/bundled/dev-pipeline/scripts/update-feature-status.py +237 -6
- package/bundled/dev-pipeline/scripts/update-refactor-status.py +214 -6
- package/bundled/dev-pipeline/templates/agent-prompts/dev-implement.md +8 -2
- package/bundled/dev-pipeline/templates/bootstrap-prompt.md +4 -0
- package/bundled/dev-pipeline/templates/bootstrap-tier1.md +14 -5
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +16 -6
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +16 -6
- package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +1 -1
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +3 -3
- package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +2 -0
- package/bundled/dev-pipeline/templates/sections/log-size-awareness.md +13 -69
- package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-agent-suffix.md +15 -7
- package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +42 -29
- package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +41 -39
- package/bundled/dev-pipeline/templates/sections/test-failure-recovery-agent.md +4 -0
- package/bundled/dev-pipeline/templates/sections/test-failure-recovery-lite.md +4 -0
- package/bundled/dev-pipeline/templates/session-status-schema.json +1 -1
- package/bundled/dev-pipeline/tests/conftest.py +1 -0
- package/bundled/dev-pipeline/tests/test_auto_skip.py +932 -0
- package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +207 -0
- package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +100 -0
- package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +43 -0
- package/bundled/dev-pipeline/tests/test_python_runner_parity.py +1138 -0
- package/bundled/dev-pipeline/tests/test_unified_cli.py +1045 -0
- package/bundled/skills/_metadata.json +1 -1
- package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +29 -34
- package/bundled/skills/bugfix-pipeline-launcher/references/configuration.md +6 -5
- package/bundled/skills/feature-pipeline-launcher/SKILL.md +29 -35
- package/bundled/skills/feature-pipeline-launcher/references/configuration.md +7 -6
- package/bundled/skills/feature-workflow/SKILL.md +3 -6
- package/bundled/skills/recovery-workflow/SKILL.md +23 -32
- package/bundled/skills/refactor-pipeline-launcher/SKILL.md +29 -35
- package/bundled/skills/refactor-pipeline-launcher/references/configuration.md +7 -6
- package/bundled/skills/refactor-workflow/SKILL.md +3 -6
- package/bundled/templates/hooks/commit-intent.json +2 -2
- package/bundled/templates/hooks/diff-prizm-docs.py +226 -0
- package/bundled/templates/hooks/prizm-pre-commit.py +45 -0
- package/bundled/templates/hooks/validate-prizm-docs.py +240 -0
- package/package.json +1 -1
- package/src/config.js +33 -12
- package/src/index.js +3 -6
- package/src/manifest.js +3 -2
- package/src/metadata.js +7 -18
- package/src/prompts.js +0 -12
- package/src/runtimes.js +18 -11
- package/src/scaffold.js +133 -116
- package/src/upgrade.js +1 -1
- package/bundled/dev-pipeline/launch-bugfix-daemon.sh +0 -500
- package/bundled/dev-pipeline/launch-feature-daemon.sh +0 -657
- package/bundled/dev-pipeline/launch-refactor-daemon.sh +0 -502
- package/bundled/dev-pipeline/lib/branch.sh +0 -326
- package/bundled/dev-pipeline/lib/common.sh +0 -1257
- package/bundled/dev-pipeline/lib/heartbeat.sh +0 -469
- package/bundled/dev-pipeline/reset-bug.sh +0 -395
- package/bundled/dev-pipeline/reset-feature.sh +0 -406
- package/bundled/dev-pipeline/reset-refactor.sh +0 -393
- package/bundled/dev-pipeline/run-bugfix.sh +0 -1315
- package/bundled/dev-pipeline/run-feature.sh +0 -1602
- package/bundled/dev-pipeline/run-recovery.sh +0 -648
- package/bundled/dev-pipeline/run-refactor.sh +0 -1348
- package/bundled/dev-pipeline/scripts/monitor-log.sh +0 -104
- package/bundled/dev-pipeline/tests/test-path-resolution.sh +0 -100
- package/bundled/dev-pipeline-windows/.env.example +0 -36
- package/bundled/dev-pipeline-windows/README.md +0 -30
- package/bundled/dev-pipeline-windows/SCHEMA_ANALYSIS.md +0 -533
- package/bundled/dev-pipeline-windows/assets/feature-list-example.json +0 -146
- package/bundled/dev-pipeline-windows/assets/prizm-dev-team-integration.md +0 -137
- package/bundled/dev-pipeline-windows/launch-bugfix-daemon.ps1 +0 -9
- package/bundled/dev-pipeline-windows/launch-feature-daemon.ps1 +0 -9
- package/bundled/dev-pipeline-windows/launch-refactor-daemon.ps1 +0 -9
- package/bundled/dev-pipeline-windows/lib/branch.ps1 +0 -235
- package/bundled/dev-pipeline-windows/lib/common.ps1 +0 -829
- package/bundled/dev-pipeline-windows/lib/daemon.ps1 +0 -140
- package/bundled/dev-pipeline-windows/lib/pipeline.ps1 +0 -967
- package/bundled/dev-pipeline-windows/lib/reset.ps1 +0 -87
- package/bundled/dev-pipeline-windows/reset-bug.ps1 +0 -9
- package/bundled/dev-pipeline-windows/reset-feature.ps1 +0 -9
- package/bundled/dev-pipeline-windows/reset-refactor.ps1 +0 -9
- package/bundled/dev-pipeline-windows/run-bugfix.ps1 +0 -9
- package/bundled/dev-pipeline-windows/run-feature.ps1 +0 -9
- package/bundled/dev-pipeline-windows/run-recovery.ps1 +0 -179
- package/bundled/dev-pipeline-windows/run-refactor.ps1 +0 -9
- package/bundled/dev-pipeline-windows/scripts/check-session-status.py +0 -228
- package/bundled/dev-pipeline-windows/scripts/detect-stuck.py +0 -530
- package/bundled/dev-pipeline-windows/scripts/generate-bootstrap-prompt.py +0 -2282
- package/bundled/dev-pipeline-windows/scripts/generate-bugfix-prompt.py +0 -767
- package/bundled/dev-pipeline-windows/scripts/generate-recovery-prompt.py +0 -805
- package/bundled/dev-pipeline-windows/scripts/generate-refactor-prompt.py +0 -845
- package/bundled/dev-pipeline-windows/scripts/init-bugfix-pipeline.py +0 -316
- package/bundled/dev-pipeline-windows/scripts/init-dev-team.py +0 -134
- package/bundled/dev-pipeline-windows/scripts/init-pipeline.py +0 -382
- package/bundled/dev-pipeline-windows/scripts/init-refactor-pipeline.py +0 -399
- package/bundled/dev-pipeline-windows/scripts/monitor-log.ps1 +0 -102
- package/bundled/dev-pipeline-windows/scripts/parse-stream-progress.py +0 -1232
- package/bundled/dev-pipeline-windows/scripts/patch-completion-notes.py +0 -191
- package/bundled/dev-pipeline-windows/scripts/prizmkit-test-gate.py +0 -446
- package/bundled/dev-pipeline-windows/scripts/update-bug-status.py +0 -913
- package/bundled/dev-pipeline-windows/scripts/update-checkpoint.py +0 -173
- package/bundled/dev-pipeline-windows/scripts/update-feature-status.py +0 -1558
- package/bundled/dev-pipeline-windows/scripts/update-refactor-status.py +0 -1119
- package/bundled/dev-pipeline-windows/scripts/utils.py +0 -542
- package/bundled/dev-pipeline-windows/templates/agent-prompts/critic-plan-challenge.md +0 -7
- package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-fix.md +0 -7
- package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-implement.md +0 -65
- package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-resume.md +0 -5
- package/bundled/dev-pipeline-windows/templates/agent-prompts/reviewer-review.md +0 -7
- package/bundled/dev-pipeline-windows/templates/bootstrap-prompt.md +0 -73
- package/bundled/dev-pipeline-windows/templates/bootstrap-tier1.md +0 -589
- package/bundled/dev-pipeline-windows/templates/bootstrap-tier2.md +0 -710
- package/bundled/dev-pipeline-windows/templates/bootstrap-tier3.md +0 -791
- package/bundled/dev-pipeline-windows/templates/bug-fix-list-schema.json +0 -263
- package/bundled/dev-pipeline-windows/templates/bugfix-bootstrap-prompt.md +0 -326
- package/bundled/dev-pipeline-windows/templates/feature-list-schema.json +0 -237
- package/bundled/dev-pipeline-windows/templates/refactor-bootstrap-prompt.md +0 -340
- package/bundled/dev-pipeline-windows/templates/refactor-list-schema.json +0 -270
- package/bundled/dev-pipeline-windows/templates/sections/ac-verification-checklist.md +0 -7
- package/bundled/dev-pipeline-windows/templates/sections/checkpoint-system.md +0 -91
- package/bundled/dev-pipeline-windows/templates/sections/context-budget-rules.md +0 -34
- package/bundled/dev-pipeline-windows/templates/sections/critical-paths-agent.md +0 -10
- package/bundled/dev-pipeline-windows/templates/sections/critical-paths-full.md +0 -12
- package/bundled/dev-pipeline-windows/templates/sections/critical-paths-lite.md +0 -7
- package/bundled/dev-pipeline-windows/templates/sections/directory-convention-agent.md +0 -8
- package/bundled/dev-pipeline-windows/templates/sections/directory-convention-full.md +0 -9
- package/bundled/dev-pipeline-windows/templates/sections/directory-convention-lite.md +0 -6
- package/bundled/dev-pipeline-windows/templates/sections/failure-capture.md +0 -21
- package/bundled/dev-pipeline-windows/templates/sections/feature-context.md +0 -21
- package/bundled/dev-pipeline-windows/templates/sections/log-size-awareness.md +0 -78
- package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification-auto.md +0 -283
- package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification-opencli.md +0 -112
- package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification.md +0 -168
- package/bundled/dev-pipeline-windows/templates/sections/phase-commit-full.md +0 -82
- package/bundled/dev-pipeline-windows/templates/sections/phase-commit.md +0 -75
- package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-agent-suffix.md +0 -23
- package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-base.md +0 -14
- package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-lite-suffix.md +0 -19
- package/bundled/dev-pipeline-windows/templates/sections/phase-critic-plan-full.md +0 -63
- package/bundled/dev-pipeline-windows/templates/sections/phase-critic-plan.md +0 -42
- package/bundled/dev-pipeline-windows/templates/sections/phase-implement-agent.md +0 -44
- package/bundled/dev-pipeline-windows/templates/sections/phase-implement-full.md +0 -59
- package/bundled/dev-pipeline-windows/templates/sections/phase-implement-lite.md +0 -39
- package/bundled/dev-pipeline-windows/templates/sections/phase-plan-agent.md +0 -27
- package/bundled/dev-pipeline-windows/templates/sections/phase-plan-lite.md +0 -27
- package/bundled/dev-pipeline-windows/templates/sections/phase-prizmkit-test.md +0 -39
- package/bundled/dev-pipeline-windows/templates/sections/phase-review-agent.md +0 -35
- package/bundled/dev-pipeline-windows/templates/sections/phase-review-full.md +0 -35
- package/bundled/dev-pipeline-windows/templates/sections/phase-specify-plan-full.md +0 -73
- package/bundled/dev-pipeline-windows/templates/sections/phase0-init.md +0 -13
- package/bundled/dev-pipeline-windows/templates/sections/phase0-test-baseline.md +0 -21
- package/bundled/dev-pipeline-windows/templates/sections/session-context.md +0 -5
- package/bundled/dev-pipeline-windows/templates/sections/subagent-timeout-recovery.md +0 -6
- package/bundled/dev-pipeline-windows/templates/sections/task-contract.md +0 -34
- package/bundled/dev-pipeline-windows/templates/sections/test-failure-recovery-agent.md +0 -48
- package/bundled/dev-pipeline-windows/templates/sections/test-failure-recovery-lite.md +0 -48
- package/bundled/dev-pipeline-windows/templates/session-status-schema.json +0 -83
- package/bundled/skills-windows/app-planner/SKILL.md +0 -296
- package/bundled/skills-windows/app-planner/assets/app-design-guide.md +0 -101
- package/bundled/skills-windows/app-planner/references/architecture-decisions.md +0 -52
- package/bundled/skills-windows/app-planner/references/brainstorm-guide.md +0 -101
- package/bundled/skills-windows/app-planner/references/frontend-design-guide.md +0 -71
- package/bundled/skills-windows/app-planner/references/infrastructure-convention-discovery.md +0 -108
- package/bundled/skills-windows/app-planner/references/project-brief-guide.md +0 -82
- package/bundled/skills-windows/app-planner/references/project-conventions-discovery.md +0 -59
- package/bundled/skills-windows/app-planner/references/project-state-detection.md +0 -90
- package/bundled/skills-windows/app-planner/references/red-team-checklist.md +0 -40
- package/bundled/skills-windows/app-planner/references/rules/backend/derivation-rules.md +0 -619
- package/bundled/skills-windows/app-planner/references/rules/backend/fixed-rules.md +0 -285
- package/bundled/skills-windows/app-planner/references/rules/backend/question-bank.md +0 -249
- package/bundled/skills-windows/app-planner/references/rules/backend/question-manifest.json +0 -46
- package/bundled/skills-windows/app-planner/references/rules/backend/template.md +0 -173
- package/bundled/skills-windows/app-planner/references/rules/database/derivation-rules.md +0 -382
- package/bundled/skills-windows/app-planner/references/rules/database/fixed-rules.md +0 -211
- package/bundled/skills-windows/app-planner/references/rules/database/question-bank.md +0 -184
- package/bundled/skills-windows/app-planner/references/rules/database/question-manifest.json +0 -39
- package/bundled/skills-windows/app-planner/references/rules/database/template.md +0 -158
- package/bundled/skills-windows/app-planner/references/rules/frontend/derivation-rules.md +0 -820
- package/bundled/skills-windows/app-planner/references/rules/frontend/fixed-rules.md +0 -188
- package/bundled/skills-windows/app-planner/references/rules/frontend/question-bank.md +0 -319
- package/bundled/skills-windows/app-planner/references/rules/frontend/question-manifest.json +0 -51
- package/bundled/skills-windows/app-planner/references/rules/frontend/template.md +0 -339
- package/bundled/skills-windows/app-planner/references/rules/mobile/derivation-rules.md +0 -649
- package/bundled/skills-windows/app-planner/references/rules/mobile/fixed-rules.md +0 -290
- package/bundled/skills-windows/app-planner/references/rules/mobile/question-bank.md +0 -232
- package/bundled/skills-windows/app-planner/references/rules/mobile/question-manifest.json +0 -47
- package/bundled/skills-windows/app-planner/references/rules/mobile/template.md +0 -175
- package/bundled/skills-windows/app-planner/references/rules-configuration.md +0 -46
- package/bundled/skills-windows/bug-fix-workflow/SKILL.md +0 -379
- package/bundled/skills-windows/bug-fix-workflow/references/bug-diagnosis.md +0 -41
- package/bundled/skills-windows/bug-planner/SKILL.md +0 -402
- package/bundled/skills-windows/bug-planner/assets/bug-confirmation-template.md +0 -43
- package/bundled/skills-windows/bug-planner/references/critic-and-verification.md +0 -44
- package/bundled/skills-windows/bug-planner/references/error-recovery.md +0 -73
- package/bundled/skills-windows/bug-planner/references/input-formats.md +0 -53
- package/bundled/skills-windows/bug-planner/references/schema-validation.md +0 -25
- package/bundled/skills-windows/bug-planner/references/severity-rules.md +0 -16
- package/bundled/skills-windows/bug-planner/scripts/validate-bug-list.py +0 -322
- package/bundled/skills-windows/bugfix-pipeline-launcher/SKILL.md +0 -304
- package/bundled/skills-windows/bugfix-pipeline-launcher/references/configuration.md +0 -84
- package/bundled/skills-windows/feature-pipeline-launcher/SKILL.md +0 -381
- package/bundled/skills-windows/feature-pipeline-launcher/references/configuration.md +0 -67
- package/bundled/skills-windows/feature-pipeline-launcher/scripts/preflight-check.py +0 -462
- package/bundled/skills-windows/feature-planner/SKILL.md +0 -397
- package/bundled/skills-windows/feature-planner/assets/evaluation-guide.md +0 -64
- package/bundled/skills-windows/feature-planner/assets/planning-guide.md +0 -214
- package/bundled/skills-windows/feature-planner/references/browser-interaction.md +0 -59
- package/bundled/skills-windows/feature-planner/references/completeness-review.md +0 -57
- package/bundled/skills-windows/feature-planner/references/decomposition-patterns.md +0 -75
- package/bundled/skills-windows/feature-planner/references/error-recovery.md +0 -90
- package/bundled/skills-windows/feature-planner/references/incremental-feature-planning.md +0 -112
- package/bundled/skills-windows/feature-planner/references/new-project-planning.md +0 -85
- package/bundled/skills-windows/feature-planner/scripts/validate-and-generate.py +0 -1020
- package/bundled/skills-windows/feature-workflow/SKILL.md +0 -374
- package/bundled/skills-windows/feature-workflow/references/brainstorm-guide.md +0 -137
- package/bundled/skills-windows/prizm-kit/SKILL.md +0 -93
- package/bundled/skills-windows/prizmkit-code-review/SKILL.md +0 -161
- package/bundled/skills-windows/prizmkit-code-review/references/dev-agent-prompt.md +0 -30
- package/bundled/skills-windows/prizmkit-code-review/references/review-report-template.md +0 -31
- package/bundled/skills-windows/prizmkit-code-review/references/reviewer-agent-prompt.md +0 -66
- package/bundled/skills-windows/prizmkit-code-review/scripts/check_loop.py +0 -186
- package/bundled/skills-windows/prizmkit-committer/SKILL.md +0 -89
- package/bundled/skills-windows/prizmkit-deploy/SKILL.md +0 -444
- package/bundled/skills-windows/prizmkit-deploy/references/ci-cd-workflows.md +0 -115
- package/bundled/skills-windows/prizmkit-deploy/references/cloud-platform-deploy.md +0 -93
- package/bundled/skills-windows/prizmkit-deploy/references/data-safety-examples.md +0 -120
- package/bundled/skills-windows/prizmkit-deploy/references/database-setup.md +0 -46
- package/bundled/skills-windows/prizmkit-deploy/references/deploy-config-schema.md +0 -148
- package/bundled/skills-windows/prizmkit-deploy/references/deploy-history-schema.md +0 -62
- package/bundled/skills-windows/prizmkit-deploy/references/deployment-modes.md +0 -50
- package/bundled/skills-windows/prizmkit-deploy/references/direct-upload.md +0 -26
- package/bundled/skills-windows/prizmkit-deploy/references/dns-setup.md +0 -42
- package/bundled/skills-windows/prizmkit-deploy/references/docker-deploy.md +0 -31
- package/bundled/skills-windows/prizmkit-deploy/references/firewall-setup.md +0 -37
- package/bundled/skills-windows/prizmkit-deploy/references/live-validation-notes.md +0 -21
- package/bundled/skills-windows/prizmkit-deploy/references/nginx-blue-green.md +0 -59
- package/bundled/skills-windows/prizmkit-deploy/references/ssh-bootstrap-flow.md +0 -49
- package/bundled/skills-windows/prizmkit-deploy/references/ssh-execution-flow.md +0 -41
- package/bundled/skills-windows/prizmkit-deploy/references/ssh-takeover.md +0 -20
- package/bundled/skills-windows/prizmkit-deploy/references/ssl-setup.md +0 -56
- package/bundled/skills-windows/prizmkit-implement/SKILL.md +0 -71
- package/bundled/skills-windows/prizmkit-init/SKILL.md +0 -356
- package/bundled/skills-windows/prizmkit-init/assets/project-brief-template.md +0 -82
- package/bundled/skills-windows/prizmkit-init/references/config-schema.md +0 -70
- package/bundled/skills-windows/prizmkit-init/references/rules/layer-detection.md +0 -41
- package/bundled/skills-windows/prizmkit-init/references/tech-stack-catalog.md +0 -13
- package/bundled/skills-windows/prizmkit-init/references/update-supplement.md +0 -9
- package/bundled/skills-windows/prizmkit-plan/SKILL.md +0 -102
- package/bundled/skills-windows/prizmkit-plan/assets/plan-template.md +0 -115
- package/bundled/skills-windows/prizmkit-plan/assets/spec-template.md +0 -73
- package/bundled/skills-windows/prizmkit-plan/references/clarify-guide.md +0 -67
- package/bundled/skills-windows/prizmkit-plan/references/examples.md +0 -85
- package/bundled/skills-windows/prizmkit-plan/references/verification-checklist.md +0 -60
- package/bundled/skills-windows/prizmkit-prizm-docs/SKILL.md +0 -129
- package/bundled/skills-windows/prizmkit-prizm-docs/assets/prizm-docs-format.md +0 -613
- package/bundled/skills-windows/prizmkit-prizm-docs/references/op-init.md +0 -45
- package/bundled/skills-windows/prizmkit-prizm-docs/references/op-rebuild.md +0 -15
- package/bundled/skills-windows/prizmkit-prizm-docs/references/op-status.md +0 -14
- package/bundled/skills-windows/prizmkit-prizm-docs/references/op-update.md +0 -19
- package/bundled/skills-windows/prizmkit-prizm-docs/references/op-validate.md +0 -17
- package/bundled/skills-windows/prizmkit-retrospective/SKILL.md +0 -87
- package/bundled/skills-windows/prizmkit-retrospective/references/knowledge-injection-steps.md +0 -50
- package/bundled/skills-windows/prizmkit-retrospective/references/structural-sync-steps.md +0 -43
- package/bundled/skills-windows/prizmkit-test/SKILL.md +0 -227
- package/bundled/skills-windows/prizmkit-test/references/boundary-coverage-protocol.md +0 -220
- package/bundled/skills-windows/prizmkit-test/references/examples.md +0 -143
- package/bundled/skills-windows/prizmkit-test/references/service-boundary-test-catalog.md +0 -225
- package/bundled/skills-windows/prizmkit-test/references/test-generation-steps.md +0 -109
- package/bundled/skills-windows/prizmkit-test/references/test-report-template.md +0 -111
- package/bundled/skills-windows/prizmkit-test/scripts/validate_boundary_report.py +0 -347
- package/bundled/skills-windows/recovery-workflow/SKILL.md +0 -355
- package/bundled/skills-windows/recovery-workflow/evals/evals.json +0 -46
- package/bundled/skills-windows/recovery-workflow/references/detection.md +0 -58
- package/bundled/skills-windows/recovery-workflow/scripts/detect-recovery-state.py +0 -544
- package/bundled/skills-windows/refactor-pipeline-launcher/SKILL.md +0 -346
- package/bundled/skills-windows/refactor-pipeline-launcher/references/configuration.md +0 -72
- package/bundled/skills-windows/refactor-planner/SKILL.md +0 -398
- package/bundled/skills-windows/refactor-planner/assets/planning-guide.md +0 -292
- package/bundled/skills-windows/refactor-planner/references/behavior-preservation.md +0 -301
- package/bundled/skills-windows/refactor-planner/references/fast-path.md +0 -59
- package/bundled/skills-windows/refactor-planner/references/planning-phases.md +0 -135
- package/bundled/skills-windows/refactor-planner/references/refactor-scoping-guide.md +0 -221
- package/bundled/skills-windows/refactor-planner/scripts/validate-and-generate-refactor.py +0 -858
- package/bundled/skills-windows/refactor-workflow/SKILL.md +0 -343
- package/bundled/skills-windows/refactor-workflow/references/brainstorm-guide.md +0 -116
- package/bundled/templates/hooks/diff-prizm-docs.sh +0 -158
- package/bundled/templates/hooks/prizm-pre-commit.sh +0 -108
- package/bundled/templates/hooks/validate-prizm-docs.sh +0 -139
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Patch completion_notes into feature-list.json, refactor-list.json, or bug-fix-list.json.
|
|
3
|
-
|
|
4
|
-
Reads a completion-summary.json file written by the AI session and patches
|
|
5
|
-
the corresponding item in the task list with the completion_notes field.
|
|
6
|
-
|
|
7
|
-
This enables rich dependency context propagation: when a downstream task's
|
|
8
|
-
bootstrap prompt is generated, it can read completion_notes from its
|
|
9
|
-
completed dependencies to understand what was built/changed.
|
|
10
|
-
|
|
11
|
-
Usage:
|
|
12
|
-
python3 patch-completion-notes.py \
|
|
13
|
-
--feature-list .prizmkit/plans/feature-list.json \
|
|
14
|
-
--feature-id F-001 \
|
|
15
|
-
--summary .prizmkit/specs/001-my-feature/completion-summary.json
|
|
16
|
-
|
|
17
|
-
python3 patch-completion-notes.py \
|
|
18
|
-
--refactor-list .prizmkit/plans/refactor-list.json \
|
|
19
|
-
--refactor-id R-001 \
|
|
20
|
-
--summary <path-to-summary>
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
import argparse
|
|
24
|
-
import json
|
|
25
|
-
import os
|
|
26
|
-
import sys
|
|
27
|
-
|
|
28
|
-
from utils import load_json_file, write_json_file, setup_logging
|
|
29
|
-
|
|
30
|
-
LOGGER = setup_logging("patch-completion-notes")
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def parse_args():
|
|
34
|
-
parser = argparse.ArgumentParser(
|
|
35
|
-
description="Patch completion_notes into a task list from completion-summary.json."
|
|
36
|
-
)
|
|
37
|
-
parser.add_argument(
|
|
38
|
-
"--feature-list",
|
|
39
|
-
default=None,
|
|
40
|
-
help="Path to .prizmkit/plans/feature-list.json",
|
|
41
|
-
)
|
|
42
|
-
parser.add_argument(
|
|
43
|
-
"--refactor-list",
|
|
44
|
-
default=None,
|
|
45
|
-
help="Path to .prizmkit/plans/refactor-list.json",
|
|
46
|
-
)
|
|
47
|
-
parser.add_argument(
|
|
48
|
-
"--bug-list",
|
|
49
|
-
default=None,
|
|
50
|
-
help="Path to .prizmkit/plans/bug-fix-list.json",
|
|
51
|
-
)
|
|
52
|
-
parser.add_argument(
|
|
53
|
-
"--feature-id",
|
|
54
|
-
default=None,
|
|
55
|
-
help="Feature ID to patch (e.g. F-001)",
|
|
56
|
-
)
|
|
57
|
-
parser.add_argument(
|
|
58
|
-
"--refactor-id",
|
|
59
|
-
default=None,
|
|
60
|
-
help="Refactor ID to patch (e.g. R-001)",
|
|
61
|
-
)
|
|
62
|
-
parser.add_argument(
|
|
63
|
-
"--bug-id",
|
|
64
|
-
default=None,
|
|
65
|
-
help="Bug ID to patch (e.g. B-001)",
|
|
66
|
-
)
|
|
67
|
-
parser.add_argument(
|
|
68
|
-
"--summary",
|
|
69
|
-
required=True,
|
|
70
|
-
help="Path to completion-summary.json file",
|
|
71
|
-
)
|
|
72
|
-
return parser.parse_args()
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
def read_completion_notes(summary_path):
|
|
76
|
-
"""Read completion_notes from a completion-summary.json file.
|
|
77
|
-
|
|
78
|
-
Returns a list of strings, or an empty list if the file is missing
|
|
79
|
-
or malformed.
|
|
80
|
-
"""
|
|
81
|
-
if not os.path.isfile(summary_path):
|
|
82
|
-
LOGGER.warning("Summary file not found: %s", summary_path)
|
|
83
|
-
return []
|
|
84
|
-
|
|
85
|
-
data, err = load_json_file(summary_path)
|
|
86
|
-
if err:
|
|
87
|
-
LOGGER.warning("Failed to read summary: %s", err)
|
|
88
|
-
return []
|
|
89
|
-
|
|
90
|
-
notes = data.get("completion_notes", [])
|
|
91
|
-
if not isinstance(notes, list):
|
|
92
|
-
LOGGER.warning("completion_notes is not a list in %s", summary_path)
|
|
93
|
-
return []
|
|
94
|
-
|
|
95
|
-
# Filter: only keep non-empty strings
|
|
96
|
-
return [n for n in notes if isinstance(n, str) and n.strip()]
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def patch_list(list_path, item_id, item_key, notes):
|
|
100
|
-
"""Patch completion_notes into a task list JSON file.
|
|
101
|
-
|
|
102
|
-
Args:
|
|
103
|
-
list_path: Path to the JSON list file
|
|
104
|
-
item_id: ID of the item to patch (e.g. "F-001" or "R-001")
|
|
105
|
-
item_key: Key for the items array (e.g. "features" or "refactors")
|
|
106
|
-
notes: List of completion note strings
|
|
107
|
-
"""
|
|
108
|
-
data, err = load_json_file(list_path)
|
|
109
|
-
if err:
|
|
110
|
-
LOGGER.error("Failed to read list: %s", err)
|
|
111
|
-
return False
|
|
112
|
-
|
|
113
|
-
items = data.get(item_key, [])
|
|
114
|
-
found = False
|
|
115
|
-
for item in items:
|
|
116
|
-
if isinstance(item, dict) and item.get("id") == item_id:
|
|
117
|
-
item["completion_notes"] = notes
|
|
118
|
-
found = True
|
|
119
|
-
break
|
|
120
|
-
|
|
121
|
-
if not found:
|
|
122
|
-
LOGGER.error("Item %s not found in %s", item_id, list_path)
|
|
123
|
-
return False
|
|
124
|
-
|
|
125
|
-
err = write_json_file(list_path, data)
|
|
126
|
-
if err:
|
|
127
|
-
LOGGER.error("Failed to write list: %s", err)
|
|
128
|
-
return False
|
|
129
|
-
|
|
130
|
-
LOGGER.info(
|
|
131
|
-
"Patched %d completion notes for %s in %s",
|
|
132
|
-
len(notes), item_id, list_path,
|
|
133
|
-
)
|
|
134
|
-
return True
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
def main():
|
|
138
|
-
args = parse_args()
|
|
139
|
-
|
|
140
|
-
# Determine mode: feature, refactor, or bug
|
|
141
|
-
if args.feature_list and args.feature_id:
|
|
142
|
-
list_path = args.feature_list
|
|
143
|
-
item_id = args.feature_id
|
|
144
|
-
item_key = "features"
|
|
145
|
-
elif args.refactor_list and args.refactor_id:
|
|
146
|
-
list_path = args.refactor_list
|
|
147
|
-
item_id = args.refactor_id
|
|
148
|
-
item_key = "refactors"
|
|
149
|
-
elif args.bug_list and args.bug_id:
|
|
150
|
-
list_path = args.bug_list
|
|
151
|
-
item_id = args.bug_id
|
|
152
|
-
item_key = "bugs"
|
|
153
|
-
else:
|
|
154
|
-
print(
|
|
155
|
-
"Error: must provide either (--feature-list + --feature-id) "
|
|
156
|
-
"or (--refactor-list + --refactor-id) "
|
|
157
|
-
"or (--bug-list + --bug-id)",
|
|
158
|
-
file=sys.stderr,
|
|
159
|
-
)
|
|
160
|
-
sys.exit(1)
|
|
161
|
-
|
|
162
|
-
# Read completion notes
|
|
163
|
-
notes = read_completion_notes(args.summary)
|
|
164
|
-
if not notes:
|
|
165
|
-
LOGGER.info("No completion notes to patch for %s", item_id)
|
|
166
|
-
sys.exit(0)
|
|
167
|
-
|
|
168
|
-
# Patch the list
|
|
169
|
-
if not patch_list(list_path, item_id, item_key, notes):
|
|
170
|
-
sys.exit(1)
|
|
171
|
-
|
|
172
|
-
# Output result
|
|
173
|
-
result = {
|
|
174
|
-
"item_id": item_id,
|
|
175
|
-
"notes_count": len(notes),
|
|
176
|
-
"list_path": os.path.abspath(list_path),
|
|
177
|
-
}
|
|
178
|
-
print(json.dumps(result, indent=2, ensure_ascii=False))
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
if __name__ == "__main__":
|
|
182
|
-
try:
|
|
183
|
-
main()
|
|
184
|
-
except KeyboardInterrupt:
|
|
185
|
-
sys.exit(130)
|
|
186
|
-
except SystemExit:
|
|
187
|
-
raise
|
|
188
|
-
except Exception as exc:
|
|
189
|
-
LOGGER.exception("Unhandled exception")
|
|
190
|
-
print("Error: {}".format(exc), file=sys.stderr)
|
|
191
|
-
sys.exit(1)
|
|
@@ -1,446 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Scoped PrizmKit test gate for feature pipeline prompts.
|
|
3
|
-
|
|
4
|
-
The feature bootstrap prompt calls this script instead of embedding the full
|
|
5
|
-
Bash/PowerShell report validation logic inline. It intentionally prints compact
|
|
6
|
-
`GATE:*` lines so the AI session can decide whether to continue, retry, or stop.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
import argparse
|
|
10
|
-
import os
|
|
11
|
-
import subprocess
|
|
12
|
-
import sys
|
|
13
|
-
from pathlib import Path
|
|
14
|
-
|
|
15
|
-
REQUIRED_BOUNDARY_COLUMNS = [
|
|
16
|
-
"Module",
|
|
17
|
-
"Interface",
|
|
18
|
-
"Service Type",
|
|
19
|
-
"Happy Path",
|
|
20
|
-
"Request Validation",
|
|
21
|
-
"Auth / Permission / Ownership",
|
|
22
|
-
"Domain Invariants",
|
|
23
|
-
"Collection / Pagination",
|
|
24
|
-
"Date / Time",
|
|
25
|
-
"State Transitions",
|
|
26
|
-
"Dependency Failure",
|
|
27
|
-
"Response Contract",
|
|
28
|
-
"N/A Reasons",
|
|
29
|
-
"Final Status",
|
|
30
|
-
]
|
|
31
|
-
|
|
32
|
-
BOUNDARY_VALIDATOR_CANDIDATES = [
|
|
33
|
-
".claude/command-assets/prizmkit-test/scripts/validate_boundary_report.py",
|
|
34
|
-
".codebuddy/skills/prizmkit-test/scripts/validate_boundary_report.py",
|
|
35
|
-
".agents/skills/prizmkit-test/scripts/validate_boundary_report.py",
|
|
36
|
-
]
|
|
37
|
-
|
|
38
|
-
OPENAPI_CANDIDATES = [
|
|
39
|
-
"openapi.yaml",
|
|
40
|
-
"openapi.yml",
|
|
41
|
-
"swagger.yaml",
|
|
42
|
-
"swagger.yml",
|
|
43
|
-
"docs/openapi.yaml",
|
|
44
|
-
"docs/openapi.yml",
|
|
45
|
-
"docs/swagger.yaml",
|
|
46
|
-
"docs/swagger.yml",
|
|
47
|
-
"api/openapi.yaml",
|
|
48
|
-
"api/openapi.yml",
|
|
49
|
-
"api/swagger.yaml",
|
|
50
|
-
"api/swagger.yml",
|
|
51
|
-
]
|
|
52
|
-
|
|
53
|
-
IGNORED_SCOPE_VALUES = {"none", "n/a", "not applicable", "(none)", "{...}", "..."}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def default_artifact_dir(feature_slug):
|
|
57
|
-
return ".prizmkit/specs/{}/".format(feature_slug)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def marker_path(feature_slug):
|
|
61
|
-
return os.path.join(default_artifact_dir(feature_slug), ".prizmkit-test-started")
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def pointer_path(feature_slug):
|
|
65
|
-
return os.path.join(default_artifact_dir(feature_slug), "test-report-path.txt")
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def normalize_artifact_dir(path):
|
|
69
|
-
return str(path or "").strip().replace("\\", "/").rstrip("/")
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def read_text(path):
|
|
73
|
-
with open(path, "r", encoding="utf-8") as fh:
|
|
74
|
-
return fh.read()
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def start_gate(feature_slug):
|
|
78
|
-
marker = marker_path(feature_slug)
|
|
79
|
-
os.makedirs(os.path.dirname(marker), exist_ok=True)
|
|
80
|
-
Path(marker).touch()
|
|
81
|
-
return {"gate": "GATE:START", "marker": marker}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
def newest_report_after_marker(marker):
|
|
85
|
-
if not os.path.isfile(marker):
|
|
86
|
-
return ""
|
|
87
|
-
try:
|
|
88
|
-
marker_mtime = os.path.getmtime(marker)
|
|
89
|
-
except OSError:
|
|
90
|
-
return ""
|
|
91
|
-
|
|
92
|
-
matches = []
|
|
93
|
-
for root, _dirs, files in os.walk(os.path.join(".prizmkit", "test")):
|
|
94
|
-
if "test-report.md" not in files:
|
|
95
|
-
continue
|
|
96
|
-
path = os.path.join(root, "test-report.md")
|
|
97
|
-
try:
|
|
98
|
-
report_mtime = os.path.getmtime(path)
|
|
99
|
-
except OSError:
|
|
100
|
-
continue
|
|
101
|
-
if report_mtime >= marker_mtime:
|
|
102
|
-
matches.append((report_mtime, path))
|
|
103
|
-
|
|
104
|
-
if not matches:
|
|
105
|
-
return ""
|
|
106
|
-
return sorted(matches)[-1][1]
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
def extract_section(report_text, heading):
|
|
110
|
-
in_section = False
|
|
111
|
-
lines = []
|
|
112
|
-
for raw_line in report_text.splitlines():
|
|
113
|
-
line = raw_line.strip()
|
|
114
|
-
if line == heading:
|
|
115
|
-
in_section = True
|
|
116
|
-
continue
|
|
117
|
-
if in_section and line.startswith("## "):
|
|
118
|
-
break
|
|
119
|
-
if in_section:
|
|
120
|
-
lines.append(raw_line)
|
|
121
|
-
return lines
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
def extract_scope_field(report_text, field_name):
|
|
125
|
-
prefix = "- {}:".format(field_name)
|
|
126
|
-
for raw_line in extract_section(report_text, "## Scope"):
|
|
127
|
-
line = raw_line.strip()
|
|
128
|
-
if line.startswith(prefix):
|
|
129
|
-
return line[len(prefix):].strip()
|
|
130
|
-
return ""
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
def extract_verdict(report_text):
|
|
134
|
-
for raw_line in extract_section(report_text, "## Verdict"):
|
|
135
|
-
line = raw_line.strip()
|
|
136
|
-
if line:
|
|
137
|
-
return line
|
|
138
|
-
return ""
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
def extract_key_value(section_lines, field_name):
|
|
142
|
-
prefix = "{}:".format(field_name).lower()
|
|
143
|
-
for raw_line in section_lines:
|
|
144
|
-
line = raw_line.strip()
|
|
145
|
-
if line.startswith("-"):
|
|
146
|
-
line = line[1:].strip()
|
|
147
|
-
if line.lower().startswith(prefix):
|
|
148
|
-
return line[len(prefix):].strip()
|
|
149
|
-
return ""
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
def parse_markdown_cells(line):
|
|
153
|
-
stripped = line.strip()
|
|
154
|
-
if not stripped.startswith("|"):
|
|
155
|
-
return []
|
|
156
|
-
return [cell.strip() for cell in stripped.strip("|").split("|")]
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
def boundary_columns_ok(matrix_lines):
|
|
160
|
-
for line in matrix_lines:
|
|
161
|
-
cells = parse_markdown_cells(line)
|
|
162
|
-
if cells and all(column in cells for column in REQUIRED_BOUNDARY_COLUMNS):
|
|
163
|
-
return True
|
|
164
|
-
return False
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
def boundary_incomplete(matrix_lines):
|
|
168
|
-
text = "\n".join(matrix_lines).lower()
|
|
169
|
-
return any(token in text for token in ["boundary-missing", "happy-path-only", "unresolved"])
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
def discover_openapi_file():
|
|
173
|
-
for candidate in OPENAPI_CANDIDATES:
|
|
174
|
-
if os.path.isfile(candidate):
|
|
175
|
-
return candidate
|
|
176
|
-
return ""
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
def boundary_validator_passed(report_path, openapi_file):
|
|
180
|
-
for validator in BOUNDARY_VALIDATOR_CANDIDATES:
|
|
181
|
-
if not os.path.isfile(validator):
|
|
182
|
-
continue
|
|
183
|
-
args = [sys.executable, validator, "--report", report_path]
|
|
184
|
-
if openapi_file:
|
|
185
|
-
args.extend(["--openapi", openapi_file])
|
|
186
|
-
result = subprocess.run(
|
|
187
|
-
args,
|
|
188
|
-
stdout=subprocess.DEVNULL,
|
|
189
|
-
stderr=subprocess.DEVNULL,
|
|
190
|
-
check=False,
|
|
191
|
-
)
|
|
192
|
-
if result.returncode == 0:
|
|
193
|
-
return True
|
|
194
|
-
return False
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
def scope_list(report_text, name):
|
|
198
|
-
values = []
|
|
199
|
-
in_list = False
|
|
200
|
-
marker = "- {}:".format(name)
|
|
201
|
-
for raw_line in extract_section(report_text, "## Scope"):
|
|
202
|
-
line = raw_line.strip()
|
|
203
|
-
if line == marker:
|
|
204
|
-
in_list = True
|
|
205
|
-
continue
|
|
206
|
-
if not in_list:
|
|
207
|
-
continue
|
|
208
|
-
if raw_line.startswith(" -") or raw_line.startswith("\t-"):
|
|
209
|
-
value = line[2:].strip().strip("`")
|
|
210
|
-
if value and value not in {"{...}", "..."}:
|
|
211
|
-
values.append(value)
|
|
212
|
-
continue
|
|
213
|
-
if line.startswith("- "):
|
|
214
|
-
break
|
|
215
|
-
return values
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
def path_is_inside_project(project_root, candidate):
|
|
219
|
-
try:
|
|
220
|
-
return os.path.commonpath([project_root, candidate]) == project_root
|
|
221
|
-
except ValueError:
|
|
222
|
-
return False
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
def scope_fresh_ok(report_path, marker, report_text):
|
|
226
|
-
try:
|
|
227
|
-
report_mtime = os.path.getmtime(report_path)
|
|
228
|
-
marker_mtime = os.path.getmtime(marker)
|
|
229
|
-
except OSError:
|
|
230
|
-
return False
|
|
231
|
-
if report_mtime < marker_mtime:
|
|
232
|
-
return False
|
|
233
|
-
|
|
234
|
-
source_files = scope_list(report_text, "In-Scope Source Files")
|
|
235
|
-
test_files = scope_list(report_text, "In-Scope Test Files")
|
|
236
|
-
if not source_files or not test_files:
|
|
237
|
-
return False
|
|
238
|
-
|
|
239
|
-
project_root = os.path.realpath(os.getcwd())
|
|
240
|
-
for listed_file in source_files + test_files:
|
|
241
|
-
normalized = listed_file.strip().strip("`")
|
|
242
|
-
if not normalized or normalized.lower() in IGNORED_SCOPE_VALUES:
|
|
243
|
-
return False
|
|
244
|
-
candidate = normalized if os.path.isabs(normalized) else os.path.join(os.getcwd(), normalized)
|
|
245
|
-
candidate_real = os.path.realpath(candidate)
|
|
246
|
-
if not path_is_inside_project(project_root, candidate_real):
|
|
247
|
-
return False
|
|
248
|
-
if not os.path.isfile(candidate_real):
|
|
249
|
-
return False
|
|
250
|
-
if os.path.getmtime(candidate_real) > report_mtime:
|
|
251
|
-
return False
|
|
252
|
-
return True
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
def write_report_pointer(feature_slug, report_path):
|
|
256
|
-
path = pointer_path(feature_slug)
|
|
257
|
-
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
258
|
-
with open(path, "w", encoding="utf-8") as fh:
|
|
259
|
-
fh.write(report_path + "\n")
|
|
260
|
-
return path
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
def update_checkpoint(checkpoint_path):
|
|
264
|
-
script_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "update-checkpoint.py")
|
|
265
|
-
if not checkpoint_path:
|
|
266
|
-
return True, ""
|
|
267
|
-
result = subprocess.run(
|
|
268
|
-
[
|
|
269
|
-
sys.executable,
|
|
270
|
-
script_path,
|
|
271
|
-
"--checkpoint-path",
|
|
272
|
-
checkpoint_path,
|
|
273
|
-
"--step",
|
|
274
|
-
"prizmkit-test",
|
|
275
|
-
"--status",
|
|
276
|
-
"completed",
|
|
277
|
-
],
|
|
278
|
-
stdout=subprocess.PIPE,
|
|
279
|
-
stderr=subprocess.STDOUT,
|
|
280
|
-
text=True,
|
|
281
|
-
check=False,
|
|
282
|
-
)
|
|
283
|
-
if result.returncode == 0:
|
|
284
|
-
return True, ""
|
|
285
|
-
output = " ".join((result.stdout or "").split())
|
|
286
|
-
return False, output[:500]
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
def validate_report(report_path, marker, feature_slug, expected_artifact_dir):
|
|
290
|
-
try:
|
|
291
|
-
report_text = read_text(report_path)
|
|
292
|
-
except OSError as exc:
|
|
293
|
-
return {
|
|
294
|
-
"status": "FAIL",
|
|
295
|
-
"reason": "unreadable_report",
|
|
296
|
-
"error": str(exc),
|
|
297
|
-
"report": report_path,
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
report_mode = extract_scope_field(report_text, "Mode")
|
|
301
|
-
report_artifact_dir = extract_scope_field(report_text, "Artifact Dir")
|
|
302
|
-
report_verdict = extract_verdict(report_text)
|
|
303
|
-
|
|
304
|
-
boundary_gate = extract_section(report_text, "## Boundary Completion Gate")
|
|
305
|
-
boundary_matrix = extract_section(report_text, "## Boundary Matrix")
|
|
306
|
-
boundary_validation = extract_section(report_text, "## Boundary Validation")
|
|
307
|
-
|
|
308
|
-
gate_passed = extract_key_value(boundary_gate, "Completion gate passed")
|
|
309
|
-
boundary_missing = extract_key_value(boundary_gate, "Boundary-missing")
|
|
310
|
-
happy_path_only = extract_key_value(boundary_gate, "Happy-path-only")
|
|
311
|
-
validation_result = extract_key_value(boundary_validation, "Validator result").lower()
|
|
312
|
-
|
|
313
|
-
columns_ok = boundary_columns_ok(boundary_matrix)
|
|
314
|
-
incomplete = boundary_incomplete(boundary_matrix)
|
|
315
|
-
openapi_file = discover_openapi_file()
|
|
316
|
-
validator_ok = boundary_validator_passed(report_path, openapi_file)
|
|
317
|
-
fresh_ok = scope_fresh_ok(report_path, marker, report_text)
|
|
318
|
-
|
|
319
|
-
artifact_ok = normalize_artifact_dir(report_artifact_dir) == normalize_artifact_dir(expected_artifact_dir)
|
|
320
|
-
boundary_ok = (
|
|
321
|
-
columns_ok
|
|
322
|
-
and not incomplete
|
|
323
|
-
and gate_passed == "yes"
|
|
324
|
-
and boundary_missing == "0"
|
|
325
|
-
and happy_path_only == "0"
|
|
326
|
-
and validation_result == "passed"
|
|
327
|
-
and validator_ok
|
|
328
|
-
and fresh_ok
|
|
329
|
-
)
|
|
330
|
-
|
|
331
|
-
result = {
|
|
332
|
-
"status": "PASS" if report_mode == "this-change" and artifact_ok and report_verdict == "PASS" and boundary_ok else "FAIL",
|
|
333
|
-
"verdict": report_verdict,
|
|
334
|
-
"mode": report_mode,
|
|
335
|
-
"artifact_dir": report_artifact_dir,
|
|
336
|
-
"boundary_gate": gate_passed,
|
|
337
|
-
"boundary_missing": boundary_missing,
|
|
338
|
-
"happy_path_only": happy_path_only,
|
|
339
|
-
"boundary_validation": validation_result,
|
|
340
|
-
"validator_passed": "1" if validator_ok else "0",
|
|
341
|
-
"scope_fresh": "1" if fresh_ok else "0",
|
|
342
|
-
"openapi": openapi_file,
|
|
343
|
-
"report": report_path,
|
|
344
|
-
"feature_slug": feature_slug,
|
|
345
|
-
}
|
|
346
|
-
if not columns_ok:
|
|
347
|
-
result["reason"] = "boundary_columns_missing"
|
|
348
|
-
elif incomplete:
|
|
349
|
-
result["reason"] = "boundary_incomplete"
|
|
350
|
-
elif not fresh_ok:
|
|
351
|
-
result["reason"] = "scope_not_fresh"
|
|
352
|
-
elif not artifact_ok:
|
|
353
|
-
result["reason"] = "wrong_artifact_dir"
|
|
354
|
-
elif report_mode != "this-change":
|
|
355
|
-
result["reason"] = "wrong_mode"
|
|
356
|
-
elif report_verdict != "PASS":
|
|
357
|
-
result["reason"] = "verdict_not_pass"
|
|
358
|
-
elif not validator_ok:
|
|
359
|
-
result["reason"] = "validator_failed"
|
|
360
|
-
elif not boundary_ok:
|
|
361
|
-
result["reason"] = "boundary_gate_failed"
|
|
362
|
-
return result
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
def check_gate(feature_slug, artifact_dir=None, checkpoint_path=None):
|
|
366
|
-
expected_artifact_dir = artifact_dir or default_artifact_dir(feature_slug)
|
|
367
|
-
marker = marker_path(feature_slug)
|
|
368
|
-
report_path = newest_report_after_marker(marker)
|
|
369
|
-
if not report_path:
|
|
370
|
-
return {"status": "MISSING", "marker": marker}
|
|
371
|
-
|
|
372
|
-
result = validate_report(report_path, marker, feature_slug, expected_artifact_dir)
|
|
373
|
-
if result["status"] != "PASS":
|
|
374
|
-
return result
|
|
375
|
-
|
|
376
|
-
write_report_pointer(feature_slug, report_path)
|
|
377
|
-
checkpoint_ok, checkpoint_error = update_checkpoint(checkpoint_path)
|
|
378
|
-
if not checkpoint_ok:
|
|
379
|
-
result["status"] = "FAIL"
|
|
380
|
-
result["reason"] = "checkpoint_update_failed"
|
|
381
|
-
result["checkpoint_error"] = checkpoint_error
|
|
382
|
-
return result
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
def format_result(result):
|
|
386
|
-
status = result.get("status") or result.get("gate", "")
|
|
387
|
-
if status == "GATE:START":
|
|
388
|
-
return "GATE:START marker={}".format(result.get("marker", ""))
|
|
389
|
-
if status == "MISSING":
|
|
390
|
-
return "GATE:MISSING marker={}".format(result.get("marker", ""))
|
|
391
|
-
if status == "PASS":
|
|
392
|
-
return "GATE:PASS {}".format(result.get("report", ""))
|
|
393
|
-
|
|
394
|
-
ordered = [
|
|
395
|
-
"reason",
|
|
396
|
-
"verdict",
|
|
397
|
-
"mode",
|
|
398
|
-
"artifact_dir",
|
|
399
|
-
"boundary_gate",
|
|
400
|
-
"boundary_missing",
|
|
401
|
-
"happy_path_only",
|
|
402
|
-
"boundary_validation",
|
|
403
|
-
"validator_passed",
|
|
404
|
-
"scope_fresh",
|
|
405
|
-
"openapi",
|
|
406
|
-
"report",
|
|
407
|
-
"checkpoint_error",
|
|
408
|
-
"error",
|
|
409
|
-
]
|
|
410
|
-
parts = []
|
|
411
|
-
for key in ordered:
|
|
412
|
-
value = result.get(key)
|
|
413
|
-
if value is not None and value != "":
|
|
414
|
-
parts.append("{}={}".format(key, value))
|
|
415
|
-
return "GATE:FAIL {}".format(" ".join(parts)).rstrip()
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
def build_parser():
|
|
419
|
-
parser = argparse.ArgumentParser(
|
|
420
|
-
description="Run the scoped PrizmKit feature test gate.",
|
|
421
|
-
)
|
|
422
|
-
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
423
|
-
|
|
424
|
-
start = subparsers.add_parser("start", help="Create the test gate marker")
|
|
425
|
-
start.add_argument("--feature-slug", required=True)
|
|
426
|
-
|
|
427
|
-
check = subparsers.add_parser("check", help="Validate the latest scoped test report")
|
|
428
|
-
check.add_argument("--feature-slug", required=True)
|
|
429
|
-
check.add_argument("--artifact-dir", default="")
|
|
430
|
-
check.add_argument("--checkpoint-path", default="")
|
|
431
|
-
return parser
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
def main(argv=None):
|
|
435
|
-
parser = build_parser()
|
|
436
|
-
args = parser.parse_args(argv)
|
|
437
|
-
if args.command == "start":
|
|
438
|
-
result = start_gate(args.feature_slug)
|
|
439
|
-
else:
|
|
440
|
-
result = check_gate(args.feature_slug, args.artifact_dir, args.checkpoint_path)
|
|
441
|
-
print(format_result(result))
|
|
442
|
-
return 0
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
if __name__ == "__main__":
|
|
446
|
-
sys.exit(main())
|