@opengsd/gsd-core 1.14.0 → 1.16.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/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.opencode/plugins/gsd-core.js +85 -5
- package/README.ja-JP.md +3 -3
- package/README.ko-KR.md +3 -3
- package/README.pt-BR.md +3 -3
- package/README.zh-CN.md +3 -3
- package/agents/gsd-code-fixer.compact.md +7 -6
- package/agents/gsd-code-fixer.md +9 -8
- package/agents/gsd-code-reviewer.compact.md +5 -3
- package/agents/gsd-code-reviewer.md +8 -6
- package/agents/gsd-debug-session-manager.compact.md +17 -2
- package/agents/gsd-debug-session-manager.md +17 -2
- package/agents/gsd-debugger.md +3 -3
- package/agents/gsd-eval-auditor.compact.md +1 -1
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-executor.md +17 -12
- package/agents/gsd-intel-updater.compact.md +1 -1
- package/agents/gsd-intel-updater.md +1 -1
- package/agents/gsd-mempalace-curator.md +2 -2
- package/agents/gsd-phase-researcher.md +19 -11
- package/agents/gsd-plan-checker.md +15 -9
- package/agents/gsd-planner.md +15 -11
- package/agents/gsd-project-researcher.compact.md +1 -1
- package/agents/gsd-project-researcher.md +1 -1
- package/agents/gsd-research-synthesizer.compact.md +1 -1
- package/agents/gsd-research-synthesizer.md +1 -1
- package/agents/gsd-ui-auditor.compact.md +21 -30
- package/agents/gsd-ui-auditor.md +166 -37
- package/agents/gsd-ui-researcher.compact.md +1 -1
- package/agents/gsd-ui-researcher.md +1 -1
- package/agents/gsd-verifier.md +37 -14
- package/bin/install.js +764 -287
- package/commands/gsd/add-tests.md +6 -1
- package/commands/gsd/ai-integration-phase.md +6 -1
- package/commands/gsd/audit-fix.md +5 -0
- package/commands/gsd/audit-milestone.md +6 -1
- package/commands/gsd/autonomous.md +7 -2
- package/commands/gsd/capture.md +9 -5
- package/commands/gsd/code-review.md +7 -2
- package/commands/gsd/complete-milestone.md +4 -0
- package/commands/gsd/config.md +7 -3
- package/commands/gsd/debug.md +11 -7
- package/commands/gsd/discuss-phase.md +7 -3
- package/commands/gsd/docs-update.md +12 -7
- package/commands/gsd/eval-review.md +6 -1
- package/commands/gsd/execute-phase.md +12 -7
- package/commands/gsd/extract-learnings.md +5 -0
- package/commands/gsd/fast.md +4 -0
- package/commands/gsd/forensics.md +5 -1
- package/commands/gsd/graphify.md +10 -6
- package/commands/gsd/health.md +5 -0
- package/commands/gsd/help.md +7 -2
- package/commands/gsd/import.md +7 -3
- package/commands/gsd/inbox.md +5 -0
- package/commands/gsd/ingest-docs.md +5 -1
- package/commands/gsd/manager.md +6 -1
- package/commands/gsd/map-codebase.md +7 -3
- package/commands/gsd/mempalace-capture.md +12 -4
- package/commands/gsd/mempalace-recall.md +5 -1
- package/commands/gsd/milestone-summary.md +5 -1
- package/commands/gsd/mvp-phase.md +8 -3
- package/commands/gsd/new-milestone.md +6 -1
- package/commands/gsd/new-project.md +5 -0
- package/commands/gsd/next.md +6 -1
- package/commands/gsd/ns-context.md +4 -0
- package/commands/gsd/ns-ideate.md +4 -0
- package/commands/gsd/ns-manage.md +4 -0
- package/commands/gsd/ns-project.md +4 -0
- package/commands/gsd/ns-review.md +4 -0
- package/commands/gsd/ns-workflow.md +4 -0
- package/commands/gsd/onboard.md +6 -1
- package/commands/gsd/pause-work.md +5 -1
- package/commands/gsd/phase.md +8 -4
- package/commands/gsd/plan-phase.md +6 -1
- package/commands/gsd/plan-review-convergence.md +11 -7
- package/commands/gsd/pr-branch.md +4 -0
- package/commands/gsd/profile-user.md +5 -1
- package/commands/gsd/progress.md +7 -2
- package/commands/gsd/quick-batch.md +21 -9
- package/commands/gsd/quick.md +12 -7
- package/commands/gsd/review.md +7 -4
- package/commands/gsd/secure-phase.md +6 -1
- package/commands/gsd/ship.md +5 -0
- package/commands/gsd/sketch.md +7 -2
- package/commands/gsd/spec-phase.md +5 -1
- package/commands/gsd/spike.md +8 -3
- package/commands/gsd/surface.md +5 -1
- package/commands/gsd/thread.md +4 -0
- package/commands/gsd/ui-phase.md +6 -1
- package/commands/gsd/ui-review.md +6 -1
- package/commands/gsd/ultraplan-phase.md +5 -1
- package/commands/gsd/undo.md +5 -1
- package/commands/gsd/update.md +6 -2
- package/commands/gsd/validate-phase.md +6 -1
- package/commands/gsd/verify-work.md +6 -1
- package/commands/gsd/workspace.md +7 -3
- package/gsd-core/bin/gsd-tools.cjs +477 -78
- package/gsd-core/bin/lib/active-workstream-store.cjs +15 -0
- package/gsd-core/bin/lib/adr-parser.cjs +3 -1
- package/gsd-core/bin/lib/agent-install-check.cjs +4 -1
- package/gsd-core/bin/lib/audit.cjs +144 -42
- package/gsd-core/bin/lib/broken-windows.cjs +13 -13
- package/gsd-core/bin/lib/capability-activation.cjs +9 -4
- package/gsd-core/bin/lib/capability-registry.cjs +197 -222
- package/gsd-core/bin/lib/capability-validator.cjs +16 -1
- package/gsd-core/bin/lib/check-auto-mode.cjs +35 -0
- package/gsd-core/bin/lib/check-command-router.cjs +164 -1625
- package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +13 -2
- package/gsd-core/bin/lib/cli-exit.cjs +12 -0
- package/gsd-core/bin/lib/codex-agent-toml.cjs +32 -33
- package/gsd-core/bin/lib/command-aliases.cjs +7 -0
- package/gsd-core/bin/lib/command-routing-hub.cjs +48 -1
- package/gsd-core/bin/lib/commands.cjs +343 -207
- package/gsd-core/bin/lib/complexity-trigger.cjs +8 -7
- package/gsd-core/bin/lib/config-loader.cjs +65 -4
- package/gsd-core/bin/lib/config.cjs +76 -19
- package/gsd-core/bin/lib/core-utils.cjs +6 -1
- package/gsd-core/bin/lib/coverage.cjs +4 -8
- package/gsd-core/bin/lib/decision-coverage-support.cjs +259 -0
- package/gsd-core/bin/lib/decisions.cjs +30 -14
- package/gsd-core/bin/lib/drift.cjs +177 -42
- package/gsd-core/bin/lib/frontmatter-fence.cjs +90 -0
- package/gsd-core/bin/lib/frontmatter-splice.cjs +494 -0
- package/gsd-core/bin/lib/frontmatter.cjs +426 -234
- package/gsd-core/bin/lib/gap-checker.cjs +72 -29
- package/gsd-core/bin/lib/gate-api-coverage-verify-pre.cjs +381 -0
- package/gsd-core/bin/lib/gate-args.cjs +53 -0
- package/gsd-core/bin/lib/gate-codebase-drift.cjs +285 -0
- package/gsd-core/bin/lib/gate-config.cjs +46 -0
- package/gsd-core/bin/lib/gate-context-drift.cjs +141 -0
- package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +169 -0
- package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +126 -0
- package/gsd-core/bin/lib/gate-evaluation-scope.cjs +555 -0
- package/gsd-core/bin/lib/gate-evidence.cjs +138 -0
- package/gsd-core/bin/lib/gate-exit.cjs +27 -0
- package/gsd-core/bin/lib/gate-gap-analysis-plan-post.cjs +61 -0
- package/gsd-core/bin/lib/gate-phase-context.cjs +170 -0
- package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +1 -1
- package/gsd-core/bin/lib/gate-predicate.cjs +165 -0
- package/gsd-core/bin/lib/gate-prohibition-enforcement.cjs +94 -0
- package/gsd-core/bin/lib/gate-schema-drift.cjs +165 -0
- package/gsd-core/bin/lib/gate-tdd-red-evidence.cjs +100 -0
- package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +182 -0
- package/gsd-core/bin/lib/gate-ui-plan.cjs +86 -0
- package/gsd-core/bin/lib/gate-ui-safety.cjs +80 -0
- package/gsd-core/bin/lib/gate-verdict.cjs +64 -0
- package/gsd-core/bin/lib/gate-verify-command-paths.cjs +78 -0
- package/gsd-core/bin/lib/gate-verify-failure-directions.cjs +41 -0
- package/gsd-core/bin/lib/graphify.cjs +10 -2
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +43 -47
- package/gsd-core/bin/lib/health-diagnostic.cjs +45 -8
- package/gsd-core/bin/lib/host-runtime-detection.cjs +9 -0
- package/gsd-core/bin/lib/init.cjs +364 -132
- package/gsd-core/bin/lib/install-engine.cjs +30 -33
- package/gsd-core/bin/lib/install-profiles.cjs +7 -4
- package/gsd-core/bin/lib/installer-migrations.cjs +8 -1
- package/gsd-core/bin/lib/io.cjs +122 -3
- package/gsd-core/bin/lib/loop-resolver.cjs +95 -0
- package/gsd-core/bin/lib/markdown-sectionizer.cjs +75 -1
- package/gsd-core/bin/lib/milestone.cjs +37 -6
- package/gsd-core/bin/lib/model-resolver.cjs +171 -62
- package/gsd-core/bin/lib/observability/event.cjs +1 -1
- package/gsd-core/bin/lib/observability/logger.cjs +46 -1
- package/gsd-core/bin/lib/pattern.cjs +10 -0
- package/gsd-core/bin/lib/phase-command-router.cjs +20 -5
- package/gsd-core/bin/lib/phase-estimation.cjs +5 -4
- package/gsd-core/bin/lib/phase-id-card.cjs +32 -0
- package/gsd-core/bin/lib/phase-id-display.cjs +78 -0
- package/gsd-core/bin/lib/phase-id.cjs +110 -8
- package/gsd-core/bin/lib/phase-lifecycle.cjs +9 -2
- package/gsd-core/bin/lib/phase-locator.cjs +29 -10
- package/gsd-core/bin/lib/phase-status.cjs +360 -0
- package/gsd-core/bin/lib/phase.cjs +489 -88
- package/gsd-core/bin/lib/plan-document.cjs +142 -20
- package/gsd-core/bin/lib/plan-drift-guard.cjs +5 -0
- package/gsd-core/bin/lib/planning-document.cjs +692 -0
- package/gsd-core/bin/lib/planning-inspect.cjs +60 -9
- package/gsd-core/bin/lib/planning-snapshot.cjs +18 -0
- package/gsd-core/bin/lib/planning-workspace.cjs +83 -55
- package/gsd-core/bin/lib/pr-branch-patterns.cjs +57 -0
- package/gsd-core/bin/lib/pristine-baseline.cjs +10 -0
- package/gsd-core/bin/lib/probe-core.cjs +7 -1
- package/gsd-core/bin/lib/profile-output.cjs +6 -3
- package/gsd-core/bin/lib/prohibition-enforcement.cjs +0 -55
- package/gsd-core/bin/lib/project-root.cjs +41 -2
- package/gsd-core/bin/lib/quick-batch-command-router.cjs +35 -9
- package/gsd-core/bin/lib/quick-batch-dispatch.cjs +11 -8
- package/gsd-core/bin/lib/real-home-guard.cjs +9 -1
- package/gsd-core/bin/lib/report-parser.cjs +269 -0
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +10 -30
- package/gsd-core/bin/lib/review-reviewer-selection.cjs +2 -2
- package/gsd-core/bin/lib/roadmap-command-router.cjs +25 -19
- package/gsd-core/bin/lib/roadmap-parser.cjs +242 -15
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +1653 -65
- package/gsd-core/bin/lib/roadmap.cjs +405 -88
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +373 -187
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +5 -2
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +57 -1
- package/gsd-core/bin/lib/runtime-homes.cjs +14 -7
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +522 -624
- package/gsd-core/bin/lib/runtime-name-policy.cjs +246 -21
- package/gsd-core/bin/lib/runtime-slash.cjs +47 -30
- package/gsd-core/bin/lib/shell-command-projection.cjs +47 -8
- package/gsd-core/bin/lib/smart-entry.cjs +19 -3
- package/gsd-core/bin/lib/stale-bake-guard.cjs +32 -48
- package/gsd-core/bin/lib/state-contract.cjs +15 -18
- package/gsd-core/bin/lib/state-document.cjs +100 -22
- package/gsd-core/bin/lib/state-transition.cjs +39 -2
- package/gsd-core/bin/lib/state.cjs +256 -105
- package/gsd-core/bin/lib/surface.cjs +19 -2
- package/gsd-core/bin/lib/tdd-red-evidence.cjs +48 -79
- package/gsd-core/bin/lib/uat-predicate.cjs +359 -38
- package/gsd-core/bin/lib/uat.cjs +432 -7
- package/gsd-core/bin/lib/ui-consideration-probe.cjs +15 -2
- package/gsd-core/bin/lib/ui-frontend-evidence.cjs +167 -40
- package/gsd-core/bin/lib/undo-commit-selection.cjs +131 -0
- package/gsd-core/bin/lib/vendor/README.md +31 -9
- package/gsd-core/bin/lib/vendor/saxes.cjs +1934 -0
- package/gsd-core/bin/lib/vendor/saxes.cjs.LICENSE.txt +92 -0
- package/gsd-core/bin/lib/vendor/tap-parser.cjs +8927 -0
- package/gsd-core/bin/lib/vendor/tap-parser.cjs.LICENSE.txt +152 -0
- package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +1378 -274
- package/gsd-core/bin/lib/verify-command-grounding.cjs +46 -2
- package/gsd-core/bin/lib/verify-command-router.cjs +18 -7
- package/gsd-core/bin/lib/verify.cjs +357 -531
- package/gsd-core/bin/lib/workstream-inventory-builder.cjs +14 -6
- package/gsd-core/bin/lib/workstream-inventory.cjs +31 -21
- package/gsd-core/bin/lib/workstream-name-policy.cjs +31 -1
- package/gsd-core/bin/lib/workstream.cjs +11 -2
- package/gsd-core/bin/lib/worktree-base-ref.cjs +482 -73
- package/gsd-core/bin/lib/worktree-safety.cjs +784 -51
- package/gsd-core/bin/shared/config-defaults.manifest.json +8 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +5 -0
- package/gsd-core/references/autonomous-smart-discuss.md +2 -1
- package/gsd-core/references/autonomous-ui-design-contract.md +3 -3
- package/gsd-core/references/checkpoints.md +5 -3
- package/gsd-core/references/edge-probe-fixtures/01-round-half-even/expected-coverage.json +28 -3
- package/gsd-core/references/edge-probe-fixtures/02-merge-intervals/expected-coverage.json +37 -4
- package/gsd-core/references/edge-probe-fixtures/03-truncate-graphemes/expected-coverage.json +28 -3
- package/gsd-core/references/edge-probe-fixtures/04-money-rounding/expected-coverage.json +28 -3
- package/gsd-core/references/edge-probe-fixtures/05-list-dedupe/expected-coverage.json +37 -4
- package/gsd-core/references/edge-probe-fixtures/06-resolved-mixed/expected-coverage.json +37 -4
- package/gsd-core/references/edge-probe.md +195 -21
- package/gsd-core/references/execute-mvp-tdd.md +5 -10
- package/gsd-core/references/execute-phase-between-wave-reset.md +10 -6
- package/gsd-core/references/execute-phase-response-language.md +1 -1
- package/gsd-core/references/execute-phase-wave-guard.md +22 -11
- package/gsd-core/references/gsd-run-resolver.md +1 -1
- package/gsd-core/references/loop-hook-dispatch.md +7 -1
- package/gsd-core/references/model-profiles.md +1 -1
- package/gsd-core/references/offer-next.md +1 -1
- package/gsd-core/references/phase-argument-parsing.md +9 -7
- package/gsd-core/references/phase-id-convention.md +28 -0
- package/gsd-core/references/planner-gap-closure.md +2 -0
- package/gsd-core/references/planner-load-graph-context.md +24 -13
- package/gsd-core/references/planner-verify-command-grounding.md +14 -0
- package/gsd-core/references/planning-config.md +12 -3
- package/gsd-core/references/spidr-splitting.md +1 -1
- package/gsd-core/references/tdd.md +37 -8
- package/gsd-core/references/ui-consideration-probe.md +10 -5
- package/gsd-core/references/verifier-phase-gates.md +5 -2
- package/gsd-core/references/verify-command-path-resolvability.md +10 -2
- package/gsd-core/references/verify-mvp-mode.md +2 -2
- package/gsd-core/references/workstream-flag.md +33 -3
- package/gsd-core/references/worktree-path-safety.md +321 -0
- package/gsd-core/templates/README.md +1 -1
- package/gsd-core/templates/UAT.md +17 -1
- package/gsd-core/templates/config.json +2 -11
- package/gsd-core/templates/verification-report.md +1 -1
- package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
- package/gsd-core/workflows/add-backlog.md +1 -1
- package/gsd-core/workflows/add-phase.md +8 -7
- package/gsd-core/workflows/add-tests.md +4 -3
- package/gsd-core/workflows/add-todo.md +6 -5
- package/gsd-core/workflows/ai-integration-phase.md +13 -4
- package/gsd-core/workflows/audit-fix.md +1 -1
- package/gsd-core/workflows/audit-milestone.md +4 -3
- package/gsd-core/workflows/audit-uat.md +1 -1
- package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +9 -18
- package/gsd-core/workflows/autonomous.md +43 -23
- package/gsd-core/workflows/check-todos.md +7 -6
- package/gsd-core/workflows/cleanup.md +2 -2
- package/gsd-core/workflows/code-review/steps/dispatch-fix.md +4 -3
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +20 -13
- package/gsd-core/workflows/code-review-fix.md +112 -25
- package/gsd-core/workflows/code-review.md +146 -135
- package/gsd-core/workflows/complete-milestone/detail/elaboration.md +4 -3
- package/gsd-core/workflows/complete-milestone.md +13 -8
- package/gsd-core/workflows/debug.md +32 -7
- package/gsd-core/workflows/diagnose-issues.md +3 -2
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/chain.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions.md +4 -3
- package/gsd-core/workflows/discuss-phase.md +4 -3
- package/gsd-core/workflows/do.md +2 -2
- package/gsd-core/workflows/docs-update.md +6 -5
- package/gsd-core/workflows/edit-phase.md +4 -3
- package/gsd-core/workflows/eval-review.md +14 -5
- package/gsd-core/workflows/execute-phase/detail/elaboration.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/code-review-disposition.md +1019 -0
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +15 -4
- package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +10 -7
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +37 -3
- package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +3 -1
- package/gsd-core/workflows/execute-phase/steps/partial-wave.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +46 -9
- package/gsd-core/workflows/execute-phase/steps/protected-branch.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/ready-wave-gate.md +37 -0
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/regression-gate.md +2 -0
- package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/threat-id-gate.md +28 -0
- package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +187 -0
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +2 -3
- package/gsd-core/workflows/execute-phase/steps/worktree-base-check.md +25 -0
- package/gsd-core/workflows/execute-phase.md +96 -178
- package/gsd-core/workflows/execute-plan.md +18 -23
- package/gsd-core/workflows/explore.md +4 -4
- package/gsd-core/workflows/extract-learnings.md +4 -2
- package/gsd-core/workflows/fast.md +1 -1
- package/gsd-core/workflows/forensics.md +1 -1
- package/gsd-core/workflows/graduation.md +1 -1
- package/gsd-core/workflows/health.md +3 -2
- package/gsd-core/workflows/help/modes/full.compact.md +3 -3
- package/gsd-core/workflows/help/modes/full.md +5 -5
- package/gsd-core/workflows/help/modes/topic.md +15 -5
- package/gsd-core/workflows/import.md +4 -3
- package/gsd-core/workflows/inbox.md +2 -2
- package/gsd-core/workflows/ingest-docs.md +3 -3
- package/gsd-core/workflows/insert-phase.md +4 -3
- package/gsd-core/workflows/list-seeds.md +1 -1
- package/gsd-core/workflows/list-workspaces.md +1 -1
- package/gsd-core/workflows/manager.md +6 -4
- package/gsd-core/workflows/map-codebase.md +5 -4
- package/gsd-core/workflows/milestone-summary.md +3 -2
- package/gsd-core/workflows/mvp-phase.md +14 -14
- package/gsd-core/workflows/new-milestone.md +11 -11
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +3 -3
- package/gsd-core/workflows/new-project/steps/codebase-map-offer.md +1 -1
- package/gsd-core/workflows/new-project.md +7 -7
- package/gsd-core/workflows/new-workspace.md +2 -2
- package/gsd-core/workflows/next.md +1 -1
- package/gsd-core/workflows/note.md +1 -1
- package/gsd-core/workflows/onboard.md +1 -1
- package/gsd-core/workflows/pause-work.md +2 -2
- package/gsd-core/workflows/plan-phase/detail/elaboration.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +17 -5
- package/gsd-core/workflows/plan-phase/steps/closed-phase-gate.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +23 -5
- package/gsd-core/workflows/plan-phase.md +50 -24
- package/gsd-core/workflows/plan-review-convergence.md +21 -5
- package/gsd-core/workflows/plant-seed.md +62 -20
- package/gsd-core/workflows/pr-branch.md +113 -13
- package/gsd-core/workflows/profile-user.md +2 -2
- package/gsd-core/workflows/progress.md +19 -49
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +27 -0
- package/gsd-core/workflows/quick/steps/quick-verification.md +4 -4
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +30 -11
- package/gsd-core/workflows/quick-batch/steps/batch-init.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/completion.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/merge-wave.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/planner-wave.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/research-phase.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/resume-mode.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/verification-wave.md +9 -3
- package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +1 -1
- package/gsd-core/workflows/quick-batch.md +15 -10
- package/gsd-core/workflows/quick.md +62 -39
- package/gsd-core/workflows/reapply-patches.md +9 -3
- package/gsd-core/workflows/remove-phase.md +3 -2
- package/gsd-core/workflows/remove-workspace.md +2 -2
- package/gsd-core/workflows/resume-project.md +3 -2
- package/gsd-core/workflows/review.md +33 -17
- package/gsd-core/workflows/scan.md +3 -2
- package/gsd-core/workflows/secure-phase.md +13 -13
- package/gsd-core/workflows/settings-advanced.md +30 -10
- package/gsd-core/workflows/settings-integrations.md +2 -3
- package/gsd-core/workflows/settings.md +4 -4
- package/gsd-core/workflows/ship.md +14 -13
- package/gsd-core/workflows/sketch-wrap-up.md +1 -1
- package/gsd-core/workflows/sketch.md +1 -1
- package/gsd-core/workflows/smart-entry.md +2 -2
- package/gsd-core/workflows/spec-phase.md +15 -5
- package/gsd-core/workflows/spike-wrap-up.md +1 -1
- package/gsd-core/workflows/spike.md +1 -1
- package/gsd-core/workflows/stats.md +1 -1
- package/gsd-core/workflows/sync-skills.md +5 -5
- package/gsd-core/workflows/thread.md +2 -2
- package/gsd-core/workflows/transition.md +13 -23
- package/gsd-core/workflows/ui-phase.md +48 -11
- package/gsd-core/workflows/ui-review.md +21 -6
- package/gsd-core/workflows/ultraplan-phase.md +3 -2
- package/gsd-core/workflows/undo.md +339 -20
- package/gsd-core/workflows/update.md +7 -7
- package/gsd-core/workflows/validate-phase.md +12 -13
- package/gsd-core/workflows/verify-work/detail/elaboration.md +43 -3
- package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +1 -1
- package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +5 -3
- package/gsd-core/workflows/verify-work.md +129 -55
- package/hooks/dist/gsd-agent-isolation-guard.js +32 -0
- package/hooks/dist/gsd-check-update-worker.js +8 -0
- package/hooks/dist/gsd-check-update.js +8 -0
- package/hooks/dist/gsd-context-monitor.js +31 -8
- package/hooks/dist/gsd-cursor-subagent-start.js +8 -0
- package/hooks/dist/gsd-secret-read-guard.js +161 -4
- package/hooks/dist/gsd-statusline.js +85 -20
- package/hooks/dist/gsd-update-banner.js +8 -0
- package/hooks/dist/gsd-validate-commit.sh +63 -4
- package/hooks/dist/gsd-windsurf-pre-write.js +11 -2
- package/hooks/dist/gsd-workflow-guard.js +5 -4
- package/hooks/dist/gsd-worktree-path-guard.js +6 -2
- package/hooks/dist/lib/cli-exit.js +12 -0
- package/hooks/dist/lib/git-probe.js +17 -1
- package/hooks/dist/lib/isolation-sentinel.js +2 -2
- package/hooks/gsd-agent-isolation-guard.js +32 -0
- package/hooks/gsd-check-update-worker.js +8 -0
- package/hooks/gsd-check-update.js +8 -0
- package/hooks/gsd-context-monitor.js +31 -8
- package/hooks/gsd-cursor-subagent-start.js +8 -0
- package/hooks/gsd-secret-read-guard.js +161 -4
- package/hooks/gsd-statusline.js +85 -20
- package/hooks/gsd-update-banner.js +8 -0
- package/hooks/gsd-validate-commit.sh +63 -4
- package/hooks/gsd-windsurf-pre-write.js +11 -2
- package/hooks/gsd-workflow-guard.js +5 -4
- package/hooks/gsd-worktree-path-guard.js +6 -2
- package/hooks/hooks.json +5 -5
- package/hooks/lib/cli-exit.js +12 -0
- package/hooks/lib/git-probe.js +17 -1
- package/hooks/lib/isolation-sentinel.js +2 -2
- package/package.json +22 -4
- package/scripts/build-hooks.js +15 -6
- package/scripts/changeset/parse.cjs +52 -4
- package/scripts/check-contract-drift.cjs +127 -11
- package/scripts/ci-timeout-report.cjs +770 -4
- package/scripts/command-contract-helpers.cjs +15 -8
- package/scripts/docs-guard-registry.cjs +34 -0
- package/scripts/gen-features.cjs +13 -8
- package/scripts/gen-hooks-cli-exit.cjs +12 -28
- package/scripts/gen-loop-host-contract.cjs +79 -1
- package/scripts/gen-platform-conformance-tier.cjs +187 -1
- package/scripts/gen-plugin-skills.cjs +87 -1
- package/scripts/gen-research-agents.cjs +24 -31
- package/scripts/gen-scripts-cli-exit.cjs +30 -3
- package/scripts/gen-test-timings.cjs +32 -7
- package/scripts/lib/cli-exit.cjs +12 -0
- package/scripts/lib/macos-conformance-tier.generated.cjs +34 -2
- package/scripts/lib/ndjson-reporter.cjs +31 -5
- package/scripts/lib/platform-conformance-tier.generated.cjs +45 -5
- package/scripts/lib/registration-ledger-preload.cjs +155 -0
- package/scripts/lib/vendor-bundle.cjs +59 -0
- package/scripts/lib/vendor-licenses/saxes-6.0.0.txt +64 -0
- package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
- package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
- package/scripts/lint-completion-predicate-drift.cjs +18 -19
- package/scripts/lint-descriptions.cjs +7 -3
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +38 -1
- package/scripts/lint-eslint-glob-coverage.allowlist.json +20 -0
- package/scripts/lint-frontmatter-fence-drift.cjs +313 -0
- package/scripts/lint-frontmatter-scalar-broad-grep.cjs +122 -16
- package/scripts/lint-phase-arg-assignment.cjs +257 -0
- package/scripts/lint-phase-enumeration-drift.cjs +12 -8
- package/scripts/lint-phase-id-drift.cjs +319 -5
- package/scripts/lint-planning-document-positive-control.cjs +329 -0
- package/scripts/lint-pr-branch-pattern-drift.cjs +148 -0
- package/scripts/lint-response-language-coverage.cjs +3 -0
- package/scripts/lint-retired-runtime-name.cjs +619 -0
- package/scripts/lint-skill-deps.cjs +7 -3
- package/scripts/lint-state-write-path-drift.cjs +93 -0
- package/scripts/lint-test-file-count.allowlist.json +38 -9
- package/scripts/lint-test-file-count.cjs +34 -1
- package/scripts/lint-vendored-deps.cjs +41 -5
- package/scripts/lint-workflow-shellcheck-baseline.json +25 -10
- package/scripts/mutation-matrix.cjs +50 -5
- package/scripts/prompt-injection-scan.sh +4 -0
- package/scripts/release-tarball-smoke.cjs +194 -1
- package/scripts/require-issue-link-policy.cjs +6 -2
- package/scripts/sync-runtime-launcher.cjs +184 -2
- package/scripts/verify-npm-publish.cjs +76 -20
- package/skills/gsd-add-tests/SKILL.md +6 -1
- package/skills/gsd-ai-integration-phase/SKILL.md +6 -1
- package/skills/gsd-audit-fix/SKILL.md +5 -0
- package/skills/gsd-audit-milestone/SKILL.md +6 -1
- package/skills/gsd-autonomous/SKILL.md +7 -2
- package/skills/gsd-capture/SKILL.md +9 -5
- package/skills/gsd-code-review/SKILL.md +7 -2
- package/skills/gsd-complete-milestone/SKILL.md +4 -0
- package/skills/gsd-config/SKILL.md +8 -4
- package/skills/gsd-debug/SKILL.md +11 -7
- package/skills/gsd-discuss-phase/SKILL.md +7 -3
- package/skills/gsd-docs-update/SKILL.md +12 -7
- package/skills/gsd-eval-review/SKILL.md +6 -1
- package/skills/gsd-execute-phase/SKILL.md +12 -7
- package/skills/gsd-extract-learnings/SKILL.md +5 -0
- package/skills/gsd-fast/SKILL.md +4 -0
- package/skills/gsd-forensics/SKILL.md +5 -1
- package/skills/gsd-graphify/SKILL.md +10 -6
- package/skills/gsd-health/SKILL.md +5 -0
- package/skills/gsd-help/SKILL.md +7 -2
- package/skills/gsd-import/SKILL.md +7 -3
- package/skills/gsd-inbox/SKILL.md +5 -0
- package/skills/gsd-ingest-docs/SKILL.md +5 -1
- package/skills/gsd-manager/SKILL.md +6 -1
- package/skills/gsd-map-codebase/SKILL.md +7 -3
- package/skills/gsd-mempalace-capture/SKILL.md +12 -4
- package/skills/gsd-mempalace-recall/SKILL.md +5 -1
- package/skills/gsd-milestone-summary/SKILL.md +5 -1
- package/skills/gsd-mvp-phase/SKILL.md +8 -3
- package/skills/gsd-new-milestone/SKILL.md +6 -1
- package/skills/gsd-new-project/SKILL.md +5 -0
- package/skills/gsd-next/SKILL.md +6 -1
- package/skills/gsd-ns-context/SKILL.md +4 -0
- package/skills/gsd-ns-ideate/SKILL.md +4 -0
- package/skills/gsd-ns-manage/SKILL.md +4 -0
- package/skills/gsd-ns-project/SKILL.md +4 -0
- package/skills/gsd-ns-review/SKILL.md +4 -0
- package/skills/gsd-ns-workflow/SKILL.md +4 -0
- package/skills/gsd-onboard/SKILL.md +6 -1
- package/skills/gsd-pause-work/SKILL.md +5 -1
- package/skills/gsd-phase/SKILL.md +8 -4
- package/skills/gsd-plan-phase/SKILL.md +6 -1
- package/skills/gsd-plan-review-convergence/SKILL.md +10 -6
- package/skills/gsd-pr-branch/SKILL.md +4 -0
- package/skills/gsd-profile-user/SKILL.md +5 -1
- package/skills/gsd-progress/SKILL.md +7 -2
- package/skills/gsd-quick/SKILL.md +16 -10
- package/skills/gsd-quick-batch/SKILL.md +21 -9
- package/skills/gsd-review/SKILL.md +7 -4
- package/skills/gsd-review-backlog/SKILL.md +3 -2
- package/skills/gsd-secure-phase/SKILL.md +6 -1
- package/skills/gsd-ship/SKILL.md +5 -0
- package/skills/gsd-sketch/SKILL.md +7 -2
- package/skills/gsd-spec-phase/SKILL.md +5 -1
- package/skills/gsd-spike/SKILL.md +8 -3
- package/skills/gsd-surface/SKILL.md +5 -1
- package/skills/gsd-thread/SKILL.md +4 -0
- package/skills/gsd-ui-phase/SKILL.md +6 -1
- package/skills/gsd-ui-review/SKILL.md +6 -1
- package/skills/gsd-ultraplan-phase/SKILL.md +5 -1
- package/skills/gsd-undo/SKILL.md +5 -1
- package/skills/gsd-update/SKILL.md +6 -2
- package/skills/gsd-validate-phase/SKILL.md +6 -1
- package/skills/gsd-verify-work/SKILL.md +6 -1
- package/skills/gsd-workspace/SKILL.md +7 -3
- package/skills/gsd-workstreams/SKILL.md +6 -6
- package/vscode/package.json +1 -1
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Decision-coverage support — the shared reading/matching helpers of the two decision-coverage
|
|
4
|
+
* gates (#5139, epic #5056, ADR-5057 §4 first bullet, design D3/D4).
|
|
5
|
+
*
|
|
6
|
+
* Moved verbatim (behaviour preserved) from `check-command-router.cts`, with the raw-content
|
|
7
|
+
* parsers replaced by their owning seams:
|
|
8
|
+
* - the frontmatter `must_haves` / `truths` / `objective` blocks are read through the
|
|
9
|
+
* Frontmatter Module (`frontmatterKeyBlockText`, the moved `extractYamlBlock`: raw text off
|
|
10
|
+
* the one fence owner's block, so frontmatter the YAML parser refuses is still scanned), and
|
|
11
|
+
* the SUMMARY `files_modified` list through its parsed reader (`rawFrontmatterField`), not a
|
|
12
|
+
* `files_modified:` regex;
|
|
13
|
+
* - the XML-tag body extraction lives in `markdown-sectionizer.cts` (`extractXmlTagBodies`).
|
|
14
|
+
*
|
|
15
|
+
* The router-facing gate modules (`gate-decision-coverage-plan.cts`,
|
|
16
|
+
* `gate-decision-coverage-verify.cts`) import from here. This module imports no io module and
|
|
17
|
+
* performs no direct console/stdout/stderr write (ESLint-enforced).
|
|
18
|
+
*/
|
|
19
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
20
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.decisionMentioned = decisionMentioned;
|
|
24
|
+
exports.loadPlanContents = loadPlanContents;
|
|
25
|
+
exports.loadSummaryContents = loadSummaryContents;
|
|
26
|
+
exports.loadDecisionExtraction = loadDecisionExtraction;
|
|
27
|
+
exports.extractPlanDesignatedSections = extractPlanDesignatedSections;
|
|
28
|
+
exports.buildPlanMessage = buildPlanMessage;
|
|
29
|
+
exports.buildVerifyMessage = buildVerifyMessage;
|
|
30
|
+
exports.phaseCommitMessages = phaseCommitMessages;
|
|
31
|
+
exports.readModifiedFilesContent = readModifiedFilesContent;
|
|
32
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
33
|
+
const decisions_cjs_1 = require("./decisions.cjs");
|
|
34
|
+
const frontmatter_fence_cjs_1 = require("./frontmatter-fence.cjs");
|
|
35
|
+
const markdown_sectionizer_cjs_1 = require("./markdown-sectionizer.cjs");
|
|
36
|
+
const security_cjs_1 = require("./security.cjs");
|
|
37
|
+
const gate_evidence_cjs_1 = require("./gate-evidence.cjs");
|
|
38
|
+
const gate_evaluation_scope_cjs_1 = require("./gate-evaluation-scope.cjs");
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
40
|
+
const frontmatterMod = require("./frontmatter.cjs");
|
|
41
|
+
const { rawFrontmatterField, frontmatterKeyBlockText } = frontmatterMod;
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
43
|
+
const planScanMod = require("./plan-scan.cjs");
|
|
44
|
+
const { scanPhasePlans } = planScanMod;
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
46
|
+
const planningScopeMod = require("./planning-scope.cjs");
|
|
47
|
+
const { SCOPE } = planningScopeMod;
|
|
48
|
+
// ─── Decision matching ────────────────────────────────────────────────────────
|
|
49
|
+
function normalizePhrase(text) {
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
51
|
+
return String(text || '')
|
|
52
|
+
.toLowerCase()
|
|
53
|
+
.replace(/[^a-z0-9\s]/g, ' ')
|
|
54
|
+
.replace(/\s+/g, ' ')
|
|
55
|
+
.trim();
|
|
56
|
+
}
|
|
57
|
+
const SOFT_PHRASE_MIN_WORDS = 6;
|
|
58
|
+
function softPhrase(text) {
|
|
59
|
+
const words = normalizePhrase(text).split(' ').filter(Boolean);
|
|
60
|
+
if (words.length < SOFT_PHRASE_MIN_WORDS)
|
|
61
|
+
return '';
|
|
62
|
+
return words.slice(0, SOFT_PHRASE_MIN_WORDS).join(' ');
|
|
63
|
+
}
|
|
64
|
+
function decisionMentioned(haystack, decision) {
|
|
65
|
+
if (!haystack)
|
|
66
|
+
return false;
|
|
67
|
+
if (new RegExp(`\\b${decision.id}\\b`).test(haystack))
|
|
68
|
+
return true;
|
|
69
|
+
const phrase = softPhrase(decision.text);
|
|
70
|
+
return phrase ? normalizePhrase(haystack).includes(phrase) : false;
|
|
71
|
+
}
|
|
72
|
+
// ─── File reading ─────────────────────────────────────────────────────────────
|
|
73
|
+
/**
|
|
74
|
+
* The contents of the phase files `pick` selects (#5170, ADR-5057 §4). An ABSENT phase directory
|
|
75
|
+
* is "no files" (`found []`); a directory or file that exists but cannot be read is `unreadable` —
|
|
76
|
+
* a gate must not take "could not read the plan" for "the plan does not cite the decision".
|
|
77
|
+
*/
|
|
78
|
+
function readPhaseFiles(phaseDir, pick) {
|
|
79
|
+
const entries = (0, gate_evidence_cjs_1.readDirEvidence)(phaseDir);
|
|
80
|
+
if (entries.kind === 'none')
|
|
81
|
+
return (0, gate_evidence_cjs_1.evidenceFound)([]);
|
|
82
|
+
if (entries.kind === 'unreadable')
|
|
83
|
+
return entries;
|
|
84
|
+
const contents = [];
|
|
85
|
+
// #3183 (lint-plan-count-drift): source live plan/summary files from the single
|
|
86
|
+
// owner (scanPhasePlans) instead of a local readdirSync filter — picks up bare PLAN.md and
|
|
87
|
+
// nested plans/, and excludes plans marked `status: superseded`.
|
|
88
|
+
// Only SCOPE.COMPLETE is a real answer: an existing nested plans/ that could not be read (TRUNCATED)
|
|
89
|
+
// would otherwise hand the gate a short plan set and let it conclude "no plan cites the decision".
|
|
90
|
+
const scan = scanPhasePlans(phaseDir);
|
|
91
|
+
if (scan.scope !== SCOPE.COMPLETE) {
|
|
92
|
+
return { kind: 'unreadable', reason: `plan scan ${scan.scope}`, span: phaseDir };
|
|
93
|
+
}
|
|
94
|
+
for (const entry of pick(scan)) {
|
|
95
|
+
const read = (0, gate_evidence_cjs_1.readTextEvidence)(node_path_1.default.join(phaseDir, entry));
|
|
96
|
+
if (read.kind === 'unreadable')
|
|
97
|
+
return read;
|
|
98
|
+
if (read.kind === 'found')
|
|
99
|
+
contents.push(read.value);
|
|
100
|
+
}
|
|
101
|
+
return (0, gate_evidence_cjs_1.evidenceFound)(contents);
|
|
102
|
+
}
|
|
103
|
+
function loadPlanContents(phaseDir) {
|
|
104
|
+
return readPhaseFiles(phaseDir, (scan) => scan.planFiles);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* #3183 (lint-plan-count-drift): same single-owner sourcing as `loadPlanContents` —
|
|
108
|
+
* scanPhasePlans's summaryFiles instead of a local `-SUMMARY.md` readdirSync filter.
|
|
109
|
+
*/
|
|
110
|
+
function loadSummaryContents(phaseDir) {
|
|
111
|
+
return readPhaseFiles(phaseDir, (scan) => scan.summaryFiles);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* The decisions of `CONTEXT.md`. `none` is an absent file (the caller's legitimate "nothing to
|
|
115
|
+
* check"); `unreadable` is a file that exists but could not be read — it must never be extracted as
|
|
116
|
+
* empty text, which would certify "no trackable decisions".
|
|
117
|
+
*/
|
|
118
|
+
function loadDecisionExtraction(contextPath) {
|
|
119
|
+
const read = (0, gate_evidence_cjs_1.readTextEvidence)(contextPath);
|
|
120
|
+
if (read.kind !== 'found')
|
|
121
|
+
return read;
|
|
122
|
+
const extraction = (0, decisions_cjs_1.extractDecisions)(read.value);
|
|
123
|
+
return (0, gate_evidence_cjs_1.evidenceFound)({
|
|
124
|
+
trackable: extraction.decisions.filter((d) => d.trackable),
|
|
125
|
+
outcome: extraction.outcome,
|
|
126
|
+
unreadableIds: extraction.unreadableIds ?? [],
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
// ─── Plan surfaces scanned for a decision citation ────────────────────────────
|
|
130
|
+
const DESIGNATED_HEADINGS_RE = /^#{1,6}\s+(?:must[_ ]haves?|truths?|tasks?|objective)\b/i;
|
|
131
|
+
function stripCommentsAndFences(text) {
|
|
132
|
+
// HTML-comment stripping stays caller-side (the seam does not strip HTML comments).
|
|
133
|
+
// Stop-at-next-open body (ReDoS-safe, #2128); an UNCLOSED `<!--` does not match,
|
|
134
|
+
// so downstream tags are preserved (unlike a `(?:-->|$)` fallback, which would
|
|
135
|
+
// wipe to EOF and fail-close the decision-coverage gate).
|
|
136
|
+
const htmlStripped = text.replace(/<!--(?:(?!<!--)[\s\S])*?-->/g, ' ');
|
|
137
|
+
// Fenced-code stripping: delegate to the canonical CommonMark-correct seam.
|
|
138
|
+
// replaces the prior independent regex copy (```` ``` ``` ```` + `~~~ ~~~`).
|
|
139
|
+
return (0, markdown_sectionizer_cjs_1.stripFencedCode)(htmlStripped).text;
|
|
140
|
+
}
|
|
141
|
+
function extractPlanDesignatedSections(planContent) {
|
|
142
|
+
if (!planContent)
|
|
143
|
+
return '';
|
|
144
|
+
const cleaned = stripCommentsAndFences(planContent);
|
|
145
|
+
// The block is the one the one fence owner finds; the body starts after the closing fence
|
|
146
|
+
// line's line ending.
|
|
147
|
+
const fence = (0, frontmatter_fence_cjs_1.locateFrontmatterFence)(cleaned);
|
|
148
|
+
const body = fence?.closed ? cleaned.slice(fence.closingFenceEnd).replace(/^\r?\n/, '') : cleaned;
|
|
149
|
+
const parts = [];
|
|
150
|
+
for (const key of ['must_haves', 'truths', 'objective']) {
|
|
151
|
+
const block = frontmatterKeyBlockText(cleaned, key);
|
|
152
|
+
if (block)
|
|
153
|
+
parts.push(block);
|
|
154
|
+
}
|
|
155
|
+
// Replace hand-rolled split(/\r?\n/) + heading walk with the seam's collectSections.
|
|
156
|
+
// stopPredicate fires on EVERY heading (collectSections needs to start a section at
|
|
157
|
+
// each heading), then we filter to designated ones — same semantics as the prior
|
|
158
|
+
// inDesignated flag: emit the heading line + body only when DESIGNATED_HEADINGS_RE matches.
|
|
159
|
+
const sections = (0, markdown_sectionizer_cjs_1.collectSections)(body, () => true);
|
|
160
|
+
const bodyParts = [];
|
|
161
|
+
for (const section of sections) {
|
|
162
|
+
const headingLine = '#'.repeat(section.heading.level) + ' ' + section.heading.text;
|
|
163
|
+
if (DESIGNATED_HEADINGS_RE.test(headingLine)) {
|
|
164
|
+
bodyParts.push(headingLine);
|
|
165
|
+
if (section.body)
|
|
166
|
+
bodyParts.push(section.body);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
parts.push(bodyParts.join('\n'));
|
|
170
|
+
parts.push((0, markdown_sectionizer_cjs_1.extractXmlTagBodies)(cleaned));
|
|
171
|
+
return parts.join('\n\n');
|
|
172
|
+
}
|
|
173
|
+
function buildPlanMessage(uncovered) {
|
|
174
|
+
if (uncovered.length === 0)
|
|
175
|
+
return 'All trackable CONTEXT.md decisions are covered by plans.';
|
|
176
|
+
return [
|
|
177
|
+
'## Decision Coverage Gap',
|
|
178
|
+
'',
|
|
179
|
+
`${uncovered.length} CONTEXT.md decision(s) are not covered by any plan:`,
|
|
180
|
+
'',
|
|
181
|
+
...uncovered.map((item) => `- **${item.id}** (${item.category || 'uncategorized'}): ${item.text}`),
|
|
182
|
+
'',
|
|
183
|
+
'Resolve by citing `D-NN:` in any of the scanned plan surfaces: front-matter',
|
|
184
|
+
'`must_haves`/`truths`/`objective`, a `## must_haves`/`truths`/`tasks`/`objective`',
|
|
185
|
+
'heading, or an `<objective>`/`<tasks>`/`<task>`/`<action>`/`<read_first>`/`<behavior>`/`<verify>`/`<acceptance_criteria>`/`<done>`',
|
|
186
|
+
'tag body. Other locations (prose outside those headings, comments, other XML tags) are not scanned.',
|
|
187
|
+
'OR move the decision to `### Claude\'s Discretion` / tag it `[informational]` if it should not be tracked.',
|
|
188
|
+
].join('\n');
|
|
189
|
+
}
|
|
190
|
+
function buildVerifyMessage(notHonored) {
|
|
191
|
+
if (notHonored.length === 0)
|
|
192
|
+
return 'All trackable CONTEXT.md decisions are honored by shipped artifacts.';
|
|
193
|
+
return [
|
|
194
|
+
'### Decision Coverage (warning)',
|
|
195
|
+
'',
|
|
196
|
+
`${notHonored.length} decision(s) not found in shipped artifacts:`,
|
|
197
|
+
'',
|
|
198
|
+
...notHonored.map((item) => `- **${item.id}** (${item.category || 'uncategorized'}): ${item.text}`),
|
|
199
|
+
'',
|
|
200
|
+
'This is a soft warning - verification status is unchanged.',
|
|
201
|
+
].join('\n');
|
|
202
|
+
}
|
|
203
|
+
// ─── Shipped-artifact haystack (verify gate) ──────────────────────────────────
|
|
204
|
+
/**
|
|
205
|
+
* The subjects and bodies of the PHASE'S OWN commits (#5164, ADR-5057 §4) — the evaluation-scope
|
|
206
|
+
* resolver's commit set for `phaseDir`, not the last 200 commits of whatever branch is checked
|
|
207
|
+
* out. A phase with no recorded task commits widens to the commits in its directory range (the
|
|
208
|
+
* resolver says so); an unreadable phase or repository yields '' ("could not look"), and a git
|
|
209
|
+
* failure on a non-git project dir writes nothing to the terminal.
|
|
210
|
+
*/
|
|
211
|
+
function phaseCommitMessages(projectDir, phaseDir) {
|
|
212
|
+
const scope = (0, gate_evaluation_scope_cjs_1.resolveEvaluationScope)(projectDir, { kind: 'phase', phase: '', phaseDir }, { includeBody: true, includeFiles: false });
|
|
213
|
+
return scope.commits.map((c) => `${c.subject}\n${c.body ?? ''}`).join('\n');
|
|
214
|
+
}
|
|
215
|
+
/** Cap on files read across all SUMMARYs, and on bytes read per file. */
|
|
216
|
+
const MODIFIED_FILES_MAX_COUNT = 50;
|
|
217
|
+
const MODIFIED_FILES_MAX_BYTES = 256 * 1024;
|
|
218
|
+
/**
|
|
219
|
+
* The contents of every file the SUMMARYs list under frontmatter `files_modified`, contained to
|
|
220
|
+
* `projectDir` and capped at `MODIFIED_FILES_MAX_COUNT` files / `MODIFIED_FILES_MAX_BYTES` each.
|
|
221
|
+
*/
|
|
222
|
+
function readModifiedFilesContent(projectDir, summaries) {
|
|
223
|
+
const out = [];
|
|
224
|
+
let total = 0;
|
|
225
|
+
for (const summary of summaries) {
|
|
226
|
+
if (!summary)
|
|
227
|
+
continue;
|
|
228
|
+
if (total >= MODIFIED_FILES_MAX_COUNT)
|
|
229
|
+
break;
|
|
230
|
+
const field = rawFrontmatterField(summary, 'files_modified');
|
|
231
|
+
const listed = field && Array.isArray(field.value) ? field.value : [];
|
|
232
|
+
for (const entry of listed) {
|
|
233
|
+
if (total >= MODIFIED_FILES_MAX_COUNT)
|
|
234
|
+
break;
|
|
235
|
+
if (typeof entry !== 'string')
|
|
236
|
+
continue;
|
|
237
|
+
const file = entry.trim();
|
|
238
|
+
if (!file)
|
|
239
|
+
continue;
|
|
240
|
+
// Migrated off the hand-rolled prefix check (ADR-4650): resolve+contain in one
|
|
241
|
+
// step via the canonical realpath predicate — the eventual read below follows
|
|
242
|
+
// symlinks, so containment must be decided on the resolved target, not a lexical
|
|
243
|
+
// prefix. Read the value the predicate RETURNED; do not re-derive the path.
|
|
244
|
+
const candidate = node_path_1.default.isAbsolute(file) ? file : node_path_1.default.join(projectDir, file);
|
|
245
|
+
const contained = (0, security_cjs_1.tryWithinRoot)(candidate, projectDir, security_cjs_1.PathAcceptance.AbsoluteInsideRoot);
|
|
246
|
+
if (contained === null)
|
|
247
|
+
continue;
|
|
248
|
+
// An absent listed file contributes nothing readable (`''`); one that exists but cannot be
|
|
249
|
+
// read is `unreadable` — the decision it may cite was never seen (#5170).
|
|
250
|
+
const read = (0, gate_evidence_cjs_1.readTextEvidence)(contained);
|
|
251
|
+
if (read.kind === 'unreadable')
|
|
252
|
+
return read;
|
|
253
|
+
const content = read.kind === 'found' ? read.value : '';
|
|
254
|
+
out.push(content.length > MODIFIED_FILES_MAX_BYTES ? content.slice(0, MODIFIED_FILES_MAX_BYTES) : content);
|
|
255
|
+
total++;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return (0, gate_evidence_cjs_1.evidenceFound)(out.join('\n\n'));
|
|
259
|
+
}
|
|
@@ -85,14 +85,14 @@ const DECISION_ID_SOURCE = 'D[0-9]*-[A-Za-z0-9][A-Za-z0-9_-]*';
|
|
|
85
85
|
const ID_ATTEMPT_SOURCE = 'D(?:[0-9][A-Za-z0-9]*)?-';
|
|
86
86
|
/**
|
|
87
87
|
* Colon form: `- **D[phase]-NN[ [tags]]:** text`
|
|
88
|
-
* (#1343:
|
|
88
|
+
* (#1343: the pre-colon run subsumes any pre-colon prose, stops at `:**`; #4788: the run is code-span-aware — a backticked span is consumed whole, so a `:` or `*` INSIDE it is data, never grammar)
|
|
89
89
|
* Group 1 captures the FULL id including any phase prefix (#4130).
|
|
90
90
|
* The ID is consumed atomically `(?=(…))\1` — see the hardening note above
|
|
91
91
|
* the constants (#4130 follow-up); with the tail unable to give back, the
|
|
92
92
|
* remaining `[^:*]*:` scan has a single viable split and the whole match is
|
|
93
93
|
* linear in line length.
|
|
94
94
|
*/
|
|
95
|
-
const bulletColonRe = new RegExp(`^\\s*-\\s+\\*\\*(?=(${DECISION_ID_SOURCE}))\\1(?:\\s*\\[([^\\]]+)\\])?[
|
|
95
|
+
const bulletColonRe = new RegExp(`^\\s*-\\s+\\*\\*(?=(${DECISION_ID_SOURCE}))\\1(?:\\s*\\[([^\\]]+)\\])?(?:\\u0060[^\\u0060]*\\u0060|[^:*\\u0060])*:\\*\\*\\s*(.*)$`);
|
|
96
96
|
/**
|
|
97
97
|
* Em-dash form: `- **D[phase]-NN[ [tags]] — title** body`
|
|
98
98
|
* The em-dash (U+2014) or its lookalike separates the ID+tags group from a title
|
|
@@ -112,22 +112,32 @@ const bulletColonRe = new RegExp(`^\\s*-\\s+\\*\\*(?=(${DECISION_ID_SOURCE}))\\1
|
|
|
112
112
|
* candidate and `**` succeeds or fails identically; no capture involves the
|
|
113
113
|
* dash position. The ID is atomic like the other forms (driver #1).
|
|
114
114
|
*/
|
|
115
|
-
const bulletEmDashRe = new RegExp(`^\\s*-\\s+\\*\\*(?=(${DECISION_ID_SOURCE}))\\1(?:\\s*\\[([^\\]]+)\\])?[
|
|
115
|
+
const bulletEmDashRe = new RegExp(`^\\s*-\\s+\\*\\*(?=(${DECISION_ID_SOURCE}))\\1(?:\\s*\\[([^\\]]+)\\])?(?:\\u0060[^\\u0060]*\\u0060|[^*—–\\u0060])*[—–](?:\\u0060[^\\u0060]*\\u0060|[^*\\u0060])*\\*\\*\\s*(.*)$`);
|
|
116
116
|
/**
|
|
117
117
|
* Titled-colon form: `- **D[phase]-NN[ [tags]]: Title.** body`
|
|
118
118
|
* A title sits between the colon and the closing `**` (so the `:**` anchor of
|
|
119
119
|
* bulletColonRe fails, and there is no em-dash for bulletEmDashRe). This is a strict
|
|
120
120
|
* superset of the colon-immediate form, so it MUST be checked AFTER bulletColonRe and
|
|
121
|
-
* bulletEmDashRe — it only catches bullets those two miss. The title
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
121
|
+
* bulletEmDashRe — it only catches bullets those two miss. The title runs are code-span-aware
|
|
122
|
+
* (#4788) but still exclude `*`, so a genuinely-malformed bullet with no bare colon at all
|
|
123
|
+
* before `**` still fails the anchor and falls through to the parse-miss guard — the #1639
|
|
124
|
+
* fail-loud discipline: the separator must be a BARE colon before `**`. A code span's
|
|
125
|
+
* `:`/`*` is data, never grammar; an UNTERMINATED backtick now fails loud (previously it was
|
|
126
|
+
* an ordinary character) — the deliberate cost of span opacity.
|
|
127
|
+
*
|
|
128
|
+
* #4793/#4958: the pre-separator run tolerates a bare colon as prose ONLY when it is
|
|
129
|
+
* immediately followed by whitespace (`:(?=\s)`), e.g. a natural sentence colon in
|
|
130
|
+
* `D-02: Two managers … same pair: the second is rejected.`. A colon with no following
|
|
131
|
+
* whitespace (a compact/ratio-style colon like `3:1`) is never consumed by this branch, so
|
|
132
|
+
* it still hard-caps the pre-separator run and the #1639/#4130/#1343 negative-space fixtures
|
|
133
|
+
* (e.g. `D-07 ratio 3:1:**`) still fail loud. The post-separator branch is unchanged and
|
|
134
|
+
* still excludes colons, so normal greedy backtracking selects the LAST valid split (a bare
|
|
135
|
+
* colon followed by whitespace, or the anchor colon itself) before the closing `**`.
|
|
126
136
|
*
|
|
127
137
|
* The ID is consumed atomically `(?=(…))\1` like the other forms — the
|
|
128
138
|
* hardening note above the constants explains why (#4130 follow-up).
|
|
129
139
|
*/
|
|
130
|
-
const bulletTitledColonRe = new RegExp(`^\\s*-\\s+\\*\\*(?=(${DECISION_ID_SOURCE}))\\1(?:\\s*\\[([^\\]]+)\\])?[
|
|
140
|
+
const bulletTitledColonRe = new RegExp(`^\\s*-\\s+\\*\\*(?=(${DECISION_ID_SOURCE}))\\1(?:\\s*\\[([^\\]]+)\\])?(?:\\u0060[^\\u0060]*\\u0060|:(?=\\s)|[^:*\\u0060])*:(?:\\u0060[^\\u0060]*\\u0060|[^:*\\u0060])*\\*\\*\\s*(.*)$`);
|
|
131
141
|
/**
|
|
132
142
|
* #4130: the parse-miss guard's probe — a line whose bold lead-in ATTEMPTS the
|
|
133
143
|
* ID grammar (see `ID_ATTEMPT_SOURCE`) but failed all three bullet patterns
|
|
@@ -403,6 +413,7 @@ function parseDecisionLines(block) {
|
|
|
403
413
|
let current = null;
|
|
404
414
|
let openIndent = null;
|
|
405
415
|
let parseMisses = 0;
|
|
416
|
+
const unreadableIds = [];
|
|
406
417
|
const flush = () => {
|
|
407
418
|
if (current) {
|
|
408
419
|
current.text = current.text.trim();
|
|
@@ -501,6 +512,11 @@ function parseDecisionLines(block) {
|
|
|
501
512
|
if (parseMissGuardRe.test(line)) {
|
|
502
513
|
flush();
|
|
503
514
|
parseMisses += 1;
|
|
515
|
+
// #4794: carry the attempted id so a caller capturing stdout (a JSON gate)
|
|
516
|
+
// can name the decision to fix — today it exists only in this stderr warn.
|
|
517
|
+
const attempted = line.match(/\*\*\s*(D(?:[0-9][A-Za-z0-9]*)?-[A-Za-z0-9_-]*)/);
|
|
518
|
+
if (attempted && !unreadableIds.includes(attempted[1]))
|
|
519
|
+
unreadableIds.push(attempted[1]);
|
|
504
520
|
console.warn(`parseDecisions: ignored unparseable decision bullet: ${trimmed}`);
|
|
505
521
|
continue;
|
|
506
522
|
}
|
|
@@ -516,7 +532,7 @@ function parseDecisionLines(block) {
|
|
|
516
532
|
}
|
|
517
533
|
}
|
|
518
534
|
flush();
|
|
519
|
-
return { decisions: out, parseMisses };
|
|
535
|
+
return { decisions: out, parseMisses, unreadableIds };
|
|
520
536
|
}
|
|
521
537
|
// ─── Primary entry point: extractDecisions ────────────────────────────────────
|
|
522
538
|
/**
|
|
@@ -541,13 +557,13 @@ function extractDecisions(content) {
|
|
|
541
557
|
const taggedBlocks = (0, markdown_sectionizer_cjs_1.extractTaggedBlocks)(stripped, 'decisions');
|
|
542
558
|
if (taggedBlocks.length > 0) {
|
|
543
559
|
const combined = taggedBlocks.join('\n\n');
|
|
544
|
-
const { decisions, parseMisses } = parseDecisionLines(combined);
|
|
560
|
+
const { decisions, parseMisses, unreadableIds } = parseDecisionLines(combined);
|
|
545
561
|
if (decisions.length > 0 && parseMisses === 0) {
|
|
546
562
|
return { decisions, outcome: 'parsed' };
|
|
547
563
|
}
|
|
548
564
|
// FIX B: parse-misses present — could-not-parse even if some decisions extracted.
|
|
549
565
|
if (parseMisses > 0) {
|
|
550
|
-
return { decisions, outcome: 'could-not-parse' };
|
|
566
|
+
return { decisions, outcome: 'could-not-parse', unreadableIds };
|
|
551
567
|
}
|
|
552
568
|
// FIX A: Block present but 0 extracted and no parse-misses.
|
|
553
569
|
// Only report could-not-parse when there is genuine evidence of real decisions
|
|
@@ -568,13 +584,13 @@ function extractDecisions(content) {
|
|
|
568
584
|
// stripFences:true → inner fences inside the section body are stripped.
|
|
569
585
|
const section = (0, markdown_sectionizer_cjs_1.collectSection)(content, (h) => /decisions?\b/i.test(h.text), { levelBounded: true, stripFences: true });
|
|
570
586
|
if (section !== null) {
|
|
571
|
-
const { decisions, parseMisses } = parseDecisionLines(section.body);
|
|
587
|
+
const { decisions, parseMisses, unreadableIds } = parseDecisionLines(section.body);
|
|
572
588
|
if (decisions.length > 0 && parseMisses === 0) {
|
|
573
589
|
return { decisions, outcome: 'parsed' };
|
|
574
590
|
}
|
|
575
591
|
// FIX B: parse-misses present — could-not-parse even if some decisions extracted.
|
|
576
592
|
if (parseMisses > 0) {
|
|
577
|
-
return { decisions, outcome: 'could-not-parse' };
|
|
593
|
+
return { decisions, outcome: 'could-not-parse', unreadableIds };
|
|
578
594
|
}
|
|
579
595
|
// FIX A: Heading found but 0 extracted and no parse-misses.
|
|
580
596
|
// Report could-not-parse when the section body holds a decision-entry-shaped
|