@pareto4/pp-core 1.5.0
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/.claude-plugin/plugin.json +23 -0
- package/GEMINI.md +53 -0
- package/LICENSE +22 -0
- package/README.md +100 -0
- package/agents/pp-advisor-researcher.md +108 -0
- package/agents/pp-ai-researcher.md +114 -0
- package/agents/pp-assumptions-analyzer.md +105 -0
- package/agents/pp-code-fixer.md +669 -0
- package/agents/pp-code-reviewer.md +387 -0
- package/agents/pp-codebase-mapper.md +853 -0
- package/agents/pp-debug-session-manager.md +315 -0
- package/agents/pp-debugger.md +1453 -0
- package/agents/pp-doc-classifier.md +168 -0
- package/agents/pp-doc-synthesizer.md +204 -0
- package/agents/pp-doc-verifier.md +217 -0
- package/agents/pp-doc-writer.md +616 -0
- package/agents/pp-domain-researcher.md +147 -0
- package/agents/pp-eval-auditor.md +191 -0
- package/agents/pp-eval-planner.md +154 -0
- package/agents/pp-executor.md +808 -0
- package/agents/pp-framework-selector.md +160 -0
- package/agents/pp-integration-checker.md +470 -0
- package/agents/pp-intel-updater.md +339 -0
- package/agents/pp-mempalace-curator.md +47 -0
- package/agents/pp-nyquist-auditor.md +204 -0
- package/agents/pp-pattern-mapper.md +335 -0
- package/agents/pp-phase-researcher.md +867 -0
- package/agents/pp-plan-checker.md +988 -0
- package/agents/pp-planner.md +1052 -0
- package/agents/pp-project-researcher.md +612 -0
- package/agents/pp-research-synthesizer.md +260 -0
- package/agents/pp-roadmapper.md +741 -0
- package/agents/pp-security-auditor.md +156 -0
- package/agents/pp-ui-auditor.md +495 -0
- package/agents/pp-ui-checker.md +309 -0
- package/agents/pp-ui-researcher.md +375 -0
- package/agents/pp-user-profiler.md +171 -0
- package/agents/pp-verifier.md +967 -0
- package/assets/gsd-logo-2000-transparent.png +0 -0
- package/assets/gsd-logo-2000-transparent.svg +17 -0
- package/assets/gsd-logo-2000.png +0 -0
- package/assets/gsd-logo-2000.svg +21 -0
- package/assets/terminal.svg +68 -0
- package/bin/install.js +12370 -0
- package/bin/lib/ui-safety-gate.cjs +107 -0
- package/commands/pp-add-tests.md +42 -0
- package/commands/pp-ai-integration-phase.md +37 -0
- package/commands/pp-audit-fix.md +34 -0
- package/commands/pp-audit-milestone.md +37 -0
- package/commands/pp-audit-uat.md +24 -0
- package/commands/pp-autonomous.md +51 -0
- package/commands/pp-capture.md +62 -0
- package/commands/pp-cleanup.md +24 -0
- package/commands/pp-code-review.md +59 -0
- package/commands/pp-complete-milestone.md +143 -0
- package/commands/pp-config.md +56 -0
- package/commands/pp-debug.md +52 -0
- package/commands/pp-discovery.md +34 -0
- package/commands/pp-discuss-phase.md +77 -0
- package/commands/pp-docs-update.md +49 -0
- package/commands/pp-eval-review.md +33 -0
- package/commands/pp-execute-phase.md +65 -0
- package/commands/pp-explore.md +27 -0
- package/commands/pp-extract-learnings.md +23 -0
- package/commands/pp-fast.md +31 -0
- package/commands/pp-forensics.md +57 -0
- package/commands/pp-graphify.md +204 -0
- package/commands/pp-health.md +31 -0
- package/commands/pp-help.md +28 -0
- package/commands/pp-import.md +45 -0
- package/commands/pp-inbox.md +39 -0
- package/commands/pp-ingest-docs.md +42 -0
- package/commands/pp-manager.md +45 -0
- package/commands/pp-map-codebase.md +83 -0
- package/commands/pp-mempalace-capture.md +71 -0
- package/commands/pp-mempalace-recall.md +102 -0
- package/commands/pp-milestone-summary.md +51 -0
- package/commands/pp-mvp-phase.md +45 -0
- package/commands/pp-new-milestone.md +45 -0
- package/commands/pp-new-project.md +47 -0
- package/commands/pp-ns-context.md +25 -0
- package/commands/pp-ns-ideate.md +24 -0
- package/commands/pp-ns-manage.md +36 -0
- package/commands/pp-ns-project.md +27 -0
- package/commands/pp-ns-review.md +29 -0
- package/commands/pp-ns-workflow.md +35 -0
- package/commands/pp-pause-work.md +43 -0
- package/commands/pp-phase.md +56 -0
- package/commands/pp-plan-phase.md +63 -0
- package/commands/pp-plan-review-convergence.md +60 -0
- package/commands/pp-pr-branch.md +26 -0
- package/commands/pp-profile-user.md +46 -0
- package/commands/pp-progress.md +49 -0
- package/commands/pp-quick.md +174 -0
- package/commands/pp-resume-work.md +30 -0
- package/commands/pp-review-backlog.md +63 -0
- package/commands/pp-review.md +42 -0
- package/commands/pp-secure-phase.md +36 -0
- package/commands/pp-settings.md +29 -0
- package/commands/pp-ship.md +24 -0
- package/commands/pp-sketch.md +60 -0
- package/commands/pp-spec-phase.md +63 -0
- package/commands/pp-spike.md +57 -0
- package/commands/pp-stats.md +20 -0
- package/commands/pp-surface.md +162 -0
- package/commands/pp-thread.md +24 -0
- package/commands/pp-ui-phase.md +35 -0
- package/commands/pp-ui-review.md +33 -0
- package/commands/pp-ultraplan-phase.md +34 -0
- package/commands/pp-undo.md +35 -0
- package/commands/pp-update.md +49 -0
- package/commands/pp-validate-phase.md +36 -0
- package/commands/pp-verify-work.md +39 -0
- package/commands/pp-workspace.md +52 -0
- package/commands/pp-workstreams.md +70 -0
- package/gemini-extension.json +6 -0
- package/hooks/dist/lib/git-cmd.js +150 -0
- package/hooks/dist/lib/pp-graphify-rebuild.sh +65 -0
- package/hooks/dist/managed-hooks-registry.cjs +39 -0
- package/hooks/dist/pp-check-update-worker.js +108 -0
- package/hooks/dist/pp-check-update.js +66 -0
- package/hooks/dist/pp-config-reload.js +133 -0
- package/hooks/dist/pp-context-monitor.js +196 -0
- package/hooks/dist/pp-cursor-post-tool.js +75 -0
- package/hooks/dist/pp-cursor-session-start.js +52 -0
- package/hooks/dist/pp-ensure-canonical-path.js +305 -0
- package/hooks/dist/pp-graphify-update.sh +158 -0
- package/hooks/dist/pp-phase-boundary.sh +47 -0
- package/hooks/dist/pp-prompt-guard.js +97 -0
- package/hooks/dist/pp-read-guard.js +101 -0
- package/hooks/dist/pp-read-injection-scanner.js +203 -0
- package/hooks/dist/pp-session-state.sh +59 -0
- package/hooks/dist/pp-statusline.js +566 -0
- package/hooks/dist/pp-update-banner.js +138 -0
- package/hooks/dist/pp-validate-commit.sh +57 -0
- package/hooks/dist/pp-workflow-guard.js +167 -0
- package/hooks/dist/pp-worktree-path-guard.js +185 -0
- package/hooks/hooks.json +70 -0
- package/hooks/lib/git-cmd.js +150 -0
- package/hooks/lib/pp-graphify-rebuild.sh +65 -0
- package/hooks/managed-hooks-registry.cjs +39 -0
- package/hooks/pp-check-update-worker.js +108 -0
- package/hooks/pp-check-update.js +66 -0
- package/hooks/pp-config-reload.js +133 -0
- package/hooks/pp-context-monitor.js +196 -0
- package/hooks/pp-cursor-post-tool.js +75 -0
- package/hooks/pp-cursor-session-start.js +52 -0
- package/hooks/pp-ensure-canonical-path.js +305 -0
- package/hooks/pp-graphify-update.sh +158 -0
- package/hooks/pp-phase-boundary.sh +47 -0
- package/hooks/pp-prompt-guard.js +97 -0
- package/hooks/pp-read-guard.js +101 -0
- package/hooks/pp-read-injection-scanner.js +203 -0
- package/hooks/pp-session-state.sh +59 -0
- package/hooks/pp-statusline.js +566 -0
- package/hooks/pp-update-banner.js +138 -0
- package/hooks/pp-validate-commit.sh +57 -0
- package/hooks/pp-workflow-guard.js +167 -0
- package/hooks/pp-worktree-path-guard.js +185 -0
- package/package.json +125 -0
- package/pp-core/bin/check-latest-version.cjs +161 -0
- package/pp-core/bin/lib/active-workstream-store.cjs +297 -0
- package/pp-core/bin/lib/adr-parser.cjs +399 -0
- package/pp-core/bin/lib/agent-command-router.cjs +68 -0
- package/pp-core/bin/lib/agent-install-check.cjs +143 -0
- package/pp-core/bin/lib/artifacts.cjs +51 -0
- package/pp-core/bin/lib/audit-command-router.cjs +61 -0
- package/pp-core/bin/lib/audit.cjs +743 -0
- package/pp-core/bin/lib/capability-activation.cjs +113 -0
- package/pp-core/bin/lib/capability-registry.cjs +3727 -0
- package/pp-core/bin/lib/capability-state.cjs +497 -0
- package/pp-core/bin/lib/capability-writer.cjs +355 -0
- package/pp-core/bin/lib/check-command-router.cjs +800 -0
- package/pp-core/bin/lib/cjs-command-router-adapter.cjs +81 -0
- package/pp-core/bin/lib/cli-exit.cjs +61 -0
- package/pp-core/bin/lib/clock.cjs +95 -0
- package/pp-core/bin/lib/clusters.cjs +131 -0
- package/pp-core/bin/lib/code-review-flags.cjs +59 -0
- package/pp-core/bin/lib/command-aliases.cjs +809 -0
- package/pp-core/bin/lib/command-arg-projection.cjs +55 -0
- package/pp-core/bin/lib/command-roster.cjs +19 -0
- package/pp-core/bin/lib/command-routing-hub.cjs +300 -0
- package/pp-core/bin/lib/commands.cjs +1244 -0
- package/pp-core/bin/lib/config-loader.cjs +714 -0
- package/pp-core/bin/lib/config-schema.cjs +58 -0
- package/pp-core/bin/lib/config-types.cjs +20 -0
- package/pp-core/bin/lib/config.cjs +796 -0
- package/pp-core/bin/lib/configuration.cjs +209 -0
- package/pp-core/bin/lib/context-utilization.cjs +48 -0
- package/pp-core/bin/lib/core-utils.cjs +198 -0
- package/pp-core/bin/lib/decisions.cjs +136 -0
- package/pp-core/bin/lib/docs.cjs +264 -0
- package/pp-core/bin/lib/drift.cjs +364 -0
- package/pp-core/bin/lib/edge-probe.cjs +196 -0
- package/pp-core/bin/lib/fallow-runner.cjs +153 -0
- package/pp-core/bin/lib/federated-config.cjs +182 -0
- package/pp-core/bin/lib/frontmatter.cjs +494 -0
- package/pp-core/bin/lib/gap-checker.cjs +260 -0
- package/pp-core/bin/lib/git-base-branch.cjs +220 -0
- package/pp-core/bin/lib/graphify-command-router.cjs +72 -0
- package/pp-core/bin/lib/graphify.cjs +472 -0
- package/pp-core/bin/lib/gsd2-import.cjs +456 -0
- package/pp-core/bin/lib/init-command-router.cjs +62 -0
- package/pp-core/bin/lib/init.cjs +1912 -0
- package/pp-core/bin/lib/install-profiles.cjs +814 -0
- package/pp-core/bin/lib/installer-migration-authoring.cjs +122 -0
- package/pp-core/bin/lib/installer-migration-report.cjs +351 -0
- package/pp-core/bin/lib/installer-migrations/000-first-time-baseline.cjs +225 -0
- package/pp-core/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +48 -0
- package/pp-core/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +94 -0
- package/pp-core/bin/lib/installer-migrations/003-rename-get-shit-done-to-gsd-core.cjs +108 -0
- package/pp-core/bin/lib/installer-migrations/004-prune-stale-pristine-snapshots.cjs +123 -0
- package/pp-core/bin/lib/installer-migrations/005-rename-gsd-core-to-pp-core.cjs +109 -0
- package/pp-core/bin/lib/installer-migrations/006-rename-gsd-command-namespace.cjs +135 -0
- package/pp-core/bin/lib/installer-migrations.cjs +823 -0
- package/pp-core/bin/lib/intel-command-router.cjs +119 -0
- package/pp-core/bin/lib/intel.cjs +584 -0
- package/pp-core/bin/lib/io.cjs +220 -0
- package/pp-core/bin/lib/learnings.cjs +270 -0
- package/pp-core/bin/lib/legacy-cleanup.cjs +253 -0
- package/pp-core/bin/lib/loop-host-contract.cjs +105 -0
- package/pp-core/bin/lib/loop-resolver.cjs +479 -0
- package/pp-core/bin/lib/milestone.cjs +381 -0
- package/pp-core/bin/lib/model-catalog.cjs +154 -0
- package/pp-core/bin/lib/model-profiles.cjs +24 -0
- package/pp-core/bin/lib/model-resolver.cjs +467 -0
- package/pp-core/bin/lib/observability/event.cjs +51 -0
- package/pp-core/bin/lib/observability/logger.cjs +146 -0
- package/pp-core/bin/lib/observability/redaction.cjs +48 -0
- package/pp-core/bin/lib/package-identity.cjs +35 -0
- package/pp-core/bin/lib/package-legitimacy.cjs +368 -0
- package/pp-core/bin/lib/phase-command-router.cjs +209 -0
- package/pp-core/bin/lib/phase-id.cjs +213 -0
- package/pp-core/bin/lib/phase-lifecycle.cjs +74 -0
- package/pp-core/bin/lib/phase-locator.cjs +145 -0
- package/pp-core/bin/lib/phase.cjs +1446 -0
- package/pp-core/bin/lib/phases-command-router.cjs +43 -0
- package/pp-core/bin/lib/plan-drift-guard.cjs +117 -0
- package/pp-core/bin/lib/plan-scan.cjs +91 -0
- package/pp-core/bin/lib/planning-workspace.cjs +245 -0
- package/pp-core/bin/lib/probe-core.cjs +402 -0
- package/pp-core/bin/lib/profile-output.cjs +1164 -0
- package/pp-core/bin/lib/profile-pipeline-command-router.cjs +138 -0
- package/pp-core/bin/lib/profile-pipeline.cjs +519 -0
- package/pp-core/bin/lib/prohibition-enforcement.cjs +660 -0
- package/pp-core/bin/lib/project-root.cjs +119 -0
- package/pp-core/bin/lib/prompt-budget.cjs +305 -0
- package/pp-core/bin/lib/research-provider.cjs +137 -0
- package/pp-core/bin/lib/research-store.cjs +167 -0
- package/pp-core/bin/lib/review-reviewer-selection.cjs +121 -0
- package/pp-core/bin/lib/roadmap-command-router.cjs +166 -0
- package/pp-core/bin/lib/roadmap-parser.cjs +456 -0
- package/pp-core/bin/lib/roadmap-upgrade.cjs +476 -0
- package/pp-core/bin/lib/roadmap.cjs +738 -0
- package/pp-core/bin/lib/runtime-artifact-conversion.cjs +1966 -0
- package/pp-core/bin/lib/runtime-artifact-layout.cjs +342 -0
- package/pp-core/bin/lib/runtime-config-adapter-registry.cjs +103 -0
- package/pp-core/bin/lib/runtime-homes.cjs +272 -0
- package/pp-core/bin/lib/runtime-hooks-surface.cjs +1460 -0
- package/pp-core/bin/lib/runtime-name-policy.cjs +97 -0
- package/pp-core/bin/lib/runtime-slash.cjs +137 -0
- package/pp-core/bin/lib/schema-detect.cjs +159 -0
- package/pp-core/bin/lib/secrets.cjs +34 -0
- package/pp-core/bin/lib/security.cjs +480 -0
- package/pp-core/bin/lib/semver-compare.cjs +42 -0
- package/pp-core/bin/lib/shell-command-projection.cjs +550 -0
- package/pp-core/bin/lib/state-command-router.cjs +172 -0
- package/pp-core/bin/lib/state-document.cjs +312 -0
- package/pp-core/bin/lib/state.cjs +2587 -0
- package/pp-core/bin/lib/surface.cjs +505 -0
- package/pp-core/bin/lib/task-command-router.cjs +85 -0
- package/pp-core/bin/lib/teams-status.cjs +74 -0
- package/pp-core/bin/lib/template.cjs +246 -0
- package/pp-core/bin/lib/uat-predicate.cjs +329 -0
- package/pp-core/bin/lib/uat.cjs +359 -0
- package/pp-core/bin/lib/ui-safety-gate.cjs +98 -0
- package/pp-core/bin/lib/update-context.cjs +221 -0
- package/pp-core/bin/lib/validate-command-router.cjs +91 -0
- package/pp-core/bin/lib/validate.cjs +122 -0
- package/pp-core/bin/lib/verification-command-router.cjs +31 -0
- package/pp-core/bin/lib/verification.cjs +196 -0
- package/pp-core/bin/lib/verify-command-router.cjs +44 -0
- package/pp-core/bin/lib/verify.cjs +1932 -0
- package/pp-core/bin/lib/workstream-inventory-builder.cjs +81 -0
- package/pp-core/bin/lib/workstream-inventory.cjs +147 -0
- package/pp-core/bin/lib/workstream-name-policy.cjs +91 -0
- package/pp-core/bin/lib/workstream.cjs +386 -0
- package/pp-core/bin/lib/worktree-base-ref.cjs +350 -0
- package/pp-core/bin/lib/worktree-safety.cjs +985 -0
- package/pp-core/bin/pp-tools.cjs +2239 -0
- package/pp-core/bin/pp_run +20 -0
- package/pp-core/bin/shared/config-defaults.manifest.json +97 -0
- package/pp-core/bin/shared/config-schema.manifest.json +176 -0
- package/pp-core/bin/shared/model-catalog.json +160 -0
- package/pp-core/bin/shared/runtime-aliases.manifest.json +79 -0
- package/pp-core/bin/verify-reapply-patches.cjs +400 -0
- package/pp-core/contexts/dev.md +21 -0
- package/pp-core/contexts/research.md +22 -0
- package/pp-core/contexts/review.md +23 -0
- package/pp-core/references/agent-contracts.md +79 -0
- package/pp-core/references/ai-evals.md +156 -0
- package/pp-core/references/ai-frameworks.md +186 -0
- package/pp-core/references/artifact-types.md +131 -0
- package/pp-core/references/autonomous-smart-discuss.md +277 -0
- package/pp-core/references/checkpoints.md +814 -0
- package/pp-core/references/common-bug-patterns.md +114 -0
- package/pp-core/references/context-budget.md +85 -0
- package/pp-core/references/continuation-format.md +253 -0
- package/pp-core/references/debugger-philosophy.md +76 -0
- package/pp-core/references/decimal-phase-calculation.md +64 -0
- package/pp-core/references/doc-conflict-engine.md +91 -0
- package/pp-core/references/domain-probes.md +125 -0
- package/pp-core/references/edge-probe-fixtures/01-round-half-even/expected-coverage.json +7 -0
- package/pp-core/references/edge-probe-fixtures/01-round-half-even/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/02-merge-intervals/expected-coverage.json +8 -0
- package/pp-core/references/edge-probe-fixtures/02-merge-intervals/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/03-truncate-graphemes/expected-coverage.json +7 -0
- package/pp-core/references/edge-probe-fixtures/03-truncate-graphemes/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/04-money-rounding/expected-coverage.json +7 -0
- package/pp-core/references/edge-probe-fixtures/04-money-rounding/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/05-list-dedupe/expected-coverage.json +8 -0
- package/pp-core/references/edge-probe-fixtures/05-list-dedupe/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/06-resolved-mixed/expected-coverage.json +8 -0
- package/pp-core/references/edge-probe-fixtures/06-resolved-mixed/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/06-resolved-mixed/resolutions.json +4 -0
- package/pp-core/references/edge-probe.md +272 -0
- package/pp-core/references/execute-mvp-tdd.md +81 -0
- package/pp-core/references/executor-examples.md +110 -0
- package/pp-core/references/few-shot-examples/plan-checker.md +73 -0
- package/pp-core/references/few-shot-examples/verifier.md +109 -0
- package/pp-core/references/gate-prompts.md +100 -0
- package/pp-core/references/gates.md +70 -0
- package/pp-core/references/git-integration.md +298 -0
- package/pp-core/references/git-planning-commit.md +40 -0
- package/pp-core/references/ios-scaffold.md +123 -0
- package/pp-core/references/loop-hook-dispatch.md +61 -0
- package/pp-core/references/mandatory-initial-read.md +2 -0
- package/pp-core/references/model-profile-resolution.md +38 -0
- package/pp-core/references/model-profiles.md +245 -0
- package/pp-core/references/mvp-concepts.md +49 -0
- package/pp-core/references/phase-argument-parsing.md +61 -0
- package/pp-core/references/planner-antipatterns.md +176 -0
- package/pp-core/references/planner-chunked.md +49 -0
- package/pp-core/references/planner-gap-closure.md +62 -0
- package/pp-core/references/planner-graphify-auto-update.md +67 -0
- package/pp-core/references/planner-guidance.md +186 -0
- package/pp-core/references/planner-human-verify-mode.md +57 -0
- package/pp-core/references/planner-interface-context.md +62 -0
- package/pp-core/references/planner-load-graph-context.md +36 -0
- package/pp-core/references/planner-mvp-mode.md +53 -0
- package/pp-core/references/planner-reviews.md +42 -0
- package/pp-core/references/planner-revision.md +87 -0
- package/pp-core/references/planner-source-audit.md +73 -0
- package/pp-core/references/planning-config.md +477 -0
- package/pp-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json +14 -0
- package/pp-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json +4 -0
- package/pp-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json +32 -0
- package/pp-core/references/prohibition-probe.md +326 -0
- package/pp-core/references/project-skills-discovery.md +19 -0
- package/pp-core/references/questioning.md +162 -0
- package/pp-core/references/research-documentation-lookup.md +29 -0
- package/pp-core/references/research-philosophy.md +29 -0
- package/pp-core/references/research-verification-protocol.md +27 -0
- package/pp-core/references/revision-loop.md +97 -0
- package/pp-core/references/scout-codebase.md +51 -0
- package/pp-core/references/skeleton-template.md +48 -0
- package/pp-core/references/sketch-interactivity.md +41 -0
- package/pp-core/references/sketch-theme-system.md +94 -0
- package/pp-core/references/sketch-tooling.md +45 -0
- package/pp-core/references/sketch-variant-patterns.md +81 -0
- package/pp-core/references/spidr-splitting.md +69 -0
- package/pp-core/references/tdd.md +330 -0
- package/pp-core/references/thinking-models-debug.md +44 -0
- package/pp-core/references/thinking-models-execution.md +50 -0
- package/pp-core/references/thinking-models-planning.md +62 -0
- package/pp-core/references/thinking-models-research.md +50 -0
- package/pp-core/references/thinking-models-verification.md +55 -0
- package/pp-core/references/thinking-partner.md +96 -0
- package/pp-core/references/ui-brand.md +162 -0
- package/pp-core/references/universal-anti-patterns.md +63 -0
- package/pp-core/references/user-profiling.md +681 -0
- package/pp-core/references/user-story-template.md +58 -0
- package/pp-core/references/verification-overrides.md +227 -0
- package/pp-core/references/verification-patterns.md +612 -0
- package/pp-core/references/verify-mvp-mode.md +85 -0
- package/pp-core/references/workstream-flag.md +111 -0
- package/pp-core/references/worktree-branch-check.md +44 -0
- package/pp-core/references/worktree-path-safety.md +67 -0
- package/pp-core/templates/AI-SPEC.md +246 -0
- package/pp-core/templates/DEBUG.md +169 -0
- package/pp-core/templates/README.md +77 -0
- package/pp-core/templates/SECURITY.md +61 -0
- package/pp-core/templates/UAT.md +265 -0
- package/pp-core/templates/UI-SPEC.md +100 -0
- package/pp-core/templates/VALIDATION.md +76 -0
- package/pp-core/templates/claude-md.md +145 -0
- package/pp-core/templates/codebase/architecture.md +255 -0
- package/pp-core/templates/codebase/concerns.md +310 -0
- package/pp-core/templates/codebase/conventions.md +307 -0
- package/pp-core/templates/codebase/integrations.md +280 -0
- package/pp-core/templates/codebase/stack.md +186 -0
- package/pp-core/templates/codebase/structure.md +285 -0
- package/pp-core/templates/codebase/testing.md +480 -0
- package/pp-core/templates/config.json +62 -0
- package/pp-core/templates/context.md +352 -0
- package/pp-core/templates/continue-here.md +78 -0
- package/pp-core/templates/copilot-instructions.md +7 -0
- package/pp-core/templates/debug-subagent-prompt.md +91 -0
- package/pp-core/templates/dev-preferences.md +21 -0
- package/pp-core/templates/discovery.md +146 -0
- package/pp-core/templates/discussion-log.md +63 -0
- package/pp-core/templates/milestone-archive.md +123 -0
- package/pp-core/templates/milestone.md +115 -0
- package/pp-core/templates/phase-prompt.md +610 -0
- package/pp-core/templates/planner-subagent-prompt.md +117 -0
- package/pp-core/templates/project.md +203 -0
- package/pp-core/templates/requirements.md +231 -0
- package/pp-core/templates/research-project/ARCHITECTURE.md +204 -0
- package/pp-core/templates/research-project/FEATURES.md +147 -0
- package/pp-core/templates/research-project/PITFALLS.md +200 -0
- package/pp-core/templates/research-project/STACK.md +120 -0
- package/pp-core/templates/research-project/SUMMARY.md +170 -0
- package/pp-core/templates/research.md +592 -0
- package/pp-core/templates/retrospective.md +54 -0
- package/pp-core/templates/roadmap.md +202 -0
- package/pp-core/templates/spec.md +333 -0
- package/pp-core/templates/state.md +195 -0
- package/pp-core/templates/summary-complex.md +60 -0
- package/pp-core/templates/summary-minimal.md +42 -0
- package/pp-core/templates/summary-standard.md +49 -0
- package/pp-core/templates/summary.md +249 -0
- package/pp-core/templates/user-profile.md +146 -0
- package/pp-core/templates/user-setup.md +311 -0
- package/pp-core/templates/verification-report.md +335 -0
- package/pp-core/workflows/_runtime-launcher.snippet.sh +1 -0
- package/pp-core/workflows/add-backlog.md +91 -0
- package/pp-core/workflows/add-phase.md +113 -0
- package/pp-core/workflows/add-tests.md +355 -0
- package/pp-core/workflows/add-todo.md +161 -0
- package/pp-core/workflows/ai-integration-phase.md +295 -0
- package/pp-core/workflows/analyze-dependencies.md +96 -0
- package/pp-core/workflows/audit-fix.md +178 -0
- package/pp-core/workflows/audit-milestone.md +362 -0
- package/pp-core/workflows/audit-uat.md +110 -0
- package/pp-core/workflows/autonomous.md +886 -0
- package/pp-core/workflows/check-todos.md +180 -0
- package/pp-core/workflows/cleanup.md +195 -0
- package/pp-core/workflows/code-review-fix.md +506 -0
- package/pp-core/workflows/code-review.md +696 -0
- package/pp-core/workflows/complete-milestone.md +857 -0
- package/pp-core/workflows/debug.md +237 -0
- package/pp-core/workflows/diagnose-issues.md +245 -0
- package/pp-core/workflows/discovery-phase.md +291 -0
- package/pp-core/workflows/discovery-sprint.md +1546 -0
- package/pp-core/workflows/discuss-phase/modes/advisor.md +176 -0
- package/pp-core/workflows/discuss-phase/modes/all.md +28 -0
- package/pp-core/workflows/discuss-phase/modes/analyze.md +44 -0
- package/pp-core/workflows/discuss-phase/modes/auto.md +57 -0
- package/pp-core/workflows/discuss-phase/modes/batch.md +52 -0
- package/pp-core/workflows/discuss-phase/modes/chain.md +98 -0
- package/pp-core/workflows/discuss-phase/modes/default.md +141 -0
- package/pp-core/workflows/discuss-phase/modes/power.md +44 -0
- package/pp-core/workflows/discuss-phase/modes/text.md +55 -0
- package/pp-core/workflows/discuss-phase/templates/checkpoint.json +18 -0
- package/pp-core/workflows/discuss-phase/templates/context.md +136 -0
- package/pp-core/workflows/discuss-phase/templates/discussion-log.md +50 -0
- package/pp-core/workflows/discuss-phase-assumptions.md +675 -0
- package/pp-core/workflows/discuss-phase-power.md +291 -0
- package/pp-core/workflows/discuss-phase.md +520 -0
- package/pp-core/workflows/do.md +111 -0
- package/pp-core/workflows/docs-update.md +1168 -0
- package/pp-core/workflows/edit-phase.md +295 -0
- package/pp-core/workflows/eval-review.md +159 -0
- package/pp-core/workflows/execute-phase/steps/codebase-drift-gate.md +95 -0
- package/pp-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +94 -0
- package/pp-core/workflows/execute-phase/steps/post-merge-gate.md +117 -0
- package/pp-core/workflows/execute-phase/steps/worktree-recovery-policy.md +9 -0
- package/pp-core/workflows/execute-phase.md +1707 -0
- package/pp-core/workflows/execute-plan.md +541 -0
- package/pp-core/workflows/explore.md +146 -0
- package/pp-core/workflows/extract-learnings.md +243 -0
- package/pp-core/workflows/fast.md +124 -0
- package/pp-core/workflows/forensics.md +279 -0
- package/pp-core/workflows/graduation.md +196 -0
- package/pp-core/workflows/health.md +224 -0
- package/pp-core/workflows/help/modes/brief.md +22 -0
- package/pp-core/workflows/help/modes/default.md +50 -0
- package/pp-core/workflows/help/modes/full.md +791 -0
- package/pp-core/workflows/help/modes/topic.md +74 -0
- package/pp-core/workflows/help.md +24 -0
- package/pp-core/workflows/import.md +256 -0
- package/pp-core/workflows/inbox.md +387 -0
- package/pp-core/workflows/ingest-docs.md +340 -0
- package/pp-core/workflows/insert-phase.md +152 -0
- package/pp-core/workflows/list-phase-assumptions.md +178 -0
- package/pp-core/workflows/list-workspaces.md +57 -0
- package/pp-core/workflows/manager.md +435 -0
- package/pp-core/workflows/map-codebase.md +444 -0
- package/pp-core/workflows/milestone-summary.md +224 -0
- package/pp-core/workflows/mvp-phase.md +222 -0
- package/pp-core/workflows/new-milestone.md +643 -0
- package/pp-core/workflows/new-project.md +1563 -0
- package/pp-core/workflows/new-workspace.md +240 -0
- package/pp-core/workflows/next.md +347 -0
- package/pp-core/workflows/node-repair.md +92 -0
- package/pp-core/workflows/note.md +158 -0
- package/pp-core/workflows/pause-work.md +250 -0
- package/pp-core/workflows/plan-milestone-gaps.md +281 -0
- package/pp-core/workflows/plan-phase.md +1755 -0
- package/pp-core/workflows/plan-review-convergence.md +369 -0
- package/pp-core/workflows/plant-seed.md +230 -0
- package/pp-core/workflows/pr-branch.md +159 -0
- package/pp-core/workflows/profile-user.md +455 -0
- package/pp-core/workflows/progress.md +756 -0
- package/pp-core/workflows/quick.md +1045 -0
- package/pp-core/workflows/reapply-patches.md +443 -0
- package/pp-core/workflows/remove-phase.md +156 -0
- package/pp-core/workflows/remove-workspace.md +108 -0
- package/pp-core/workflows/resume-project.md +348 -0
- package/pp-core/workflows/review.md +765 -0
- package/pp-core/workflows/scan.md +107 -0
- package/pp-core/workflows/secure-phase.md +184 -0
- package/pp-core/workflows/session-report.md +146 -0
- package/pp-core/workflows/settings-advanced.md +816 -0
- package/pp-core/workflows/settings-integrations.md +312 -0
- package/pp-core/workflows/settings.md +592 -0
- package/pp-core/workflows/ship.md +465 -0
- package/pp-core/workflows/sketch-wrap-up.md +286 -0
- package/pp-core/workflows/sketch.md +361 -0
- package/pp-core/workflows/spec-phase.md +495 -0
- package/pp-core/workflows/spike-wrap-up.md +307 -0
- package/pp-core/workflows/spike.md +453 -0
- package/pp-core/workflows/stats.md +80 -0
- package/pp-core/workflows/sync-skills.md +182 -0
- package/pp-core/workflows/thread.md +222 -0
- package/pp-core/workflows/transition.md +694 -0
- package/pp-core/workflows/ui-phase.md +328 -0
- package/pp-core/workflows/ui-review.md +193 -0
- package/pp-core/workflows/ultraplan-phase.md +199 -0
- package/pp-core/workflows/undo.md +314 -0
- package/pp-core/workflows/update.md +501 -0
- package/pp-core/workflows/validate-phase.md +183 -0
- package/pp-core/workflows/verify-phase.md +569 -0
- package/pp-core/workflows/verify-work.md +804 -0
- package/scripts/affected-tests-lib.cjs +554 -0
- package/scripts/audit-workflow-script-paths.cjs +73 -0
- package/scripts/base64-scan.sh +351 -0
- package/scripts/build-hooks.js +254 -0
- package/scripts/changeset/README.md +129 -0
- package/scripts/changeset/cli.cjs +597 -0
- package/scripts/changeset/github-release-notes.cjs +199 -0
- package/scripts/changeset/lint.cjs +147 -0
- package/scripts/changeset/new.cjs +151 -0
- package/scripts/changeset/parse.cjs +114 -0
- package/scripts/changeset/render.cjs +34 -0
- package/scripts/changeset/serialize.cjs +130 -0
- package/scripts/check-alias-drift.cjs +114 -0
- package/scripts/check-env.cjs +312 -0
- package/scripts/check-npm-integrity.cjs +215 -0
- package/scripts/ci-guard-runner.cjs +22 -0
- package/scripts/ci-prepare-test-scope.cjs +93 -0
- package/scripts/ci-rebase-check.cjs +86 -0
- package/scripts/ci-test-scope.cjs +441 -0
- package/scripts/command-contract-helpers.cjs +64 -0
- package/scripts/diff-touches-shipped-paths.cjs +149 -0
- package/scripts/fix-slash-commands.cjs +161 -0
- package/scripts/gen-capability-registry.cjs +2646 -0
- package/scripts/gen-commands-reference.cjs +139 -0
- package/scripts/gen-inventory-manifest.cjs +114 -0
- package/scripts/gen-loop-host-contract.cjs +526 -0
- package/scripts/gen-research-agents.cjs +276 -0
- package/scripts/generate-package-identity.cjs +134 -0
- package/scripts/issue-dedupe.cjs +278 -0
- package/scripts/issue-version-gate.cjs +140 -0
- package/scripts/lib/allowlist-ratchet.cjs +236 -0
- package/scripts/lib/cli-exit.cjs +56 -0
- package/scripts/lint-allow-test-rule-refs.allowlist.json +328 -0
- package/scripts/lint-allow-test-rule-refs.cjs +162 -0
- package/scripts/lint-command-contract.cjs +118 -0
- package/scripts/lint-descriptions.cjs +87 -0
- package/scripts/lint-docs-required.cjs +222 -0
- package/scripts/lint-legacy-dir-name.cjs +166 -0
- package/scripts/lint-package-identity-drift.cjs +141 -0
- package/scripts/lint-pr-check-project-dir.cjs +99 -0
- package/scripts/lint-regression-test-names.allowlist.json +269 -0
- package/scripts/lint-regression-test-names.cjs +117 -0
- package/scripts/lint-shell-command-projection-drift.cjs +62 -0
- package/scripts/lint-skill-deps.cjs +185 -0
- package/scripts/lint-test-file-count.allowlist.json +181 -0
- package/scripts/lint-test-file-count.cjs +246 -0
- package/scripts/lint-windows-test-portability.cjs +178 -0
- package/scripts/mutation-matrix.cjs +323 -0
- package/scripts/pr-target-policy.cjs +63 -0
- package/scripts/pr-template-policy.cjs +268 -0
- package/scripts/prompt-injection-scan.sh +207 -0
- package/scripts/registry-smoke.cjs +337 -0
- package/scripts/release-notes/discord-release-summary.cjs +373 -0
- package/scripts/release-notes/format-github-release-notes.cjs +261 -0
- package/scripts/release-tarball-smoke.cjs +763 -0
- package/scripts/research-profiles.cjs +149 -0
- package/scripts/run-affected-tests.cjs +7 -0
- package/scripts/run-tests.cjs +589 -0
- package/scripts/secret-scan-lint.sh +231 -0
- package/scripts/secret-scan.sh +358 -0
- package/scripts/setup-branch-protection.sh +234 -0
- package/scripts/strip-prose-atrefs.cjs +106 -0
- package/scripts/sync-manifest-versions.cjs +119 -0
- package/scripts/sync-next-version.cjs +133 -0
- package/scripts/sync-rulesets.sh +34 -0
- package/scripts/sync-runtime-launcher.cjs +425 -0
- package/scripts/test-failure-reasons.cjs +34 -0
- package/scripts/update-size-baseline.cjs +68 -0
- package/scripts/verify-npm-publish.cjs +240 -0
- package/scripts/verify-opengsd-sweep.cjs +288 -0
- package/scripts/verify-phase-02-rename.sh +258 -0
- package/scripts/verify-phase-03-rename.sh +376 -0
- package/scripts/workflow-policy.cjs +483 -0
- package/scripts/workflow-size.cjs +90 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* lint-windows-test-portability.cjs — flag tests that combine chmod exec-bit
|
|
5
|
+
* with bare sh/bash -c without a platform guard.
|
|
6
|
+
*
|
|
7
|
+
* ## Why
|
|
8
|
+
*
|
|
9
|
+
* Windows Git Bash (msys2) does not honour Node's chmod exec bit for
|
|
10
|
+
* PATH-executing extension-less scripts. A test that (a) makes a fixture
|
|
11
|
+
* executable via chmodSync and (b) runs it with `sh -c`/`bash -c` will pass
|
|
12
|
+
* on Mac/Linux but fail only in the CI `test (windows-latest, *)` /
|
|
13
|
+
* `full test (windows-latest, *)` lanes, producing a hard-to-diagnose
|
|
14
|
+
* false-negative gate. See CONTEXT.md → DEFECT.WINDOWS-TEST-PORTABILITY.
|
|
15
|
+
*
|
|
16
|
+
* ## What this enforces
|
|
17
|
+
*
|
|
18
|
+
* For every file in tests/**\/*.test.cjs (recursive, excluding node_modules):
|
|
19
|
+
* - makesExecutable: contains chmodSync?( with an exec-bit octal literal
|
|
20
|
+
* - shellDashC: contains a sh/bash -c invocation (array form or string literal)
|
|
21
|
+
* - guarded: contains a process.platform / os.platform() / win32 / isWindows guard
|
|
22
|
+
* - optOut: contains the literal `windows-portability-ok`
|
|
23
|
+
* VIOLATION = makesExecutable && shellDashC && !guarded && !optOut
|
|
24
|
+
*
|
|
25
|
+
* ## Remediation
|
|
26
|
+
*
|
|
27
|
+
* Gate the bare-command execution with `if (process.platform !== 'win32')`,
|
|
28
|
+
* or invoke via an explicit interpreter (`sh <path>`), or annotate
|
|
29
|
+
* `// windows-portability-ok: <reason>`.
|
|
30
|
+
*
|
|
31
|
+
* ## Export contract (for unit tests)
|
|
32
|
+
*
|
|
33
|
+
* When required as a module (`require.main !== module`) this file exports
|
|
34
|
+
* `scanContent(source)` → { makesExecutable, shellDashC, guarded, optOut, violation }.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
const fs = require('fs');
|
|
38
|
+
const path = require('path');
|
|
39
|
+
|
|
40
|
+
// ─── Detection regexes ──────────────────────────────────────────────────────
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Match chmod/chmodSync( calls with an octal mode literal whose exec bits are
|
|
44
|
+
* set, e.g. `fs.chmodSync(p, 0o755)` or `chmod(file, 0o111)`.
|
|
45
|
+
*/
|
|
46
|
+
const CHMOD_RE = /chmod(?:Sync)?\s*\([^,;]+,\s*0o([0-7]{3})\b/g;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Array form: execFileSync/spawnSync/exec* with 'sh' or 'bash' (optionally
|
|
50
|
+
* prefixed) as the first arg and '-c' as an element of the args array.
|
|
51
|
+
* e.g. execFileSync('bash', ['-c', ...]) or spawnSync('/bin/sh', ['-c', ...])
|
|
52
|
+
*/
|
|
53
|
+
const SHELL_ARRAY_RE =
|
|
54
|
+
/(?:execFile(?:Sync)?|spawnSync|spawn|exec)\s*\(\s*['"`](?:\/(?:usr\/)?bin\/)?(?:bash|sh)['"`]\s*,\s*\[[^\]]*['"]-c['"]/;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* String-literal form: any string containing `bash -c` or `sh -c`.
|
|
58
|
+
*/
|
|
59
|
+
const SHELL_STRING_RE = /['"`][^'"`\n]*(?:bash|sh)\s+-c[^'"`\n]*['"`]/;
|
|
60
|
+
|
|
61
|
+
/** Platform guard presence. */
|
|
62
|
+
const GUARD_RE = /process\.platform|os\.platform\s*\(|\bwin32\b|\bisWindows\b/;
|
|
63
|
+
|
|
64
|
+
/** Opt-out annotation. */
|
|
65
|
+
const OPT_OUT_RE = /windows-portability-ok/;
|
|
66
|
+
|
|
67
|
+
// ─── Pure scanning function (exported for unit tests) ────────────────────────
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Scan a single file's source text and return detection flags.
|
|
71
|
+
*
|
|
72
|
+
* @param {string} source - The file contents as a string.
|
|
73
|
+
* @returns {{ makesExecutable: boolean, shellDashC: boolean, guarded: boolean, optOut: boolean, violation: boolean }}
|
|
74
|
+
*/
|
|
75
|
+
function scanContent(source) {
|
|
76
|
+
// Reset stateful regex before use.
|
|
77
|
+
CHMOD_RE.lastIndex = 0;
|
|
78
|
+
|
|
79
|
+
let makesExecutable = false;
|
|
80
|
+
let match;
|
|
81
|
+
while ((match = CHMOD_RE.exec(source)) !== null) {
|
|
82
|
+
const oct = match[1];
|
|
83
|
+
if ((parseInt(oct, 8) & 0o111) !== 0) {
|
|
84
|
+
makesExecutable = true;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const shellDashC = SHELL_ARRAY_RE.test(source) || SHELL_STRING_RE.test(source);
|
|
90
|
+
const guarded = GUARD_RE.test(source);
|
|
91
|
+
const optOut = OPT_OUT_RE.test(source);
|
|
92
|
+
const violation = makesExecutable && shellDashC && !guarded && !optOut;
|
|
93
|
+
|
|
94
|
+
return { makesExecutable, shellDashC, guarded, optOut, violation };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ─── Filesystem walker ───────────────────────────────────────────────────────
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Recursively collect all *.test.cjs files under `dir`, excluding node_modules.
|
|
101
|
+
*
|
|
102
|
+
* @param {string} dir
|
|
103
|
+
* @param {string[]} [acc]
|
|
104
|
+
* @returns {string[]}
|
|
105
|
+
*/
|
|
106
|
+
function collectTestFiles(dir, acc) {
|
|
107
|
+
acc = acc || [];
|
|
108
|
+
let entries;
|
|
109
|
+
try {
|
|
110
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
111
|
+
} catch {
|
|
112
|
+
return acc;
|
|
113
|
+
}
|
|
114
|
+
for (const entry of entries) {
|
|
115
|
+
if (entry.name === 'node_modules') continue;
|
|
116
|
+
const full = path.join(dir, entry.name);
|
|
117
|
+
if (entry.isDirectory()) {
|
|
118
|
+
collectTestFiles(full, acc);
|
|
119
|
+
} else if (entry.isFile() && entry.name.endsWith('.test.cjs')) {
|
|
120
|
+
acc.push(full);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return acc;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// ─── Main ────────────────────────────────────────────────────────────────────
|
|
127
|
+
|
|
128
|
+
function main() {
|
|
129
|
+
const ROOT = path.join(__dirname, '..');
|
|
130
|
+
const TESTS_DIR = path.join(ROOT, 'tests');
|
|
131
|
+
|
|
132
|
+
const files = collectTestFiles(TESTS_DIR);
|
|
133
|
+
const violations = [];
|
|
134
|
+
|
|
135
|
+
for (const file of files) {
|
|
136
|
+
let source;
|
|
137
|
+
try {
|
|
138
|
+
source = fs.readFileSync(file, 'utf8');
|
|
139
|
+
} catch {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const { violation } = scanContent(source);
|
|
143
|
+
if (violation) {
|
|
144
|
+
const rel = path.relative(ROOT, file).replace(/\\/g, '/');
|
|
145
|
+
violations.push(rel);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (violations.length > 0) {
|
|
150
|
+
for (const rel of violations) {
|
|
151
|
+
process.stderr.write(
|
|
152
|
+
`${rel}: chmod-executable + sh/bash -c with no platform guard\n`,
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
process.stderr.write(
|
|
156
|
+
'\nWindows Git Bash does not honor Node\'s chmod exec bit for ' +
|
|
157
|
+
'PATH-executing extension-less scripts ' +
|
|
158
|
+
'(CONTEXT.md → DEFECT.WINDOWS-TEST-PORTABILITY). ' +
|
|
159
|
+
'Gate the bare-command execution with ' +
|
|
160
|
+
'`if (process.platform !== \'win32\')`, or invoke via an explicit ' +
|
|
161
|
+
'interpreter (`sh <path>`), or annotate ' +
|
|
162
|
+
'`// windows-portability-ok: <reason>`.\n',
|
|
163
|
+
);
|
|
164
|
+
process.exitCode = 1;
|
|
165
|
+
} else {
|
|
166
|
+
console.log(
|
|
167
|
+
`ok lint-windows-test-portability: ${files.length} file(s) scanned, no violations`,
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// ─── Module boundary ─────────────────────────────────────────────────────────
|
|
173
|
+
|
|
174
|
+
if (require.main === module) {
|
|
175
|
+
main();
|
|
176
|
+
} else {
|
|
177
|
+
module.exports = { scanContent };
|
|
178
|
+
}
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* scripts/mutation-matrix.cjs
|
|
6
|
+
*
|
|
7
|
+
* Single source of truth for the ADR-457 Stryker mutation gate dynamic matrix.
|
|
8
|
+
*
|
|
9
|
+
* Computes which covered modules changed vs a base ref and emits a GitHub
|
|
10
|
+
* Actions matrix JSON so CI can run one Stryker shard per changed module in
|
|
11
|
+
* parallel rather than a single serial run over all modules.
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* node scripts/mutation-matrix.cjs --base origin/next
|
|
15
|
+
* printf 'src/config-schema.cts\n' | node scripts/mutation-matrix.cjs
|
|
16
|
+
* node scripts/mutation-matrix.cjs --base origin/next --print
|
|
17
|
+
*
|
|
18
|
+
* Output (stdout, default): JSON object
|
|
19
|
+
* {
|
|
20
|
+
* "has_work": "true"|"false",
|
|
21
|
+
* "matrix": {
|
|
22
|
+
* "include": [
|
|
23
|
+
* { "name": "<module>", "mutate": "pp-core/bin/lib/<module>.cjs", "tests": "<space-joined test files>" },
|
|
24
|
+
* ...
|
|
25
|
+
* ]
|
|
26
|
+
* }
|
|
27
|
+
* }
|
|
28
|
+
*
|
|
29
|
+
* Exit codes: 0 always (empty matrix is not an error, has_work "false").
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
const { execFileSync } = require('child_process');
|
|
33
|
+
const { readFileSync } = require('fs');
|
|
34
|
+
|
|
35
|
+
const { ExitError, runMain } = require('./lib/cli-exit.cjs');
|
|
36
|
+
|
|
37
|
+
// ── Per-module mutation score ratchet ─────────────────────────────────────────
|
|
38
|
+
// ADR-456 / issue #1187: every covered module declares a minScore floor.
|
|
39
|
+
//
|
|
40
|
+
// HOW THE RATCHET WORKS:
|
|
41
|
+
// • minScore locks in the current measured mutation score (minus a 1–2 pt
|
|
42
|
+
// margin for run-to-run timeout variance).
|
|
43
|
+
// • CI fails a shard if the module's live score drops below its minScore.
|
|
44
|
+
// • Raise minScore (never lower) as a module's tests improve.
|
|
45
|
+
// • The goal is every module reaching TARGET_MUTATION_SCORE (80).
|
|
46
|
+
//
|
|
47
|
+
// GOODHART SAFETY: scores are improved by writing genuine behavioural
|
|
48
|
+
// assertions that kill real mutants — never by adding brittle exact-string
|
|
49
|
+
// matches on incidental output. A justified `// Stryker disable` on a
|
|
50
|
+
// confirmed equivalent mutant is acceptable.
|
|
51
|
+
//
|
|
52
|
+
// HOW TO UPDATE:
|
|
53
|
+
// 1. Run the per-module Stryker shard locally.
|
|
54
|
+
// 2. Note the reported score.
|
|
55
|
+
// 3. Set minScore = floor(score) - 1 (never lower than current value).
|
|
56
|
+
// 4. Open a PR — the CI gate will enforce the new floor on every future run.
|
|
57
|
+
|
|
58
|
+
/** Long-run target for all modules (ADR-456). */
|
|
59
|
+
const TARGET_MUTATION_SCORE = 80;
|
|
60
|
+
|
|
61
|
+
// ── Single source of truth: covered modules ───────────────────────────────────
|
|
62
|
+
// Each entry: { cjs: '<built artifact>', tests: ['tests/...', ...], minScore: N }
|
|
63
|
+
//
|
|
64
|
+
// minScore is the CI break threshold for this module's shard.
|
|
65
|
+
// Floors are measured scores minus 1–2 pts for run-to-run variance.
|
|
66
|
+
// Measured CI scores 2026-06-14 (issue #1187, timeout-free — source of truth):
|
|
67
|
+
// context-utilization 92.31% → floor 80 (target already met)
|
|
68
|
+
// prompt-budget 68.33% → floor 66 (local was 99.6% — TIMEOUT INFLATION; CI is the truth)
|
|
69
|
+
// frontmatter 63.35% → floor 62
|
|
70
|
+
// adr-parser 69.30% → floor 68
|
|
71
|
+
// config-schema 54.55% → floor 52 (local was 69.7% — TIMEOUT INFLATION; CI is the truth)
|
|
72
|
+
// active-workstream-store 81.91% → floor 80
|
|
73
|
+
// core-utils 77.52% → floor 75
|
|
74
|
+
//
|
|
75
|
+
// LESSON: floors MUST be calibrated from CI mutation runs (CI runs with
|
|
76
|
+
// timeout≈0, deterministic). Local runs count timeouts as kills and
|
|
77
|
+
// inflate scores significantly (prompt-budget: 99.6% local vs 68.3% CI;
|
|
78
|
+
// config-schema: 69.7% local vs 54.55% CI). Never set a floor from a
|
|
79
|
+
// local run without CI cross-check.
|
|
80
|
+
const COVERED = {
|
|
81
|
+
'context-utilization': {
|
|
82
|
+
cjs: 'pp-core/bin/lib/context-utilization.cjs',
|
|
83
|
+
tests: [
|
|
84
|
+
'tests/context-utilization.property.test.cjs',
|
|
85
|
+
],
|
|
86
|
+
// After mutation-killer assertions added in #1187: measured 92.31% (2026-06-14).
|
|
87
|
+
// 3 survivors are __esModule boilerplate (genuinely equivalent CJS interop mutants).
|
|
88
|
+
// minScore raised to TARGET (80) — module now meets ADR-456 goal.
|
|
89
|
+
minScore: 80,
|
|
90
|
+
},
|
|
91
|
+
'prompt-budget': {
|
|
92
|
+
cjs: 'pp-core/bin/lib/prompt-budget.cjs',
|
|
93
|
+
tests: [
|
|
94
|
+
'tests/prompt-budget.property.test.cjs',
|
|
95
|
+
'tests/prompt-budget.unit.test.cjs',
|
|
96
|
+
],
|
|
97
|
+
// CI 68.33% timeout-free (164 killed / 1 timeout / 240 total) 2026-06-14;
|
|
98
|
+
// local was 99.6% — timeout inflation. Floor = 68 - 2 margin.
|
|
99
|
+
minScore: 66,
|
|
100
|
+
},
|
|
101
|
+
frontmatter: {
|
|
102
|
+
cjs: 'pp-core/bin/lib/frontmatter.cjs',
|
|
103
|
+
tests: [
|
|
104
|
+
'tests/frontmatter.property.test.cjs',
|
|
105
|
+
'tests/frontmatter.unit.test.cjs',
|
|
106
|
+
],
|
|
107
|
+
minScore: 62,
|
|
108
|
+
},
|
|
109
|
+
'adr-parser': {
|
|
110
|
+
cjs: 'pp-core/bin/lib/adr-parser.cjs',
|
|
111
|
+
tests: [
|
|
112
|
+
'tests/adr-parser.property.test.cjs',
|
|
113
|
+
'tests/adr-parser.test.cjs',
|
|
114
|
+
'tests/adr-parser.unit.test.cjs',
|
|
115
|
+
],
|
|
116
|
+
minScore: 68,
|
|
117
|
+
},
|
|
118
|
+
'config-schema': {
|
|
119
|
+
cjs: 'pp-core/bin/lib/config-schema.cjs',
|
|
120
|
+
tests: [
|
|
121
|
+
'tests/config-schema.property.test.cjs',
|
|
122
|
+
],
|
|
123
|
+
// CI 54.55% timeout-free (18 killed / 0 timeout / 33 total) 2026-06-14;
|
|
124
|
+
// local was 69.7% — timeout inflation. Floor = 54 - 2 margin.
|
|
125
|
+
minScore: 52,
|
|
126
|
+
},
|
|
127
|
+
'active-workstream-store': {
|
|
128
|
+
cjs: 'pp-core/bin/lib/active-workstream-store.cjs',
|
|
129
|
+
tests: [
|
|
130
|
+
'tests/active-workstream-store.test.cjs',
|
|
131
|
+
'tests/active-workstream-store.unit.test.cjs',
|
|
132
|
+
],
|
|
133
|
+
minScore: 80,
|
|
134
|
+
},
|
|
135
|
+
'core-utils': {
|
|
136
|
+
cjs: 'pp-core/bin/lib/core-utils.cjs',
|
|
137
|
+
tests: [
|
|
138
|
+
'tests/core-utils.test.cjs',
|
|
139
|
+
],
|
|
140
|
+
minScore: 75, // measured 77.52% (2026-06-14, issue #1187); floor = 77 - 2
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// ── Files that, when changed, invalidate ALL modules ─────────────────────────
|
|
145
|
+
// Changes to the Stryker config, this script itself, or any covered test file
|
|
146
|
+
// affect all mutation scores and must force a full re-run.
|
|
147
|
+
const GLOBAL_TRIGGERS = new Set([
|
|
148
|
+
'stryker.config.mjs',
|
|
149
|
+
'scripts/mutation-matrix.cjs',
|
|
150
|
+
]);
|
|
151
|
+
|
|
152
|
+
// Also flag all test files that belong to any covered module as global triggers.
|
|
153
|
+
for (const mod of Object.values(COVERED)) {
|
|
154
|
+
for (const t of mod.tests) {
|
|
155
|
+
GLOBAL_TRIGGERS.add(t);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ── Argument parsing ──────────────────────────────────────────────────────────
|
|
160
|
+
function parseArgs(argv) {
|
|
161
|
+
const out = { base: null, print: false };
|
|
162
|
+
for (let i = 0; i < argv.length; i++) {
|
|
163
|
+
const arg = argv[i];
|
|
164
|
+
if (arg === '--base') {
|
|
165
|
+
out.base = argv[++i];
|
|
166
|
+
if (!out.base || out.base.startsWith('--')) {
|
|
167
|
+
throw new Error('--base requires a value');
|
|
168
|
+
}
|
|
169
|
+
} else if (arg.startsWith('--base=')) {
|
|
170
|
+
out.base = arg.slice('--base='.length);
|
|
171
|
+
if (!out.base) throw new Error('--base requires a value');
|
|
172
|
+
} else if (arg === '--print') {
|
|
173
|
+
out.print = true;
|
|
174
|
+
} else if (arg === '--help' || arg === '-h') {
|
|
175
|
+
console.log([
|
|
176
|
+
'Usage:',
|
|
177
|
+
' node scripts/mutation-matrix.cjs --base <ref> [--print]',
|
|
178
|
+
' printf "src/foo.cts\\n" | node scripts/mutation-matrix.cjs [--print]',
|
|
179
|
+
'',
|
|
180
|
+
'Options:',
|
|
181
|
+
' --base <ref> Git ref to diff against (default: origin/${GITHUB_BASE_REF:-next})',
|
|
182
|
+
' --print Human-readable output instead of JSON',
|
|
183
|
+
].join('\n'));
|
|
184
|
+
throw new ExitError(0);
|
|
185
|
+
} else {
|
|
186
|
+
throw new Error(`unknown argument: ${arg}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return out;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// ── Changed-file resolution ───────────────────────────────────────────────────
|
|
193
|
+
function resolveChangedFiles(args) {
|
|
194
|
+
// When --base is provided, always use git diff (regardless of stdin).
|
|
195
|
+
// When --base is absent AND stdin is not a TTY (isTTY is falsy / undefined),
|
|
196
|
+
// read a newline-delimited file list from stdin.
|
|
197
|
+
if (!args.base && process.stdin.isTTY !== true) {
|
|
198
|
+
const raw = readFileSync(process.stdin.fd, 'utf8');
|
|
199
|
+
return raw.split('\n').map(l => l.trim()).filter(Boolean);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Otherwise (--base given, or stdin is a real TTY), diff against the base ref.
|
|
203
|
+
const defaultBase = `origin/${process.env.GITHUB_BASE_REF || 'next'}`;
|
|
204
|
+
const base = args.base || defaultBase;
|
|
205
|
+
const stdout = execFileSync('git', ['diff', '--name-only', `${base}...HEAD`], {
|
|
206
|
+
encoding: 'utf8',
|
|
207
|
+
});
|
|
208
|
+
return stdout.split('\n').map(l => l.trim()).filter(Boolean);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ── Module classification ─────────────────────────────────────────────────────
|
|
212
|
+
function computeMatrix(changedFiles) {
|
|
213
|
+
// Check for global triggers first — if any hit, include every covered module.
|
|
214
|
+
const allModuleNames = Object.keys(COVERED);
|
|
215
|
+
for (const f of changedFiles) {
|
|
216
|
+
if (GLOBAL_TRIGGERS.has(f)) {
|
|
217
|
+
return allModuleNames;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Otherwise find which modules have their src/*.cts changed.
|
|
222
|
+
const changed = new Set();
|
|
223
|
+
for (const f of changedFiles) {
|
|
224
|
+
// Match src/<module>.cts (top-level src/, not nested)
|
|
225
|
+
const m = f.match(/^src\/([^/]+)\.cts$/);
|
|
226
|
+
if (m && COVERED[m[1]]) {
|
|
227
|
+
changed.add(m[1]);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return [...changed];
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// ── Output formatting ─────────────────────────────────────────────────────────
|
|
234
|
+
function buildResult(moduleNames) {
|
|
235
|
+
const include = moduleNames.map(name => ({
|
|
236
|
+
name,
|
|
237
|
+
mutate: COVERED[name].cjs,
|
|
238
|
+
tests: COVERED[name].tests.join(' '),
|
|
239
|
+
minScore: COVERED[name].minScore,
|
|
240
|
+
}));
|
|
241
|
+
|
|
242
|
+
return {
|
|
243
|
+
has_work: include.length > 0 ? 'true' : 'false',
|
|
244
|
+
matrix: { include },
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function printHuman(result, changedFiles) {
|
|
249
|
+
console.log(`Changed files (${changedFiles.length}):`);
|
|
250
|
+
for (const f of changedFiles) console.log(` ${f}`);
|
|
251
|
+
console.log('');
|
|
252
|
+
console.log(`has_work: ${result.has_work}`);
|
|
253
|
+
console.log(`Shards (${result.matrix.include.length}):`);
|
|
254
|
+
for (const shard of result.matrix.include) {
|
|
255
|
+
console.log(` [${shard.name}]`);
|
|
256
|
+
console.log(` mutate: ${shard.mutate}`);
|
|
257
|
+
console.log(` tests: ${shard.tests}`);
|
|
258
|
+
console.log(` minScore: ${shard.minScore}`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// ── Main ──────────────────────────────────────────────────────────────────────
|
|
263
|
+
function main() {
|
|
264
|
+
try {
|
|
265
|
+
const args = parseArgs(process.argv.slice(2));
|
|
266
|
+
const changedFiles = resolveChangedFiles(args);
|
|
267
|
+
const moduleNames = computeMatrix(changedFiles);
|
|
268
|
+
const result = buildResult(moduleNames);
|
|
269
|
+
|
|
270
|
+
if (args.print) {
|
|
271
|
+
printHuman(result, changedFiles);
|
|
272
|
+
} else {
|
|
273
|
+
console.log(JSON.stringify(result, null, 2));
|
|
274
|
+
}
|
|
275
|
+
} catch (err) {
|
|
276
|
+
if (err instanceof ExitError) throw err;
|
|
277
|
+
console.error(`mutation-matrix: ${err.message}`);
|
|
278
|
+
throw new ExitError(2);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// ── MUTATION_BREAK resolver ───────────────────────────────────────────────────
|
|
283
|
+
/**
|
|
284
|
+
* Resolves the per-shard mutation break threshold from the MUTATION_BREAK env var.
|
|
285
|
+
*
|
|
286
|
+
* Fail-closed contract:
|
|
287
|
+
* - undefined → 60 (local run: no env set, documented backstop)
|
|
288
|
+
* - set but empty (e.g. CI matrix.minScore missing) → throws (wiring error)
|
|
289
|
+
* - non-numeric or out-of-range [1, 100] → throws (invalid config)
|
|
290
|
+
* - valid integer string → returns that number
|
|
291
|
+
*
|
|
292
|
+
* This function is the single call site for reading MUTATION_BREAK.
|
|
293
|
+
* stryker.config.mjs imports and calls it so CI shards with a bad
|
|
294
|
+
* MUTATION_BREAK fail immediately rather than silently falling back to 60
|
|
295
|
+
* and bypassing a per-module floor above 60 (e.g. prompt-budget: 90).
|
|
296
|
+
*
|
|
297
|
+
* @param {string|undefined} raw - value of process.env.MUTATION_BREAK
|
|
298
|
+
* @returns {number}
|
|
299
|
+
*/
|
|
300
|
+
function resolveMutationBreak(raw) {
|
|
301
|
+
if (raw === undefined) {
|
|
302
|
+
// Local run with no MUTATION_BREAK set — use documented backstop.
|
|
303
|
+
return 60;
|
|
304
|
+
}
|
|
305
|
+
if (typeof raw !== 'string' || raw.trim() === '') {
|
|
306
|
+
throw new Error(
|
|
307
|
+
'MUTATION_BREAK is set but empty — CI shard wiring is broken (matrix.minScore missing?)'
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
const n = Number(raw);
|
|
311
|
+
if (!Number.isFinite(n) || n < 1 || n > 100) {
|
|
312
|
+
throw new Error(
|
|
313
|
+
`MUTATION_BREAK invalid: "${raw}" (expected a per-module minScore 1-100)`
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
return n;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Export internals for programmatic use (tests/mutation-matrix-ratchet.test.cjs).
|
|
320
|
+
// The require.main guard prevents main() from running when this file is require()d.
|
|
321
|
+
module.exports = { COVERED, TARGET_MUTATION_SCORE, resolveMutationBreak };
|
|
322
|
+
|
|
323
|
+
if (require.main === module) runMain(main);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* PR target-branch policy — ADR-230.
|
|
5
|
+
*
|
|
6
|
+
* Extracted from .github/workflows/pr-target-validator.yml so the classification
|
|
7
|
+
* logic can be unit-tested independently and required by the workflow at checkout
|
|
8
|
+
* from the TRUSTED base-branch copy (fork-tamper-safe).
|
|
9
|
+
*
|
|
10
|
+
* Pure module: no I/O, no GitHub API calls, no side effects.
|
|
11
|
+
*
|
|
12
|
+
* See: docs/branching.md, docs/adr/230-introduce-next-integration-branch.md
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The five patterns that allow a PR to target `main`.
|
|
17
|
+
* Verbatim from the github-script in pr-target-validator.yml.
|
|
18
|
+
*
|
|
19
|
+
* @type {RegExp[]}
|
|
20
|
+
*/
|
|
21
|
+
const MAIN_ALLOWED_PATTERNS = [
|
|
22
|
+
/^release\/\d+\.\d+\.0$/, // release branches
|
|
23
|
+
/^hotfix\/\d+\.\d+\.\d+$/, // hotfix branches
|
|
24
|
+
/^fix\/critical-/, // production-down emergencies
|
|
25
|
+
/^chore\/backmerge-/, // auto-backmerge from this workflow
|
|
26
|
+
/^revert\/critical-/, // emergency reverts
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Classify a pull request by its base and head branch names.
|
|
31
|
+
*
|
|
32
|
+
* @param {string} base - The PR's target branch (e.g. 'next', 'main', 'release/1.2.0').
|
|
33
|
+
* @param {string} head - The PR's source branch (e.g. 'feat/my-feature').
|
|
34
|
+
* @returns {{ decision: 'allowed' | 'blocked' | 'unusual' }}
|
|
35
|
+
*/
|
|
36
|
+
function classifyPrTarget(base, head) {
|
|
37
|
+
// PRs targeting `next` are always fine.
|
|
38
|
+
if (base === 'next') {
|
|
39
|
+
return { decision: 'allowed' };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// PRs targeting `main`: only specific branch types allowed.
|
|
43
|
+
if (base === 'main') {
|
|
44
|
+
const allowed = MAIN_ALLOWED_PATTERNS.some(re => re.test(head));
|
|
45
|
+
if (allowed) {
|
|
46
|
+
return { decision: 'allowed' };
|
|
47
|
+
}
|
|
48
|
+
return { decision: 'blocked' };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// PRs targeting release/X.Y.0 or hotfix/X.Y.Z are fine (stabilization PRs).
|
|
52
|
+
if (/^release\/\d+\.\d+\.0$/.test(base) || /^hotfix\/\d+\.\d+\.\d+$/.test(base)) {
|
|
53
|
+
return { decision: 'allowed' };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Any other target is unusual but not forbidden.
|
|
57
|
+
return { decision: 'unusual' };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = {
|
|
61
|
+
MAIN_ALLOWED_PATTERNS,
|
|
62
|
+
classifyPrTarget,
|
|
63
|
+
};
|