@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
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
* Complexity-triggered refactor extension point — analyzer, evaluator, and
|
|
4
4
|
* baseline persistence (issue #1953).
|
|
5
5
|
*
|
|
6
|
-
* LEAF MODULE — imports ONLY: node:fs, node:path
|
|
6
|
+
* LEAF MODULE — imports ONLY: node:fs, node:path, and the zero-import leaf
|
|
7
|
+
* frontmatter-fence.cjs (the one frontmatter fence owner, read by parseProposal). No other
|
|
8
|
+
* src/ imports.
|
|
7
9
|
*
|
|
8
10
|
* Pipeline: analyzeSource (decision-point complexity per function, via
|
|
9
11
|
* stripLiterals to blank comments/string/regex content while preserving
|
|
@@ -49,6 +51,7 @@ exports.readBaseline = readBaseline;
|
|
|
49
51
|
exports.writeBaseline = writeBaseline;
|
|
50
52
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
51
53
|
const node_path_1 = __importDefault(require("node:path"));
|
|
54
|
+
const frontmatter_fence_cjs_1 = require("./frontmatter-fence.cjs");
|
|
52
55
|
// ─── Constants ─────────────────────────────────────────────────────────────
|
|
53
56
|
exports.BASELINE_FILE_NAME = 'complexity-baseline.json'; // under .planning/
|
|
54
57
|
exports.PROPOSAL_SUFFIX = '-REFACTOR.md'; // ${PHASE_DIR}/${PADDED}-REFACTOR.md
|
|
@@ -1018,13 +1021,11 @@ function renderProposal(p) {
|
|
|
1018
1021
|
*/
|
|
1019
1022
|
function parseProposal(text) {
|
|
1020
1023
|
try {
|
|
1021
|
-
|
|
1024
|
+
// The block is the one the one fence owner finds (`locateFrontmatterFence`).
|
|
1025
|
+
const fence = (0, frontmatter_fence_cjs_1.locateFrontmatterFence)(text);
|
|
1026
|
+
if (!fence?.closed)
|
|
1022
1027
|
return null;
|
|
1023
|
-
const
|
|
1024
|
-
const closeIdx = text.indexOf('\n---', headerEnd);
|
|
1025
|
-
if (closeIdx === -1)
|
|
1026
|
-
return null;
|
|
1027
|
-
const yamlBody = text.slice(headerEnd, closeIdx);
|
|
1028
|
+
const yamlBody = text.slice(fence.openEnd, fence.bodyEnd);
|
|
1028
1029
|
const fm = {};
|
|
1029
1030
|
for (const rawLine of yamlBody.split(/\r?\n/)) {
|
|
1030
1031
|
const line = rawLine.replace(/\r$/, '');
|
|
@@ -28,6 +28,9 @@ const node_fs_1 = __importDefault(require("node:fs"));
|
|
|
28
28
|
const node_os_1 = __importDefault(require("node:os"));
|
|
29
29
|
const node_path_1 = __importDefault(require("node:path"));
|
|
30
30
|
const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
|
|
31
|
+
// #4717: runtime-identity fill — env rung + per-install marker rung.
|
|
32
|
+
const runtime_slash_cjs_1 = require("./runtime-slash.cjs");
|
|
33
|
+
const runtime_name_policy_cjs_1 = require("./runtime-name-policy.cjs");
|
|
31
34
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
32
35
|
const planningWorkspace = require("./planning-workspace.cjs");
|
|
33
36
|
const { planningDir, planningRoot } = planningWorkspace;
|
|
@@ -150,8 +153,21 @@ const CONFIG_DEFAULTS = {
|
|
|
150
153
|
research_before_questions: _getNestedConfigDefault('workflow', 'research_before_questions'), // #3894
|
|
151
154
|
smart_zone_tokens: _getNestedConfigDefault('workflow', 'smart_zone_tokens'),
|
|
152
155
|
inline_plan_threshold: _getNestedConfigDefault('workflow', 'inline_plan_threshold'), // #3801
|
|
156
|
+
planner_stall_detection_enabled: _getNestedConfigDefault('planner', 'stall_detection_enabled'),
|
|
153
157
|
max_prompt_tokens: _getNestedConfigDefault('review', 'max_prompt_tokens'),
|
|
154
158
|
};
|
|
159
|
+
/**
|
|
160
|
+
* Resolve the planner watchdog policy from hand-edited configuration.
|
|
161
|
+
* Only a real JSON boolean may override the default; strings/numbers/null
|
|
162
|
+
* fail safe to the manifest-owned default-on behavior (#4570).
|
|
163
|
+
*/
|
|
164
|
+
function resolvePlannerStallDetectionEnabled(value) {
|
|
165
|
+
if (typeof value === 'boolean')
|
|
166
|
+
return value;
|
|
167
|
+
// A missing or skewed manifest must never convert an absent override into
|
|
168
|
+
// permission to disable the watchdog. The documented contract is default-on.
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
155
171
|
/**
|
|
156
172
|
* Deep-merge two plain config objects. `overlay` wins on key conflict.
|
|
157
173
|
* Explicit `null` in overlay overrides base (null means "unset this key").
|
|
@@ -601,7 +617,7 @@ function _warnUnusableConfig(fault) {
|
|
|
601
617
|
* cannot dirty the working tree; the ~30 callers that omit it keep persisting, so
|
|
602
618
|
* a legacy config is still migrated exactly once by ordinary use.
|
|
603
619
|
*/
|
|
604
|
-
function
|
|
620
|
+
function loadConfigResolvedInternal(cwd, options = {}) {
|
|
605
621
|
// Opt-OUT, not opt-in: omitting the option must preserve the historical
|
|
606
622
|
// write-back for every existing caller.
|
|
607
623
|
const persist = options['persist'] !== false;
|
|
@@ -614,7 +630,7 @@ function loadConfigResolved(cwd, options = {}) {
|
|
|
614
630
|
: (options['workstreamContext'] && Object.prototype.hasOwnProperty.call(options['workstreamContext'], 'ws'))
|
|
615
631
|
? options['workstreamContext']['ws']
|
|
616
632
|
: (process.env['GSD_WORKSTREAM'] || null);
|
|
617
|
-
const ws = typeof activeWorkstream === 'string' ? activeWorkstream
|
|
633
|
+
const ws = typeof activeWorkstream === 'string' ? activeWorkstream.trim() || null : null;
|
|
618
634
|
// wsRequested: true when caller explicitly requested a non-empty workstream.
|
|
619
635
|
// Used for source labeling (Fix 4) and early absent-dir intercept (Fix 2).
|
|
620
636
|
const wsRequested = ws != null && ws !== '';
|
|
@@ -858,6 +874,7 @@ function loadConfigResolved(cwd, options = {}) {
|
|
|
858
874
|
phase_naming: get('phase_naming') ?? defaults.phase_naming,
|
|
859
875
|
project_code: get('project_code') ?? defaults.project_code,
|
|
860
876
|
subagent_timeout: get('subagent_timeout', { section: 'workflow', field: 'subagent_timeout' }) ?? defaults.subagent_timeout,
|
|
877
|
+
planner_stall_detection_enabled: resolvePlannerStallDetectionEnabled(getNested('planner', 'stall_detection_enabled')),
|
|
861
878
|
model_overrides: (parsed['model_overrides']) || null,
|
|
862
879
|
agent_tools: (parsed['agent_tools']) || null,
|
|
863
880
|
models: (parsed['models']) || null,
|
|
@@ -959,7 +976,7 @@ function loadConfigResolved(cwd, options = {}) {
|
|
|
959
976
|
// `workstream: null` still wins the `hasOwnProperty` check at the top of this
|
|
960
977
|
// function, so spreading cannot let `workstreamContext` reintroduce a workstream.
|
|
961
978
|
if (wsRequested && rootParsed) {
|
|
962
|
-
const fb =
|
|
979
|
+
const fb = loadConfigResolvedInternal(cwd, { ...options, workstream: null });
|
|
963
980
|
return fallback({ config: fb.config, source: 'root', degraded: true });
|
|
964
981
|
}
|
|
965
982
|
// Branch B, C, D, E
|
|
@@ -967,7 +984,7 @@ function loadConfigResolved(cwd, options = {}) {
|
|
|
967
984
|
if (rootParsed) {
|
|
968
985
|
// Branch B: workstream requested but ws config.json absent; root config present.
|
|
969
986
|
// (Only reached when wsRequested is false — e.g. ws='' with .planning/workstreams//config.json)
|
|
970
|
-
const fb =
|
|
987
|
+
const fb = loadConfigResolvedInternal(cwd, { ...options, workstream: null });
|
|
971
988
|
return fallback({ config: fb.config, source: 'root', degraded: true });
|
|
972
989
|
}
|
|
973
990
|
// Branch C: .planning/ exists but no config.json and no root config — federated/builtin defaults
|
|
@@ -1016,6 +1033,7 @@ function loadConfigResolved(cwd, options = {}) {
|
|
|
1016
1033
|
resolve_model_ids: (globalDefaults['resolve_model_ids']) ?? defaults.resolve_model_ids,
|
|
1017
1034
|
context_window: (globalDefaults['context_window']) ?? defaults.context_window,
|
|
1018
1035
|
subagent_timeout: (globalDefaults['subagent_timeout']) ?? defaults.subagent_timeout,
|
|
1036
|
+
planner_stall_detection_enabled: resolvePlannerStallDetectionEnabled(globalDefaults['planner']?.['stall_detection_enabled']),
|
|
1019
1037
|
model_overrides: (globalDefaults['model_overrides']) || null,
|
|
1020
1038
|
models: (globalDefaults['models']) || null,
|
|
1021
1039
|
granularity: (globalDefaults['granularity']) !== undefined ? globalDefaults['granularity'] : null,
|
|
@@ -1054,6 +1072,48 @@ function loadConfigResolved(cwd, options = {}) {
|
|
|
1054
1072
|
}
|
|
1055
1073
|
}
|
|
1056
1074
|
}
|
|
1075
|
+
/**
|
|
1076
|
+
* #4717 — fill an empty `runtime` from the environment, then the per-install
|
|
1077
|
+
* marker. writeNonClaudeDefaults stamps `runtime` into the SHARED
|
|
1078
|
+
* ~/.gsd/defaults.json with whichever non-Claude runtime installed first, so
|
|
1079
|
+
* direct readers of config.runtime saw another runtime's identity (or
|
|
1080
|
+
* nothing) on a multi-runtime machine. Copy-on-write: the builtin-defaults
|
|
1081
|
+
* branch returns a shared object, so never assign into it. An explicit
|
|
1082
|
+
* config.runtime is never overridden.
|
|
1083
|
+
*/
|
|
1084
|
+
function fillRuntimeIdentity(resolved) {
|
|
1085
|
+
const cfg = resolved?.config;
|
|
1086
|
+
if (!cfg)
|
|
1087
|
+
return resolved;
|
|
1088
|
+
const runtime = (0, runtime_name_policy_cjs_1.resolveRuntimeNameFromCandidates)(process.env['GSD_RUNTIME'], (0, runtime_slash_cjs_1.readInstallRuntimeMarker)());
|
|
1089
|
+
// Only a runtime the name policy can canonicalize is an identity. Unknown
|
|
1090
|
+
// tokens pass THROUGH resolveRuntimeNameFromCandidates (future-runtime
|
|
1091
|
+
// tolerance) and must not be materialized into config.runtime, where ~30
|
|
1092
|
+
// consumers would read them — fail safe to no identity (#4717 review).
|
|
1093
|
+
const canonicalRuntime = runtime ? (0, runtime_name_policy_cjs_1.canonicalizeRuntimeName)(runtime) : null;
|
|
1094
|
+
if (!canonicalRuntime)
|
|
1095
|
+
return resolved;
|
|
1096
|
+
// Rung 1 — empty runtime: materialize THIS install's identity (env, then
|
|
1097
|
+
// the per-install marker). An explicit runtime is never overridden.
|
|
1098
|
+
if (!cfg['runtime']) {
|
|
1099
|
+
return { ...resolved, config: { ...cfg, runtime: canonicalRuntime } };
|
|
1100
|
+
}
|
|
1101
|
+
// Rung 2 (#4717 stamped-defaults leg): the global-defaults branch forwards
|
|
1102
|
+
// the SHARED ~/.gsd/defaults.json's runtime verbatim — whichever non-Claude
|
|
1103
|
+
// runtime installed FIRST stamped that machine-wide file, and every other
|
|
1104
|
+
// runtime's resolution inherited its identity (the issue's second failure
|
|
1105
|
+
// shape). When THIS install carries its own identity (GSD_RUNTIME or the
|
|
1106
|
+
// marker), the stamp — not the operator — is speaking: correct it. Project
|
|
1107
|
+
// and workstream configs are explicit operator intent and are never touched;
|
|
1108
|
+
// with no install identity of its own the stamped value stays (status quo).
|
|
1109
|
+
if (resolved.source === 'global-defaults') {
|
|
1110
|
+
return { ...resolved, config: { ...cfg, runtime: canonicalRuntime } };
|
|
1111
|
+
}
|
|
1112
|
+
return resolved;
|
|
1113
|
+
}
|
|
1114
|
+
function loadConfigResolved(cwd, options = {}) {
|
|
1115
|
+
return fillRuntimeIdentity(loadConfigResolvedInternal(cwd, options));
|
|
1116
|
+
}
|
|
1057
1117
|
/**
|
|
1058
1118
|
* loadConfig — backwards-compatible config loading, now a thin wrapper over loadConfigResolved.
|
|
1059
1119
|
* Returns the config object only; for provenance metadata use loadConfigResolved.
|
|
@@ -1072,6 +1132,7 @@ module.exports = {
|
|
|
1072
1132
|
_getNestedConfigDefault,
|
|
1073
1133
|
_getConfigValue,
|
|
1074
1134
|
_getConfigNested,
|
|
1135
|
+
resolvePlannerStallDetectionEnabled,
|
|
1075
1136
|
_deepMergeConfig,
|
|
1076
1137
|
_warnedUnknownConfigKeys,
|
|
1077
1138
|
_warnedShadowedGlobalKeys,
|
|
@@ -20,11 +20,11 @@ const cliExitMod = require("./cli-exit.cjs");
|
|
|
20
20
|
const { ExitError } = cliExitMod;
|
|
21
21
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
22
22
|
const configLoader = require("./config-loader.cjs");
|
|
23
|
-
const { CONFIG_DEFAULTS } = configLoader;
|
|
23
|
+
const { CONFIG_DEFAULTS, resolvePlannerStallDetectionEnabled } = configLoader;
|
|
24
24
|
const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
|
|
25
25
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
26
26
|
const planningWorkspace = require("./planning-workspace.cjs");
|
|
27
|
-
const { planningDir, planningRoot, withPlanningLock } = planningWorkspace;
|
|
27
|
+
const { planningDir, planningRoot, resolveEnvWorkstream, withPlanningLock } = planningWorkspace;
|
|
28
28
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
29
29
|
const modelProfiles = require("./model-profiles.cjs");
|
|
30
30
|
const { VALID_PROFILES, getAgentToModelMapForProfile, formatAgentToModelMapAsTable } = modelProfiles;
|
|
@@ -66,6 +66,14 @@ const SHIP_PR_BODY_TEMPLATE_TOKENS = new Set([
|
|
|
66
66
|
'padded_phase',
|
|
67
67
|
]);
|
|
68
68
|
const SHIP_PR_BODY_SOURCE_RE = /^(ROADMAP|PLAN|SUMMARY|VERIFICATION|STATE|REQUIREMENTS|CONTEXT)\.md\s+##\s+[^\r\n#][^\r\n]*$/;
|
|
69
|
+
// ADR-612 PR-5: configuration accepts every convention the runtime can read.
|
|
70
|
+
// Keep this distinct from roadmap-upgrade's supported target set: sequential
|
|
71
|
+
// is valid project configuration but is not a migration destination.
|
|
72
|
+
const VALID_PHASE_ID_CONVENTIONS = Object.freeze([
|
|
73
|
+
'sequential',
|
|
74
|
+
'milestone-prefixed',
|
|
75
|
+
'bracket',
|
|
76
|
+
]);
|
|
69
77
|
/**
|
|
70
78
|
* Schema-level defaults for well-known config keys.
|
|
71
79
|
* When a key is absent from config.json and no --default flag was supplied,
|
|
@@ -75,6 +83,7 @@ const SCHEMA_DEFAULTS = {
|
|
|
75
83
|
'context_window': 200000,
|
|
76
84
|
'executor.stall_detect_interval_minutes': 5,
|
|
77
85
|
'executor.stall_threshold_minutes': 10,
|
|
86
|
+
'planner.stall_detection_enabled': CONFIG_DEFAULTS.planner_stall_detection_enabled,
|
|
78
87
|
'planner.stall_detect_interval_minutes': 5,
|
|
79
88
|
'planner.stall_threshold_minutes': 10,
|
|
80
89
|
'git.create_tag': true,
|
|
@@ -119,6 +128,19 @@ const SCHEMA_DEFAULTS = {
|
|
|
119
128
|
// WARNING_THRESHOLD/CRITICAL_THRESHOLD so the copies cannot drift.
|
|
120
129
|
'hooks.context_warning_threshold': 35,
|
|
121
130
|
'hooks.context_critical_threshold': 25,
|
|
131
|
+
// #4974: gates.* confirmation toggles — an absent key must resolve to the
|
|
132
|
+
// documented default (true) rather than "Key not found", matching
|
|
133
|
+
// config-defaults.manifest.json's `gates` block. Literal here (like
|
|
134
|
+
// git.create_tag above) rather than derived from config-loader.cjs's flat
|
|
135
|
+
// CONFIG_DEFAULTS: that flat projection is enumerated 1:1 against
|
|
136
|
+
// gsd-core/references/planning-config.md by
|
|
137
|
+
// tests/config-field-docs.test.cjs, and these 3 keys are internal workflow
|
|
138
|
+
// wiring, not part of that public flat-key surface. Only the 3 keys
|
|
139
|
+
// actually read by workflow conditions are registered — see
|
|
140
|
+
// gsd-core/bin/shared/config-schema.manifest.json.
|
|
141
|
+
'gates.execute_next_plan': true,
|
|
142
|
+
'gates.confirm_transition': true,
|
|
143
|
+
'gates.confirm_milestone_scope': true,
|
|
122
144
|
};
|
|
123
145
|
/**
|
|
124
146
|
* Resolve a schema-level default for an absent key (#2256). Checks the legacy
|
|
@@ -152,12 +174,15 @@ function resolveSchemaDefault(cwd, kp) {
|
|
|
152
174
|
* Centralizing emission here means masking can't be missed at a call site.
|
|
153
175
|
*/
|
|
154
176
|
function emitResolvedDefault(kp, value, raw) {
|
|
177
|
+
const resolvedValue = kp === 'planner.stall_detection_enabled'
|
|
178
|
+
? resolvePlannerStallDetectionEnabled(value)
|
|
179
|
+
: value;
|
|
155
180
|
if ((0, secrets_cjs_1.isSecretKey)(kp)) {
|
|
156
|
-
const masked = (0, secrets_cjs_1.maskSecret)(
|
|
181
|
+
const masked = (0, secrets_cjs_1.maskSecret)(resolvedValue);
|
|
157
182
|
output(masked, raw, masked);
|
|
158
183
|
return;
|
|
159
184
|
}
|
|
160
|
-
output(
|
|
185
|
+
output(resolvedValue, raw, String(resolvedValue));
|
|
161
186
|
}
|
|
162
187
|
// ─── Validation helpers ───────────────────────────────────────────────────────
|
|
163
188
|
function validateKnownConfigKeyPath(keyPath) {
|
|
@@ -252,7 +277,8 @@ function validateShipPrBodySections(value) {
|
|
|
252
277
|
*
|
|
253
278
|
* Merges (increasing priority):
|
|
254
279
|
* 1. Hardcoded defaults — every key that loadConfig() resolves, plus mode/granularity
|
|
255
|
-
* 2. User-level defaults from
|
|
280
|
+
* 2. User-level defaults from $GSD_HOME/.gsd/defaults.json (if present;
|
|
281
|
+
* GSD_HOME defaults to the home directory, as in the config loader)
|
|
256
282
|
* 3. userChoices — the settings the user explicitly selected during /gsd:new-project
|
|
257
283
|
*
|
|
258
284
|
* Uses the canonical `git` namespace for branching keys (consistent with VALID_CONFIG_KEYS
|
|
@@ -263,24 +289,27 @@ function validateShipPrBodySections(value) {
|
|
|
263
289
|
*/
|
|
264
290
|
function buildNewProjectConfig(userChoices) {
|
|
265
291
|
const choices = userChoices || {};
|
|
266
|
-
|
|
292
|
+
// #4976: the GSD-owned store resolves exactly as the config loader resolves
|
|
293
|
+
// it (`GSD_HOME || homedir()`), so the defaults.json seeding this project is
|
|
294
|
+
// the one the loader and its #3532 shadow warning read in the same run.
|
|
295
|
+
const gsdHome = process.env['GSD_HOME'] || node_os_1.default.homedir();
|
|
267
296
|
// Detect API key availability
|
|
268
|
-
const braveKeyFile = node_path_1.default.join(
|
|
297
|
+
const braveKeyFile = node_path_1.default.join(gsdHome, '.gsd', 'brave_api_key');
|
|
269
298
|
const hasBraveSearch = !!(process.env['BRAVE_API_KEY'] || node_fs_1.default.existsSync(braveKeyFile));
|
|
270
|
-
const firecrawlKeyFile = node_path_1.default.join(
|
|
299
|
+
const firecrawlKeyFile = node_path_1.default.join(gsdHome, '.gsd', 'firecrawl_api_key');
|
|
271
300
|
const hasFirecrawl = !!(process.env['FIRECRAWL_API_KEY'] || node_fs_1.default.existsSync(firecrawlKeyFile));
|
|
272
|
-
const exaKeyFile = node_path_1.default.join(
|
|
301
|
+
const exaKeyFile = node_path_1.default.join(gsdHome, '.gsd', 'exa_api_key');
|
|
273
302
|
const hasExaSearch = !!(process.env['EXA_API_KEY'] || node_fs_1.default.existsSync(exaKeyFile));
|
|
274
|
-
const tavilyKeyFile = node_path_1.default.join(
|
|
303
|
+
const tavilyKeyFile = node_path_1.default.join(gsdHome, '.gsd', 'tavily_api_key');
|
|
275
304
|
const hasTavilySearch = !!(process.env['TAVILY_API_KEY'] || node_fs_1.default.existsSync(tavilyKeyFile));
|
|
276
|
-
const refKeyFile = node_path_1.default.join(
|
|
305
|
+
const refKeyFile = node_path_1.default.join(gsdHome, '.gsd', 'ref_api_key');
|
|
277
306
|
const hasRefSearch = !!(process.env['REF_API_KEY'] || node_fs_1.default.existsSync(refKeyFile));
|
|
278
|
-
const perplexityKeyFile = node_path_1.default.join(
|
|
307
|
+
const perplexityKeyFile = node_path_1.default.join(gsdHome, '.gsd', 'perplexity_api_key');
|
|
279
308
|
const hasPerplexity = !!(process.env['PERPLEXITY_API_KEY'] || node_fs_1.default.existsSync(perplexityKeyFile));
|
|
280
|
-
const jinaKeyFile = node_path_1.default.join(
|
|
309
|
+
const jinaKeyFile = node_path_1.default.join(gsdHome, '.gsd', 'jina_api_key');
|
|
281
310
|
const hasJina = !!(process.env['JINA_API_KEY'] || node_fs_1.default.existsSync(jinaKeyFile));
|
|
282
|
-
// Load user-level defaults from
|
|
283
|
-
const globalDefaultsPath = node_path_1.default.join(
|
|
311
|
+
// Load user-level defaults from $GSD_HOME/.gsd/defaults.json if available
|
|
312
|
+
const globalDefaultsPath = node_path_1.default.join(gsdHome, '.gsd', 'defaults.json');
|
|
284
313
|
let userDefaults = {};
|
|
285
314
|
try {
|
|
286
315
|
if (node_fs_1.default.existsSync(globalDefaultsPath)) {
|
|
@@ -422,7 +451,7 @@ function buildNewProjectConfig(userChoices) {
|
|
|
422
451
|
*
|
|
423
452
|
* Accepts user-chosen settings as a JSON string (the keys the user explicitly
|
|
424
453
|
* configured during /gsd:new-project). All remaining keys are filled from
|
|
425
|
-
* hardcoded defaults and optional
|
|
454
|
+
* hardcoded defaults and optional $GSD_HOME/.gsd/defaults.json.
|
|
426
455
|
*
|
|
427
456
|
* Idempotent: if config.json already exists, returns { created: false }.
|
|
428
457
|
*/
|
|
@@ -542,7 +571,7 @@ function _setNestedValue(config, keyPath, parsedValue) {
|
|
|
542
571
|
}
|
|
543
572
|
/**
|
|
544
573
|
* Deletes a value from the config object, allowing nested values via dot
|
|
545
|
-
* notation (e.g., "review.models.
|
|
574
|
+
* notation (e.g., "review.models.codex"). Mirrors `_setNestedValue`'s
|
|
546
575
|
* prototype-pollution guard on every path segment (including intermediates).
|
|
547
576
|
*
|
|
548
577
|
* Unlike `_setNestedValue`, this NEVER creates missing intermediate objects —
|
|
@@ -806,6 +835,16 @@ function cmdConfigSet(cwd, keyPath, value, raw, options = {}) {
|
|
|
806
835
|
const VALID_CONTEXT_VALUES = ['dev', 'research', 'review'];
|
|
807
836
|
if (kp === 'context')
|
|
808
837
|
assertEnumValue(parsedValue, val, VALID_CONTEXT_VALUES, 'context value');
|
|
838
|
+
// #4974: `mode` was never enum-validated — `config-set mode custom` (or any
|
|
839
|
+
// other string) silently succeeded, even though only "interactive" and
|
|
840
|
+
// "yolo" are documented/read values (gsd-core/references/planning-config.md,
|
|
841
|
+
// docs/CONFIGURATION.md, pinned by tests/config-field-docs.test.cjs).
|
|
842
|
+
const VALID_MODE_VALUES = ['interactive', 'yolo'];
|
|
843
|
+
if (kp === 'mode')
|
|
844
|
+
assertEnumValue(parsedValue, val, VALID_MODE_VALUES, 'mode');
|
|
845
|
+
if (kp === 'phase_id_convention') {
|
|
846
|
+
assertEnumValue(parsedValue, val, VALID_PHASE_ID_CONVENTIONS, 'phase_id_convention');
|
|
847
|
+
}
|
|
809
848
|
// Codebase drift detector (#2003)
|
|
810
849
|
const VALID_DRIFT_ACTIONS = ['warn', 'auto-remap'];
|
|
811
850
|
if (kp === 'workflow.drift_action')
|
|
@@ -853,6 +892,20 @@ function cmdConfigSet(cwd, keyPath, value, raw, options = {}) {
|
|
|
853
892
|
error(`Invalid workflow.agent_hint_routing '${val}'. Must be a boolean (true or false).`);
|
|
854
893
|
}
|
|
855
894
|
}
|
|
895
|
+
// Planner watchdog opt-out (#4570) — only a real boolean may change the
|
|
896
|
+
// default-on policy. In particular, string "false" must not disable it.
|
|
897
|
+
if (kp === 'planner.stall_detection_enabled') {
|
|
898
|
+
if (typeof parsedValue !== 'boolean') {
|
|
899
|
+
error(`Invalid planner.stall_detection_enabled '${val}'. Must be a boolean (true or false).`);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
// Dispatch audit-trail opt-in (#4975) — boolean only. The live seams honour
|
|
903
|
+
// only a real `true`, so any other stored value would be silently ignored.
|
|
904
|
+
if (kp === 'audit.enabled') {
|
|
905
|
+
if (typeof parsedValue !== 'boolean') {
|
|
906
|
+
error(`Invalid audit.enabled '${val}'. Must be a boolean (true or false).`);
|
|
907
|
+
}
|
|
908
|
+
}
|
|
856
909
|
// #3086 — git.create_tag: boolean only
|
|
857
910
|
if (kp === 'git.create_tag') {
|
|
858
911
|
if (typeof parsedValue !== 'boolean') {
|
|
@@ -1161,6 +1214,9 @@ function cmdConfigGet(cwd, keyPath, raw, defaultValue) {
|
|
|
1161
1214
|
}
|
|
1162
1215
|
error(`Key not found: ${kp}`, ERROR_REASON.CONFIG_KEY_NOT_FOUND);
|
|
1163
1216
|
}
|
|
1217
|
+
if (kp === 'planner.stall_detection_enabled') {
|
|
1218
|
+
current = resolvePlannerStallDetectionEnabled(current);
|
|
1219
|
+
}
|
|
1164
1220
|
// Never echo plaintext for sensitive keys via config-get. Plaintext lives
|
|
1165
1221
|
// in config.json on disk; the CLI surface always shows the masked form.
|
|
1166
1222
|
if ((0, secrets_cjs_1.isSecretKey)(kp)) {
|
|
@@ -1190,7 +1246,7 @@ function resolveFromRootConfig(cwd, kp) {
|
|
|
1190
1246
|
// diverges from planningRoot without a workstream and loadConfigResolved does NOT
|
|
1191
1247
|
// inherit root — matching the runtime's own `if (ws)` gate keeps the two surfaces
|
|
1192
1248
|
// from diverging on the project-scoped (non-workstream) case.
|
|
1193
|
-
if (!
|
|
1249
|
+
if (!resolveEnvWorkstream())
|
|
1194
1250
|
return { found: false, value: undefined };
|
|
1195
1251
|
const root = planningRoot(cwd);
|
|
1196
1252
|
const rootConfigPath = node_path_1.default.join(root, 'config.json');
|
|
@@ -1297,7 +1353,7 @@ function cmdConfigPath(cwd, _raw, workstreamContext = null) {
|
|
|
1297
1353
|
* (caller uses `await` which is safe on a sync return value).
|
|
1298
1354
|
*/
|
|
1299
1355
|
function cmdMigrateConfig(cwd, raw) {
|
|
1300
|
-
const ws =
|
|
1356
|
+
const ws = resolveEnvWorkstream();
|
|
1301
1357
|
// #3749: resolve the migration target through the project-aware resolver so
|
|
1302
1358
|
// GSD_PROJECT scopes the write; migrateOnDisk itself cannot (see its
|
|
1303
1359
|
// configPathOverride note).
|
|
@@ -1345,6 +1401,7 @@ function cmdMigrateConfig(cwd, raw) {
|
|
|
1345
1401
|
}
|
|
1346
1402
|
module.exports = {
|
|
1347
1403
|
VALID_CONFIG_KEYS,
|
|
1404
|
+
VALID_PHASE_ID_CONVENTIONS,
|
|
1348
1405
|
cmdConfigEnsureSection,
|
|
1349
1406
|
cmdConfigSet,
|
|
1350
1407
|
cmdConfigGet,
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* - node:fs / node:path (stdlib)
|
|
16
16
|
* - ./phase-id.cjs (comparePhaseNum, used by readSubdirectories)
|
|
17
17
|
* - ./planning-workspace.cjs (findContextMdIn, used by getPhaseFileStats)
|
|
18
|
+
* - ./frontmatter-fence.cjs (locateFrontmatterFence, used by extractOneLinerFromBody)
|
|
18
19
|
*
|
|
19
20
|
* #3883 (ADR-3473 §8.3): two of this module's cyclic partners require
|
|
20
21
|
* generateSlugInternal, the canonical slug formula:
|
|
@@ -37,6 +38,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
37
38
|
};
|
|
38
39
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
39
40
|
const node_path_1 = __importDefault(require("node:path"));
|
|
41
|
+
// frontmatter-fence.cjs is a leaf module (no imports), so this adds no cycle.
|
|
42
|
+
const frontmatter_fence_cjs_1 = require("./frontmatter-fence.cjs");
|
|
40
43
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
41
44
|
const phaseIdModule = require("./phase-id.cjs");
|
|
42
45
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
@@ -139,7 +142,9 @@ function extractOneLinerFromBody(content) {
|
|
|
139
142
|
if (!content)
|
|
140
143
|
return null;
|
|
141
144
|
const normalized = content.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
142
|
-
|
|
145
|
+
// The body starts after the block the one fence owner finds, and the blank lines after it.
|
|
146
|
+
const fence = (0, frontmatter_fence_cjs_1.locateFrontmatterFence)(normalized);
|
|
147
|
+
const body = fence?.closed ? normalized.slice(fence.closingFenceEnd).replace(/^\n+/, '') : normalized;
|
|
143
148
|
// #3170: anchor to a summary-shaped heading (Summary / Overview /
|
|
144
149
|
// Accomplishments) so an incidental first heading (a rule list, task
|
|
145
150
|
// breakdown, deviation note) does not contribute its first bold run as the
|
|
@@ -34,6 +34,7 @@ const { output, error } = io;
|
|
|
34
34
|
const coreUtils = require("./core-utils.cjs");
|
|
35
35
|
const { toPosixPath } = coreUtils;
|
|
36
36
|
const security_cjs_1 = require("./security.cjs");
|
|
37
|
+
const frontmatter_fence_cjs_1 = require("./frontmatter-fence.cjs");
|
|
37
38
|
// ─── Frozen typed-IR surface ────────────────────────────────────────────────
|
|
38
39
|
const MODE = Object.freeze({
|
|
39
40
|
COVERAGE: 'coverage',
|
|
@@ -186,15 +187,10 @@ function setKey(obj, key, value) {
|
|
|
186
187
|
obj[key] = value;
|
|
187
188
|
}
|
|
188
189
|
// ─── Frontmatter region helpers ──────────────────────────────────────────────
|
|
190
|
+
/** The closed frontmatter block's YAML text, as the one fence owner finds it, or null. */
|
|
189
191
|
function getFrontmatterYaml(content) {
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
return null;
|
|
193
|
-
const closingLineStart = content.indexOf('\n---', headerEnd);
|
|
194
|
-
if (closingLineStart === -1)
|
|
195
|
-
return null;
|
|
196
|
-
const yamlEnd = content[closingLineStart - 1] === '\r' ? closingLineStart - 1 : closingLineStart;
|
|
197
|
-
return content.slice(headerEnd, yamlEnd);
|
|
192
|
+
const fence = (0, frontmatter_fence_cjs_1.locateFrontmatterFence)(content);
|
|
193
|
+
return fence?.closed ? content.slice(fence.openEnd, fence.bodyEnd) : null;
|
|
198
194
|
}
|
|
199
195
|
/**
|
|
200
196
|
* Locate and parse the top-level `coverage:` block from a SUMMARY document.
|