@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
|
@@ -571,6 +571,55 @@ function sliceMilestoneWindow(content, version) {
|
|
|
571
571
|
return null;
|
|
572
572
|
return content.slice(selected.index, computeMilestoneSectionEnd(content, selected[0], selected.index));
|
|
573
573
|
}
|
|
574
|
+
/**
|
|
575
|
+
* Enumerate the milestone section ranges recognized by the ROADMAP readers.
|
|
576
|
+
* Markdown boundaries reuse the reader's heading tokenizer, milestone-signal
|
|
577
|
+
* vocabulary, name/version extractor, and section-end owner. Collapsed
|
|
578
|
+
* archives reuse the same `<details><summary>` shape handled by
|
|
579
|
+
* `extractCurrentMilestoneScoped`.
|
|
580
|
+
*/
|
|
581
|
+
function milestoneSections(content) {
|
|
582
|
+
const sections = [];
|
|
583
|
+
const headings = (0, markdown_sectionizer_cjs_1.tokenizeHeadings)(content);
|
|
584
|
+
for (const heading of headings) {
|
|
585
|
+
if (heading.level < 1 || heading.level > 3)
|
|
586
|
+
continue;
|
|
587
|
+
if (/^Phase\s+\S/i.test(heading.text))
|
|
588
|
+
continue;
|
|
589
|
+
if (!MILESTONE_HEADING_SIGNAL_PATTERN.test(heading.text))
|
|
590
|
+
continue;
|
|
591
|
+
const extracted = extractMilestoneHeadingName(heading.text);
|
|
592
|
+
const version = extracted?.version ?? null;
|
|
593
|
+
const versionMajor = version?.match(/^v(\d+)/i);
|
|
594
|
+
const milestoneInt = versionMajor ? parseInt(versionMajor[1], 10) : null;
|
|
595
|
+
const lineEnd = content.indexOf('\n', heading.offset);
|
|
596
|
+
const fullLine = content.slice(heading.offset, lineEnd === -1 ? content.length : lineEnd);
|
|
597
|
+
sections.push({
|
|
598
|
+
start: heading.offset,
|
|
599
|
+
end: computeMilestoneSectionEnd(content, fullLine, heading.offset, undefined, headings),
|
|
600
|
+
version,
|
|
601
|
+
milestoneInt: milestoneInt !== null && Number.isSafeInteger(milestoneInt) ? milestoneInt : null,
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
const detailsPattern = /<details\b[^>]*>[\s\S]*?<\/details>/gi;
|
|
605
|
+
let detailsMatch;
|
|
606
|
+
while ((detailsMatch = detailsPattern.exec(content)) !== null) {
|
|
607
|
+
const summary = detailsMatch[0].match(/<summary[^>]*>([^<]*)<\/summary>/i)?.[1]?.trim() ?? '';
|
|
608
|
+
if (!MILESTONE_HEADING_SIGNAL_PATTERN.test(summary))
|
|
609
|
+
continue;
|
|
610
|
+
const extracted = extractMilestoneHeadingName(summary);
|
|
611
|
+
const version = extracted?.version ?? null;
|
|
612
|
+
const versionMajor = version?.match(/^v(\d+)/i);
|
|
613
|
+
const milestoneInt = versionMajor ? parseInt(versionMajor[1], 10) : null;
|
|
614
|
+
sections.push({
|
|
615
|
+
start: detailsMatch.index,
|
|
616
|
+
end: detailsMatch.index + detailsMatch[0].length,
|
|
617
|
+
version,
|
|
618
|
+
milestoneInt: milestoneInt !== null && Number.isSafeInteger(milestoneInt) ? milestoneInt : null,
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
return sections.sort((a, b) => a.start - b.start || a.end - b.end);
|
|
622
|
+
}
|
|
574
623
|
/**
|
|
575
624
|
* #3184: counts RAW phase references — a `#{2,4} Phase <id>:` heading
|
|
576
625
|
* (fence-aware via `tokenizeHeadings`) or a `#2199` bullet entry — BEFORE any
|
|
@@ -600,17 +649,37 @@ function sliceMilestoneWindow(content, version) {
|
|
|
600
649
|
// decoy `### [GSD.04] Notes:` outside the window manufactured a false V005
|
|
601
650
|
// while suppressing the correct V004. The digit anchor forecloses both.
|
|
602
651
|
const BRACKET_PHASE_ENTRY_HEADING_RE = new RegExp(`^${PHASE_HEADING_PREFIX_SRC}${PHASE_NUMBER_TOKEN_SOURCE}${OPTIONAL_PHASE_TAG_SOURCE}\\s*:`, 'i');
|
|
652
|
+
// #1729: `(?:\s*\([^)\n]{0,200}\))?` tolerates a pre-colon ( ) tag (literal
|
|
653
|
+
// mirror of OPTIONAL_PHASE_TAG_SOURCE). Hoisted out of hasPhaseEntries (#4144
|
|
654
|
+
// round 5 Blocker 1) so a consumer OUTSIDE this file's own phase-entry count —
|
|
655
|
+
// the bracket roadmap migrator's "phase-like but unparsed" refusal
|
|
656
|
+
// (src/roadmap-upgrade.cts) — can ask "is this heading text a phase heading
|
|
657
|
+
// by the readers' own rules" without re-deriving the pattern. A heading with
|
|
658
|
+
// no phase-number token and no trailing colon (`## Phase Details`, `##
|
|
659
|
+
// Phase Lifecycle`, `### Phase Notes`) is NOT a phase heading by this
|
|
660
|
+
// grammar — it is an ordinary section heading that happens to start with the
|
|
661
|
+
// word "Phase".
|
|
662
|
+
const PHASE_HEADING_TEXT_RE = /^(?:\[[^\]]{1,200}\]\s*)?Phase\s+([\w][\w.-]*)(?:\s*\([^)\n]{0,200}\))?\s*:/i;
|
|
663
|
+
/**
|
|
664
|
+
* #4144 round 5 Blocker 1: whether `headingText` — a heading's text with its
|
|
665
|
+
* leading `#{1,6}` markers and surrounding whitespace already stripped
|
|
666
|
+
* (`tokenizeHeadings`'s own `h.text`, or the equivalent for a line a caller
|
|
667
|
+
* already knows is a `#{2,4}` heading) — is a phase heading by the readers'
|
|
668
|
+
* own grammar. The single owner of this test; `hasPhaseEntries` below is
|
|
669
|
+
* itself just the first caller.
|
|
670
|
+
*/
|
|
671
|
+
function isPhaseHeadingText(headingText) {
|
|
672
|
+
return PHASE_HEADING_TEXT_RE.test(headingText);
|
|
673
|
+
}
|
|
603
674
|
function hasPhaseEntries(markdown, phaseIdConvention) {
|
|
604
|
-
// #1729: `(?:\s*\([^)\n]{0,200}\))?` tolerates a pre-colon ( ) tag (literal mirror of OPTIONAL_PHASE_TAG_SOURCE).
|
|
605
675
|
// #3641: the widened grammar engages ONLY when the resolved convention is
|
|
606
676
|
// 'bracket' — a project that has not opted in runs the legacy pattern
|
|
607
677
|
// alone, byte-identically.
|
|
608
|
-
const phaseHeadingPattern = /^(?:\[[^\]]{1,200}\]\s*)?Phase\s+([\w][\w.-]*)(?:\s*\([^)\n]{0,200}\))?\s*:/i;
|
|
609
678
|
const bracketMode = phaseIdConvention === 'bracket';
|
|
610
679
|
for (const h of (0, markdown_sectionizer_cjs_1.tokenizeHeadings)(markdown)) {
|
|
611
680
|
if (h.level < 2 || h.level > 4)
|
|
612
681
|
continue;
|
|
613
|
-
if (
|
|
682
|
+
if (isPhaseHeadingText(h.text))
|
|
614
683
|
return true;
|
|
615
684
|
if (bracketMode && BRACKET_PHASE_ENTRY_HEADING_RE.test(h.text))
|
|
616
685
|
return true;
|
|
@@ -671,6 +740,23 @@ function collectTablePhaseRows(window) {
|
|
|
671
740
|
}
|
|
672
741
|
return rows;
|
|
673
742
|
}
|
|
743
|
+
/**
|
|
744
|
+
* True when `content` contains a GFM table whose header row is phase-listing
|
|
745
|
+
* SHAPED (`| Phase | ... |`), regardless of whether it also declares a `Name`
|
|
746
|
+
* column. `collectTablePhaseRows` correctly refuses to mint a phase from a
|
|
747
|
+
* `| Phase | Status |`-shaped table (no name column, so no declaration) —
|
|
748
|
+
* but that table's mere presence still signals this roadmap has moved to
|
|
749
|
+
* table-based tracking, not checklist-based tracking. Callers that decide
|
|
750
|
+
* whether to treat bare checklist entries as phase declarations (#4899's
|
|
751
|
+
* roadmap.cts synthesis fallback) must see this signal even when
|
|
752
|
+
* `collectTablePhaseRows` itself returns nothing for the same content —
|
|
753
|
+
* otherwise a thin, name-less Progress table cannot suppress a checklist
|
|
754
|
+
* synthesis it was never meant to coexist with.
|
|
755
|
+
*/
|
|
756
|
+
function hasPhaseListingTableHeader(content) {
|
|
757
|
+
const unfenced = (0, markdown_sectionizer_cjs_1.stripFencedCode)(content).text;
|
|
758
|
+
return unfenced.split(/\r?\n/).some((line) => PHASE_LISTING_HEADER_RE.test(line));
|
|
759
|
+
}
|
|
674
760
|
/**
|
|
675
761
|
* #3262: the sole owner of "which phase ids does THIS milestone window
|
|
676
762
|
* declare". Extracted verbatim from `getMilestonePhaseFilter`'s former inline
|
|
@@ -840,6 +926,44 @@ function classifyMilestoneWindow(input) {
|
|
|
840
926
|
SCOPE.COMPLETE // rows 6, 7
|
|
841
927
|
);
|
|
842
928
|
}
|
|
929
|
+
// #5007 (Phase 6 / ADR-4910 §8): the bulk phase-heading-block strip (heading
|
|
930
|
+
// line + body through to the next heading of any level) used by BOTH the
|
|
931
|
+
// <details>-fallback branch and preambleWithoutPhaseDetails inside
|
|
932
|
+
// extractCurrentMilestoneScoped below — literally the same regex, previously
|
|
933
|
+
// duplicated verbatim at both call sites. Composed from
|
|
934
|
+
// phaseHeadingPrefixSrcFor (LABEL_ONLY, no convention argument — reproduces
|
|
935
|
+
// the prior bare `Phase\s+` literal byte-for-byte, same non-widening
|
|
936
|
+
// discipline as the phase.cts counter sites) rather than routed through
|
|
937
|
+
// buildPhaseHeadingScanRegex, since this site needs the whole matched block
|
|
938
|
+
// (heading + body), not a phase-number/title capture. The one real behavior
|
|
939
|
+
// change here is the phase-number token itself: the prior literal admitted
|
|
940
|
+
// any `[\w][\w.-]*` (including non-numeric garbage); PHASE_NUMBER_TOKEN_SOURCE
|
|
941
|
+
// tightens it to the real phase-number grammar (digits, optional trailing
|
|
942
|
+
// letter, dotted subphases) — verified against real phase-number fixtures
|
|
943
|
+
// (plain, decimal, and bracket-tag-bearing) in tests/roadmap-parser.test.cjs.
|
|
944
|
+
const PHASE_HEADING_BLOCK_STRIP_RE = new RegExp(
|
|
945
|
+
// #1729: `(?:\s*\([^)\n]{0,200}\))?` (OPTIONAL_PHASE_TAG_SOURCE) tolerates a pre-colon ( ) tag.
|
|
946
|
+
`^#{2,4}\\s*${phaseHeadingPrefixSrcFor(PHASE_HEADING_BASELINE.LABEL_ONLY)}${PHASE_NUMBER_TOKEN_SOURCE}${OPTIONAL_PHASE_TAG_SOURCE}\\s*:[^\\n]*(?:\\n(?!#{1,6}\\s)[^\\n]*)*\\n?`, 'gim');
|
|
947
|
+
/**
|
|
948
|
+
* #5038: single owner for classifying a `milestone:` scalar as STATE.md spells
|
|
949
|
+
* it. The frontmatter parser (FAILSAFE_SCHEMA) and the raw-regex readers both
|
|
950
|
+
* see YAML null as text, so every reader classifies it here. Recognizes the
|
|
951
|
+
* YAML 1.2 core-schema null spellings (`null`, `Null`, `NULL`, `~`) with an
|
|
952
|
+
* optional trailing ` # comment` and optional surrounding quotes (the
|
|
953
|
+
* frontmatter parser has already stripped them, so the raw readers must agree);
|
|
954
|
+
* a blank value is absent, not null.
|
|
955
|
+
*/
|
|
956
|
+
function classifyMilestoneScalar(raw) {
|
|
957
|
+
if (typeof raw !== 'string')
|
|
958
|
+
return { explicitNull: false, version: null };
|
|
959
|
+
const trimmed = raw.trim();
|
|
960
|
+
if (trimmed === '')
|
|
961
|
+
return { explicitNull: false, version: null };
|
|
962
|
+
const bare = trimmed.replace(/\s+#.*$/, '').trim().replace(/^(['"])(.*)\1$/, '$2');
|
|
963
|
+
if (/^(?:null|Null|NULL|~)$/.test(bare))
|
|
964
|
+
return { explicitNull: true, version: null };
|
|
965
|
+
return { explicitNull: false, version: trimmed };
|
|
966
|
+
}
|
|
843
967
|
/**
|
|
844
968
|
* Extract the current milestone section from ROADMAP.md by positive lookup,
|
|
845
969
|
* carrying a `scope` discriminator (ADR-3180 Decision 2) alongside the value.
|
|
@@ -874,18 +998,23 @@ function extractCurrentMilestoneScoped(content, cwd, ws, phaseIdConvention) {
|
|
|
874
998
|
return { value: stripShippedMilestones(content), scope: SCOPE.COMPLETE };
|
|
875
999
|
}
|
|
876
1000
|
let version = null;
|
|
1001
|
+
let stateAssertsNoMilestone = false;
|
|
877
1002
|
try {
|
|
878
1003
|
const statePath = node_path_1.default.join(planningDir(cwd, ws), 'STATE.md');
|
|
879
1004
|
const stateRaw = (0, shell_command_projection_cjs_1.platformReadSync)(statePath);
|
|
880
1005
|
if (stateRaw !== null) {
|
|
881
1006
|
const milestoneMatch = stateRaw.match(/^milestone:\s*(.+)/m);
|
|
882
1007
|
if (milestoneMatch) {
|
|
883
|
-
|
|
1008
|
+
const classified = classifyMilestoneScalar(milestoneMatch[1]);
|
|
1009
|
+
version = classified.version;
|
|
1010
|
+
stateAssertsNoMilestone = classified.explicitNull;
|
|
884
1011
|
}
|
|
885
1012
|
}
|
|
886
1013
|
}
|
|
887
1014
|
catch { /* ignore */ }
|
|
888
|
-
|
|
1015
|
+
// #5038: an explicit `milestone: null` is a deliberate "no milestone" — do
|
|
1016
|
+
// not let the in-progress bullet guess one (same stance as getMilestoneInfo).
|
|
1017
|
+
if (!version && !stateAssertsNoMilestone) {
|
|
889
1018
|
const inProgressMatch = content.match(/(?:🚧|🔄)\s*\*\*v(\d+\.\d+)\s/);
|
|
890
1019
|
if (inProgressMatch) {
|
|
891
1020
|
version = 'v' + inProgressMatch[1];
|
|
@@ -964,8 +1093,9 @@ function extractCurrentMilestoneScoped(content, cwd, ws, phaseIdConvention) {
|
|
|
964
1093
|
const firstMilestoneMatch = content.match(anyMilestoneOrDetails);
|
|
965
1094
|
const preambleCutoff = firstMilestoneMatch ? firstMilestoneMatch.index : detailsOpenIdx;
|
|
966
1095
|
const preamble = (0, markdown_sectionizer_cjs_1.stripTaggedBlocks)(content.slice(0, preambleCutoff), 'details')
|
|
967
|
-
// #
|
|
968
|
-
.
|
|
1096
|
+
// #5007 (Phase 6 / ADR-4910 §8): shared owner, see
|
|
1097
|
+
// PHASE_HEADING_BLOCK_STRIP_RE above.
|
|
1098
|
+
.replace(PHASE_HEADING_BLOCK_STRIP_RE, '')
|
|
969
1099
|
.replace(/^#{1,4}\s*Phase Details\b[^\n]*\n?/gim, '');
|
|
970
1100
|
const value = preamble + content.slice(detailsOpenIdx, detailsEnd);
|
|
971
1101
|
return {
|
|
@@ -1200,15 +1330,23 @@ function extractCurrentMilestoneScoped(content, cwd, ws, phaseIdConvention) {
|
|
|
1200
1330
|
// every phase (phase_count: 0, exit 0). Only strip preamble phase details when
|
|
1201
1331
|
// the selected milestone section actually contains its own — otherwise the
|
|
1202
1332
|
// preamble phases ARE this milestone's phases and must be preserved.
|
|
1203
|
-
|
|
1333
|
+
// #5007 (Phase 6 / ADR-4910 §8): a pure "does this section have ANY phase
|
|
1334
|
+
// heading" boolean — same shape as phase.cts:1691's anyHeadingPattern
|
|
1335
|
+
// (composed directly from phaseHeadingPrefixSrcFor, no shared owner exposes
|
|
1336
|
+
// a captureless existence check), but this site's terminal token is `\S`
|
|
1337
|
+
// (any non-whitespace), not phase.cts:1691's `\d` — kept as `\S` to
|
|
1338
|
+
// reproduce this site's own prior behavior byte-for-byte rather than
|
|
1339
|
+
// forcing the two sites onto an identical terminal token that would be a
|
|
1340
|
+
// behavior change here.
|
|
1341
|
+
const currentSectionHasPhaseDetails = new RegExp(`^#{2,4}\\s*${phaseHeadingPrefixSrcFor(PHASE_HEADING_BASELINE.LABEL_ONLY)}\\S`, 'im').test(currentSection);
|
|
1204
1342
|
const preambleBase = (0, markdown_sectionizer_cjs_1.stripTaggedBlocks)(beforeMilestones, 'details');
|
|
1205
1343
|
// #3235: the conditional wraps the REPLACE, not the pattern. This used to select between the
|
|
1206
1344
|
// strip regex and a `/$/` sentinel, which made the do-not-strip branch an identity replacement
|
|
1207
1345
|
// (CodeQL js/identity-replacement, alert 53) -- correct, but it left both branches sharing one
|
|
1208
1346
|
// replacement argument, so changing `''` would silently give the no-op branch a real effect.
|
|
1209
|
-
// #
|
|
1347
|
+
// #5007 (Phase 6 / ADR-4910 §8): shared owner, see PHASE_HEADING_BLOCK_STRIP_RE above.
|
|
1210
1348
|
const preambleWithoutPhaseDetails = currentSectionHasPhaseDetails
|
|
1211
|
-
? preambleBase.replace(
|
|
1349
|
+
? preambleBase.replace(PHASE_HEADING_BLOCK_STRIP_RE, '')
|
|
1212
1350
|
: preambleBase;
|
|
1213
1351
|
// Unconditional in BOTH branches -- the #730 `Phase Details` heading strip is independent of
|
|
1214
1352
|
// whether the selected milestone section carries phase details of its own.
|
|
@@ -1618,14 +1756,22 @@ function getMilestoneInfo(cwd) {
|
|
|
1618
1756
|
if (roadmap === null)
|
|
1619
1757
|
throw new Error('missing');
|
|
1620
1758
|
let stateVersion = null;
|
|
1759
|
+
// #5038: true only when the `milestone:` key is PRESENT and classifies as
|
|
1760
|
+
// an explicit null (any spelling classifyMilestoneScalar accepts), as
|
|
1761
|
+
// opposed to ABSENT. Gates the ROADMAP auto-derivation fallback, which
|
|
1762
|
+
// only bootstraps a milestone for a project that never mentioned one.
|
|
1763
|
+
let explicitlyNoMilestone = false;
|
|
1621
1764
|
if (cwd) {
|
|
1622
1765
|
try {
|
|
1623
1766
|
const statePath = node_path_1.default.join(planningDir(cwd), 'STATE.md');
|
|
1624
1767
|
const stateRaw = (0, shell_command_projection_cjs_1.platformReadSync)(statePath);
|
|
1625
1768
|
if (stateRaw !== null) {
|
|
1626
1769
|
const m = stateRaw.match(/^milestone:\s*(.+)/m);
|
|
1627
|
-
if (m)
|
|
1628
|
-
|
|
1770
|
+
if (m) {
|
|
1771
|
+
const classified = classifyMilestoneScalar(m[1]);
|
|
1772
|
+
explicitlyNoMilestone = classified.explicitNull;
|
|
1773
|
+
stateVersion = classified.version;
|
|
1774
|
+
}
|
|
1629
1775
|
}
|
|
1630
1776
|
}
|
|
1631
1777
|
catch {
|
|
@@ -1682,6 +1828,11 @@ function getMilestoneInfo(cwd) {
|
|
|
1682
1828
|
// or heading-but-nameless). §7.2 rule 4 — never fabricate a name.
|
|
1683
1829
|
return scoped({ version: stateVersion, name: null }, SCOPE.TRUNCATED);
|
|
1684
1830
|
}
|
|
1831
|
+
// #5038: an explicit null is a deliberate "no milestone"; do not let the
|
|
1832
|
+
// auto-derivation fallback below replace it with a guessed version.
|
|
1833
|
+
if (explicitlyNoMilestone) {
|
|
1834
|
+
return scoped(null, SCOPE.UNSCOPED);
|
|
1835
|
+
}
|
|
1685
1836
|
// No STATE.md version. The 🚧 in-progress bullet is still consulted first
|
|
1686
1837
|
// (unchanged from the pre-#3216 fallback).
|
|
1687
1838
|
const inProgressMatch = roadmap.match(/🚧\s*\*\*v(\d+(?:\.\d+)+)\s+([^*]+)\*\*/);
|
|
@@ -2015,17 +2166,21 @@ function currentMilestoneRawRanges(content, cwd) {
|
|
|
2015
2166
|
if (!cwd)
|
|
2016
2167
|
return null;
|
|
2017
2168
|
let version = null;
|
|
2169
|
+
let stateAssertsNoMilestone = false;
|
|
2018
2170
|
try {
|
|
2019
2171
|
const statePath = node_path_1.default.join(planningDir(cwd), 'STATE.md');
|
|
2020
2172
|
const stateRaw = (0, shell_command_projection_cjs_1.platformReadSync)(statePath);
|
|
2021
2173
|
if (stateRaw !== null) {
|
|
2022
2174
|
const milestoneMatch = stateRaw.match(/^milestone:\s*(.+)/m);
|
|
2023
|
-
if (milestoneMatch)
|
|
2024
|
-
|
|
2175
|
+
if (milestoneMatch) {
|
|
2176
|
+
const classified = classifyMilestoneScalar(milestoneMatch[1]);
|
|
2177
|
+
version = classified.version;
|
|
2178
|
+
stateAssertsNoMilestone = classified.explicitNull;
|
|
2179
|
+
}
|
|
2025
2180
|
}
|
|
2026
2181
|
}
|
|
2027
2182
|
catch { /* ignore */ }
|
|
2028
|
-
if (!version) {
|
|
2183
|
+
if (!version && !stateAssertsNoMilestone) {
|
|
2029
2184
|
const inProgressMatch = content.match(/(?:🚧|🔄)\s*\*\*v(\d+\.\d+)\s/);
|
|
2030
2185
|
if (inProgressMatch)
|
|
2031
2186
|
version = 'v' + inProgressMatch[1];
|
|
@@ -2056,6 +2211,69 @@ function currentMilestoneRawRanges(content, cwd) {
|
|
|
2056
2211
|
}
|
|
2057
2212
|
return { primary: { start: sectionStart, end: sectionEnd }, details };
|
|
2058
2213
|
}
|
|
2214
|
+
/**
|
|
2215
|
+
* #4731 — extract a bold-labeled phase field (Goal, Requirements, ...) reading
|
|
2216
|
+
* past hard-wrapped continuation lines. The roadmapper soft-wraps long fields
|
|
2217
|
+
* at ~85 chars, so a single-line capture silently truncated every wrapped
|
|
2218
|
+
* Goal/Requirements. Stops at: another `**Field**` label line, a blank line,
|
|
2219
|
+
* or any heading. Wrapped lines are trimmed and joined with single spaces; a
|
|
2220
|
+
* single-line field is returned unchanged (trimmed). Returns null when the
|
|
2221
|
+
* label is absent.
|
|
2222
|
+
*/
|
|
2223
|
+
function extractPhaseFieldMultiline(section, label) {
|
|
2224
|
+
// #2769 label shapes: `**X:**`, `**X**:`, and the spaced `**X** :`.
|
|
2225
|
+
// #4837: anchored to line start (`^[ \t]*`, `m` flag) so an inline
|
|
2226
|
+
// `**Label**` mention embedded in an EARLIER field's own body text cannot
|
|
2227
|
+
// shadow the real field's own declaration line. `[ \t]*` (not `\s*`) keeps
|
|
2228
|
+
// the anchor scoped to same-line leading whitespace under the `m` flag.
|
|
2229
|
+
const labelRe = new RegExp('^[ \\t]*\\*\\*' + label + '(?::\\*\\*|\\*\\*\\s*:?)\\s*([^\\n]+)', 'im');
|
|
2230
|
+
const match = section.match(labelRe);
|
|
2231
|
+
if (!match)
|
|
2232
|
+
return null;
|
|
2233
|
+
const startIdx = match.index ?? 0;
|
|
2234
|
+
const after = section.slice(startIdx + match[0].length);
|
|
2235
|
+
const firstLine = match[1].trim();
|
|
2236
|
+
// #4837 (isolated-review finding): the continuation loop's fence-stop check
|
|
2237
|
+
// only ever sees lines AFTER the label's own line — a fence opener on the
|
|
2238
|
+
// SAME line as the label (`**Requirements:** ```js`) was invisible to it,
|
|
2239
|
+
// leaking one line of fence content before the closing fence line
|
|
2240
|
+
// coincidentally matched the same stop check. Checked here too, so a fence
|
|
2241
|
+
// opening on the label's own line is caught just as conservatively.
|
|
2242
|
+
if (/^(?:`{3,}|~{3,})/.test(firstLine))
|
|
2243
|
+
return null;
|
|
2244
|
+
const contLines = [];
|
|
2245
|
+
const lines = after.split('\n');
|
|
2246
|
+
for (let li = 0; li < lines.length; li++) {
|
|
2247
|
+
const raw = lines[li];
|
|
2248
|
+
// The split's first element is the remainder of the captured first line's
|
|
2249
|
+
// own newline — an empty leading element is the line break, not a blank
|
|
2250
|
+
// continuation line.
|
|
2251
|
+
if (li === 0 && !raw.trim())
|
|
2252
|
+
continue;
|
|
2253
|
+
if (!raw.trim())
|
|
2254
|
+
break;
|
|
2255
|
+
// #4837: a list item is a structural boundary — the real corruption
|
|
2256
|
+
// vector (a `- Deferred to Phase N: OTHER-ID` bullet folding a foreign
|
|
2257
|
+
// REQ-ID into this field's citation-scan input).
|
|
2258
|
+
if (/^\s*[-*+]\s/.test(raw))
|
|
2259
|
+
break;
|
|
2260
|
+
// #4837: case-insensitive label-start character class — a
|
|
2261
|
+
// lowercase-first-letter label (`**requirements:**`) is as much a field
|
|
2262
|
+
// boundary as a capitalized one.
|
|
2263
|
+
if (/^\s*\*\*[A-Za-z][A-Za-z ]*:?(\*\*)?:?\s/.test(raw))
|
|
2264
|
+
break;
|
|
2265
|
+
if (/^\s*#{1,4}\s/.test(raw))
|
|
2266
|
+
break;
|
|
2267
|
+
if (/^\s*\|/.test(raw))
|
|
2268
|
+
break;
|
|
2269
|
+
// #4837: a fenced code block opener stops the scan — folding fence
|
|
2270
|
+
// content is never safe, and stopping early is conservative.
|
|
2271
|
+
if (/^\s*(?:`{3,}|~{3,})/.test(raw))
|
|
2272
|
+
break;
|
|
2273
|
+
contLines.push(raw.trim());
|
|
2274
|
+
}
|
|
2275
|
+
return [firstLine, ...contLines].join(' ').trim() || null;
|
|
2276
|
+
}
|
|
2059
2277
|
module.exports = {
|
|
2060
2278
|
stripShippedMilestones,
|
|
2061
2279
|
extractCurrentMilestone,
|
|
@@ -2065,6 +2283,7 @@ module.exports = {
|
|
|
2065
2283
|
replaceInCurrentMilestone,
|
|
2066
2284
|
getRoadmapPhaseInternal,
|
|
2067
2285
|
getMilestoneInfo,
|
|
2286
|
+
classifyMilestoneScalar,
|
|
2068
2287
|
getMilestonePhaseFilter,
|
|
2069
2288
|
currentMilestoneRawRanges,
|
|
2070
2289
|
withPhaseSection,
|
|
@@ -2077,6 +2296,7 @@ module.exports = {
|
|
|
2077
2296
|
// own doc comment. milestone.cts's destructive-consumer guard consumes
|
|
2078
2297
|
// this instead of composing locate+select+section-end itself.
|
|
2079
2298
|
sliceMilestoneWindow,
|
|
2299
|
+
milestoneSections,
|
|
2080
2300
|
hasVersionedMilestones,
|
|
2081
2301
|
hasMilestoneSectioning,
|
|
2082
2302
|
// #3642: the >=1 sibling buildStateFrontmatter's unbounded branch consumes.
|
|
@@ -2090,9 +2310,16 @@ module.exports = {
|
|
|
2090
2310
|
// guards and the edit-phase workflow's pre/post capture are built on.
|
|
2091
2311
|
scanMilestonePhaseIds,
|
|
2092
2312
|
collectTablePhaseRows,
|
|
2313
|
+
hasPhaseListingTableHeader,
|
|
2093
2314
|
findMilestoneScopeHeadingLines,
|
|
2094
2315
|
// #3641: the scope axis's phase-ENTRY predicate, exported so roadmap
|
|
2095
2316
|
// validate's V004 document-level check routes through the same single
|
|
2096
2317
|
// owner (and its convention gate) instead of a private inline copy.
|
|
2318
|
+
extractPhaseFieldMultiline,
|
|
2097
2319
|
hasPhaseEntries,
|
|
2320
|
+
// #4144 round 5 Blocker 1: the readers' own phase-heading grammar, so the
|
|
2321
|
+
// bracket roadmap migrator's "phase-like but unparsed" refusal
|
|
2322
|
+
// (src/roadmap-upgrade.cts) can gate on it instead of a private, looser
|
|
2323
|
+
// "starts with the word Phase" regex.
|
|
2324
|
+
isPhaseHeadingText,
|
|
2098
2325
|
};
|