@opengsd/gsd-core 1.11.0 → 1.12.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/agents/gsd-code-fixer.md +1 -1
- package/agents/gsd-debug-session-manager.md +1 -1
- package/agents/gsd-debugger.md +1 -1
- package/agents/gsd-dom-verifier.md +169 -0
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-executor.md +17 -9
- package/agents/gsd-framework-selector.md +1 -3
- package/agents/gsd-intel-updater.md +1 -1
- package/agents/gsd-mempalace-curator.md +0 -1
- package/agents/gsd-pattern-mapper.md +11 -0
- package/agents/gsd-phase-researcher.md +3 -1
- package/agents/gsd-plan-checker.md +15 -55
- package/agents/gsd-planner.md +6 -4
- package/agents/gsd-project-researcher.md +1 -1
- package/agents/gsd-research-synthesizer.md +2 -2
- package/agents/gsd-roadmapper.md +15 -11
- package/agents/gsd-ui-checker.md +63 -4
- package/agents/gsd-ui-researcher.md +41 -3
- package/agents/gsd-verifier.md +1 -1
- package/bin/install.js +609 -134
- package/commands/gsd/discuss-phase.md +1 -1
- package/commands/gsd/import.md +1 -1
- package/commands/gsd/quick.md +8 -4
- package/gsd-core/bin/gsd-tools.cjs +567 -51
- package/gsd-core/bin/lib/active-workstream-store.cjs +8 -0
- package/gsd-core/bin/lib/adr-parser.cjs +13 -7
- package/gsd-core/bin/lib/agent-install-check.cjs +162 -0
- package/gsd-core/bin/lib/api-coverage.cjs +30 -9
- package/gsd-core/bin/lib/artifacts.cjs +2 -0
- package/gsd-core/bin/lib/assumption-delta.cjs +30 -11
- package/gsd-core/bin/lib/audit.cjs +163 -41
- package/gsd-core/bin/lib/broken-windows.cjs +306 -28
- package/gsd-core/bin/lib/capability-lock.cjs +10 -4
- package/gsd-core/bin/lib/capability-registry.cjs +336 -95
- package/gsd-core/bin/lib/capability-state.cjs +18 -3
- package/gsd-core/bin/lib/capability-validator.cjs +205 -18
- package/gsd-core/bin/lib/check-command-router.cjs +145 -5
- package/gsd-core/bin/lib/cli-exit.cjs +496 -10
- package/gsd-core/bin/lib/code-review-depth.cjs +288 -0
- package/gsd-core/bin/lib/codex-agent-toml.cjs +410 -4
- package/gsd-core/bin/lib/command-arg-projection.cjs +144 -14
- package/gsd-core/bin/lib/command-routing-hub.cjs +31 -2
- package/gsd-core/bin/lib/commands.cjs +543 -44
- package/gsd-core/bin/lib/complexity-trigger.cjs +26 -6
- package/gsd-core/bin/lib/config-loader.cjs +118 -29
- package/gsd-core/bin/lib/config.cjs +92 -2
- package/gsd-core/bin/lib/configuration.cjs +129 -37
- package/gsd-core/bin/lib/core-utils.cjs +84 -7
- package/gsd-core/bin/lib/edge-probe.cjs +9 -1
- package/gsd-core/bin/lib/estimate-cli.cjs +55 -11
- package/gsd-core/bin/lib/exit-code-registry.cjs +98 -0
- package/gsd-core/bin/lib/frontmatter.cjs +840 -305
- package/gsd-core/bin/lib/gap-checker.cjs +27 -3
- package/gsd-core/bin/lib/git-base-branch.cjs +174 -39
- package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +7 -3
- package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +6 -3
- package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +22 -8
- package/gsd-core/bin/lib/health-diagnostic.cjs +23 -3
- package/gsd-core/bin/lib/host-integration.cjs +39 -6
- package/gsd-core/bin/lib/init-command-router.cjs +118 -21
- package/gsd-core/bin/lib/init.cjs +120 -41
- package/gsd-core/bin/lib/install-engine.cjs +68 -3
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +33 -1
- package/gsd-core/bin/lib/install-profiles.cjs +78 -4
- package/gsd-core/bin/lib/installer-migration-report.cjs +3 -0
- package/gsd-core/bin/lib/installer-migrations/010-antigravity-retire-confighome-artifacts.cjs +169 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +10 -7
- package/gsd-core/bin/lib/intel.cjs +101 -26
- package/gsd-core/bin/lib/io.cjs +160 -15
- package/gsd-core/bin/lib/learnings.cjs +85 -14
- package/gsd-core/bin/lib/legacy-cleanup.cjs +8 -2
- package/gsd-core/bin/lib/markdown-table.cjs +52 -4
- package/gsd-core/bin/lib/milestone.cjs +90 -5
- package/gsd-core/bin/lib/model-catalog.cjs +177 -19
- package/gsd-core/bin/lib/model-resolver.cjs +10 -28
- package/gsd-core/bin/lib/onboard-projection.cjs +5 -1
- package/gsd-core/bin/lib/phase-estimation.cjs +17 -8
- package/gsd-core/bin/lib/phase-id.cjs +70 -4
- package/gsd-core/bin/lib/phase-lifecycle.cjs +24 -16
- package/gsd-core/bin/lib/phase-locator.cjs +138 -17
- package/gsd-core/bin/lib/phase.cjs +405 -84
- package/gsd-core/bin/lib/plan-document.cjs +263 -0
- package/gsd-core/bin/lib/plan-scan.cjs +13 -2
- package/gsd-core/bin/lib/planning-command-router.cjs +61 -0
- package/gsd-core/bin/lib/planning-inspect.cjs +1168 -0
- package/gsd-core/bin/lib/planning-snapshot.cjs +18 -14
- package/gsd-core/bin/lib/planning-workspace.cjs +56 -0
- package/gsd-core/bin/lib/probe-core.cjs +4 -1
- package/gsd-core/bin/lib/profile-pipeline-command-router.cjs +50 -7
- package/gsd-core/bin/lib/profile-pipeline.cjs +6 -3
- package/gsd-core/bin/lib/real-home-guard.cjs +419 -0
- package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +71 -45
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +9 -9
- package/gsd-core/bin/lib/roadmap-command-router.cjs +45 -31
- package/gsd-core/bin/lib/roadmap-parser.cjs +79 -16
- package/gsd-core/bin/lib/roadmap.cjs +74 -19
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +96 -8
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +34 -1
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +287 -55
- package/gsd-core/bin/lib/runtime-identity.cjs +234 -0
- package/gsd-core/bin/lib/runtime-slash.cjs +72 -2
- package/gsd-core/bin/lib/shell-command-projection.cjs +71 -8
- package/gsd-core/bin/lib/smart-entry.cjs +12 -22
- package/gsd-core/bin/lib/spec-section.cjs +12 -7
- package/gsd-core/bin/lib/state-command-router.cjs +47 -18
- package/gsd-core/bin/lib/state-contract.cjs +359 -0
- package/gsd-core/bin/lib/state-document.cjs +186 -0
- package/gsd-core/bin/lib/state-md-schema.cjs +221 -0
- package/gsd-core/bin/lib/state-transition.cjs +517 -101
- package/gsd-core/bin/lib/state.cjs +946 -163
- package/gsd-core/bin/lib/surface.cjs +10 -2
- package/gsd-core/bin/lib/task-command-router.cjs +111 -1
- package/gsd-core/bin/lib/task-content-resolution.cjs +368 -0
- package/gsd-core/bin/lib/teams-status.cjs +4 -1
- package/gsd-core/bin/lib/uat-predicate.cjs +58 -20
- package/gsd-core/bin/lib/uat.cjs +1376 -125
- package/gsd-core/bin/lib/ui-consideration-probe.cjs +9 -1
- package/gsd-core/bin/lib/ui-safety-gate.cjs +37 -7
- package/gsd-core/bin/lib/unusable-input.cjs +13 -0
- package/gsd-core/bin/lib/validate-command-router.cjs +2 -2
- package/gsd-core/bin/lib/vendor/README.md +43 -5
- package/gsd-core/bin/lib/vendor/js-yaml.cjs +3014 -0
- package/gsd-core/bin/lib/verification.cjs +14 -1
- package/gsd-core/bin/lib/verify-command-grounding.cjs +846 -0
- package/gsd-core/bin/lib/verify.cjs +95 -40
- package/gsd-core/bin/lib/workstream-name-policy.cjs +25 -4
- package/gsd-core/bin/lib/worktree-base-ref.cjs +66 -12
- package/gsd-core/bin/lib/worktree-safety.cjs +177 -21
- package/gsd-core/bin/shared/config-defaults.manifest.json +7 -1
- package/gsd-core/bin/shared/config-schema.manifest.json +5 -0
- package/gsd-core/bin/shared/exit-codes.json +8 -0
- package/gsd-core/bin/shared/exit-codes.sh +20 -0
- package/gsd-core/bin/shared/model-catalog.json +8 -1
- package/gsd-core/references/agent-contracts.md +3 -2
- package/gsd-core/references/api-coverage.md +24 -2
- package/gsd-core/references/autonomous-smart-discuss.md +3 -3
- package/gsd-core/references/checkpoints.md +37 -19
- package/gsd-core/references/decimal-phase-calculation.md +5 -5
- package/gsd-core/references/edge-probe.md +8 -0
- package/gsd-core/references/execute-mvp-tdd.md +1 -3
- package/gsd-core/references/execute-phase-between-wave-reset.md +9 -12
- package/gsd-core/references/execute-phase-wave-guard.md +11 -9
- package/gsd-core/references/failing-direction.md +78 -0
- package/gsd-core/references/gate-prompts.md +1 -1
- package/gsd-core/references/git-integration.md +5 -5
- package/gsd-core/references/git-planning-commit.md +3 -3
- package/gsd-core/references/gsd-run-resolver.md +1 -1
- package/gsd-core/references/loop-hook-dispatch.md +22 -0
- package/gsd-core/references/model-profiles.md +1 -1
- package/gsd-core/references/nyquist-compliance.md +74 -0
- package/gsd-core/references/offer-next.md +3 -5
- package/gsd-core/references/phase-argument-parsing.md +3 -3
- package/gsd-core/references/planner-failing-direction.md +53 -0
- package/gsd-core/references/planner-human-verify-mode.md +15 -1
- package/gsd-core/references/planner-revision.md +1 -1
- package/gsd-core/references/planner-verify-command-grounding.md +17 -0
- package/gsd-core/references/planning-config.md +37 -8
- package/gsd-core/references/reviewer-instances.md +31 -0
- package/gsd-core/references/runtime-aware-dispatch.md +1 -1
- package/gsd-core/references/tdd.md +1 -3
- package/gsd-core/references/ui-brand.md +65 -21
- package/gsd-core/references/ui-consideration-probe.md +1 -1
- package/gsd-core/references/universal-anti-patterns.md +2 -2
- package/gsd-core/references/verify-command-path-resolvability.md +42 -0
- package/gsd-core/references/verify-mvp-mode.md +1 -1
- package/gsd-core/references/workstream-flag.md +11 -11
- package/gsd-core/templates/README.md +1 -1
- package/gsd-core/templates/SECURITY.md +3 -3
- package/gsd-core/templates/UI-SPEC.md +25 -3
- package/gsd-core/templates/VALIDATION.md +3 -3
- package/gsd-core/templates/phase-prompt.md +3 -0
- package/gsd-core/templates/state.md +7 -0
- 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 +3 -3
- package/gsd-core/workflows/add-tests.md +3 -8
- package/gsd-core/workflows/add-todo.md +1 -1
- package/gsd-core/workflows/ai-integration-phase.md +4 -9
- package/gsd-core/workflows/audit-fix.md +12 -3
- package/gsd-core/workflows/audit-milestone.md +9 -9
- package/gsd-core/workflows/audit-uat.md +17 -2
- package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +2 -2
- package/gsd-core/workflows/autonomous.md +10 -26
- package/gsd-core/workflows/check-todos.md +1 -1
- package/gsd-core/workflows/cleanup.md +2 -2
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +1 -1
- package/gsd-core/workflows/code-review-fix.md +1 -1
- package/gsd-core/workflows/code-review.md +121 -40
- package/gsd-core/workflows/complete-milestone.md +15 -10
- package/gsd-core/workflows/debug.md +5 -3
- package/gsd-core/workflows/diagnose-issues.md +12 -6
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/chain.md +3 -7
- package/gsd-core/workflows/discuss-phase/modes/text.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +1 -3
- package/gsd-core/workflows/discuss-phase-assumptions.md +2 -2
- package/gsd-core/workflows/discuss-phase.md +1 -1
- package/gsd-core/workflows/do.md +3 -6
- package/gsd-core/workflows/docs-update.md +5 -4
- package/gsd-core/workflows/edit-phase.md +1 -1
- package/gsd-core/workflows/eval-review.md +4 -9
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +113 -11
- package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/partial-wave.md +1 -1
- 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 +22 -4
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/protected-branch.md +21 -0
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +39 -0
- package/gsd-core/workflows/execute-phase.md +38 -54
- package/gsd-core/workflows/execute-plan.md +17 -12
- package/gsd-core/workflows/explore.md +1 -1
- package/gsd-core/workflows/extract-learnings.md +1 -1
- package/gsd-core/workflows/fast.md +2 -2
- package/gsd-core/workflows/forensics.md +1 -1
- package/gsd-core/workflows/graduation.md +5 -5
- package/gsd-core/workflows/health.md +3 -6
- package/gsd-core/workflows/import.md +14 -11
- package/gsd-core/workflows/inbox.md +4 -5
- package/gsd-core/workflows/ingest-docs.md +44 -11
- package/gsd-core/workflows/insert-phase.md +5 -5
- package/gsd-core/workflows/list-seeds.md +5 -3
- package/gsd-core/workflows/list-workspaces.md +1 -1
- package/gsd-core/workflows/manager.md +12 -23
- package/gsd-core/workflows/map-codebase.md +1 -1
- package/gsd-core/workflows/milestone-summary.md +1 -1
- package/gsd-core/workflows/mvp-phase.md +2 -2
- package/gsd-core/workflows/new-milestone.md +9 -21
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
- package/gsd-core/workflows/new-project.md +12 -26
- package/gsd-core/workflows/new-workspace.md +1 -1
- package/gsd-core/workflows/next.md +2 -2
- package/gsd-core/workflows/pause-work.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/adr-ingest-express-path.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +2 -4
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +3 -3
- package/gsd-core/workflows/plan-phase.md +121 -42
- package/gsd-core/workflows/plan-review-convergence.md +46 -9
- package/gsd-core/workflows/plant-seed.md +2 -2
- package/gsd-core/workflows/pr-branch.md +187 -51
- package/gsd-core/workflows/profile-user.md +16 -14
- package/gsd-core/workflows/progress.md +27 -12
- package/gsd-core/workflows/quick/steps/discussion-phase.md +1 -3
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +1 -3
- package/gsd-core/workflows/quick/steps/quick-verification.md +2 -4
- package/gsd-core/workflows/quick/steps/research-phase.md +2 -4
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +3 -3
- package/gsd-core/workflows/quick.md +20 -29
- package/gsd-core/workflows/remove-phase.md +4 -4
- package/gsd-core/workflows/remove-workspace.md +2 -2
- package/gsd-core/workflows/resume-project.md +8 -12
- package/gsd-core/workflows/review.md +193 -15
- package/gsd-core/workflows/scan.md +1 -1
- package/gsd-core/workflows/secure-phase.md +2 -2
- package/gsd-core/workflows/settings-advanced.md +7 -9
- package/gsd-core/workflows/settings-integrations.md +64 -31
- package/gsd-core/workflows/settings.md +3 -5
- package/gsd-core/workflows/ship.md +12 -6
- package/gsd-core/workflows/sketch-wrap-up.md +11 -17
- package/gsd-core/workflows/sketch.md +12 -18
- package/gsd-core/workflows/smart-entry.md +3 -5
- package/gsd-core/workflows/spec-phase.md +23 -1
- package/gsd-core/workflows/spike-wrap-up.md +7 -11
- package/gsd-core/workflows/spike.md +20 -31
- package/gsd-core/workflows/stats.md +2 -2
- package/gsd-core/workflows/sync-skills.md +1 -1
- package/gsd-core/workflows/thread.md +11 -7
- package/gsd-core/workflows/transition.md +5 -5
- package/gsd-core/workflows/ui-phase.md +10 -16
- package/gsd-core/workflows/ui-review.md +6 -10
- package/gsd-core/workflows/ultraplan-phase.md +5 -13
- package/gsd-core/workflows/undo.md +8 -16
- package/gsd-core/workflows/update.md +6 -10
- package/gsd-core/workflows/validate-phase.md +2 -2
- package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +25 -1
- package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +1 -1
- package/gsd-core/workflows/verify-work.md +57 -18
- package/hooks/dist/gsd-agent-isolation-guard.js +77 -38
- package/hooks/dist/gsd-config-reload.js +18 -12
- package/hooks/dist/gsd-context-monitor.js +19 -10
- package/hooks/dist/gsd-cursor-post-tool.js +3 -1
- package/hooks/dist/gsd-cursor-pre-tool.js +3 -1
- package/hooks/dist/gsd-cursor-session-start.js +2 -1
- package/hooks/dist/gsd-cursor-stop.js +2 -1
- package/hooks/dist/gsd-cursor-subagent-start.js +28 -23
- package/hooks/dist/gsd-cursor-subagent-stop.js +3 -1
- package/hooks/dist/gsd-ensure-canonical-path.js +2 -1
- package/hooks/dist/gsd-graphify-update.sh +22 -18
- package/hooks/dist/gsd-node-runner.sh +76 -0
- package/hooks/dist/gsd-phase-boundary.sh +1 -0
- package/hooks/dist/gsd-prompt-guard.js +16 -7
- package/hooks/dist/gsd-read-guard.js +16 -7
- package/hooks/dist/gsd-read-injection-scanner.js +17 -8
- package/hooks/dist/gsd-session-state.sh +1 -0
- package/hooks/dist/gsd-statusline.js +215 -26
- package/hooks/dist/gsd-validate-commit.sh +80 -6
- package/hooks/dist/gsd-windsurf-pre-command.js +16 -11
- package/hooks/dist/gsd-windsurf-pre-write.js +22 -13
- package/hooks/dist/gsd-workflow-guard.js +34 -16
- package/hooks/dist/gsd-worktree-path-guard.js +36 -21
- package/hooks/dist/gsd-write-guard.js +35 -25
- package/hooks/dist/lib/cli-exit.js +560 -0
- package/hooks/dist/lib/exit-code-registry.js +98 -0
- package/hooks/dist/lib/git-probe.js +84 -0
- package/hooks/dist/lib/hook-exit.js +81 -0
- package/hooks/dist/managed-hooks-registry.cjs +3 -0
- package/hooks/gsd-agent-isolation-guard.js +77 -38
- package/hooks/gsd-config-reload.js +18 -12
- package/hooks/gsd-context-monitor.js +19 -10
- package/hooks/gsd-cursor-post-tool.js +3 -1
- package/hooks/gsd-cursor-pre-tool.js +3 -1
- package/hooks/gsd-cursor-session-start.js +2 -1
- package/hooks/gsd-cursor-stop.js +2 -1
- package/hooks/gsd-cursor-subagent-start.js +28 -23
- package/hooks/gsd-cursor-subagent-stop.js +3 -1
- package/hooks/gsd-ensure-canonical-path.js +2 -1
- package/hooks/gsd-graphify-update.sh +22 -18
- package/hooks/gsd-node-runner.sh +76 -0
- package/hooks/gsd-phase-boundary.sh +1 -0
- package/hooks/gsd-prompt-guard.js +16 -7
- package/hooks/gsd-read-guard.js +16 -7
- package/hooks/gsd-read-injection-scanner.js +17 -8
- package/hooks/gsd-session-state.sh +1 -0
- package/hooks/gsd-statusline.js +215 -26
- package/hooks/gsd-validate-commit.sh +80 -6
- package/hooks/gsd-windsurf-pre-command.js +16 -11
- package/hooks/gsd-windsurf-pre-write.js +22 -13
- package/hooks/gsd-workflow-guard.js +34 -16
- package/hooks/gsd-worktree-path-guard.js +36 -21
- package/hooks/gsd-write-guard.js +35 -25
- package/hooks/lib/cli-exit.js +560 -0
- package/hooks/lib/exit-code-registry.js +98 -0
- package/hooks/lib/git-probe.js +84 -0
- package/hooks/lib/hook-exit.js +81 -0
- package/hooks/managed-hooks-registry.cjs +3 -0
- package/package.json +12 -7
- package/scripts/base64-scan.sh +74 -12
- package/scripts/build-hooks.js +5 -0
- package/scripts/check-glossary-refs.cjs +77 -15
- package/scripts/check-mutation-score-ratchet.cjs +156 -0
- package/scripts/ci-check-job-near-cap.cjs +49 -0
- package/scripts/ci-pr-mergeability.cjs +262 -0
- package/scripts/ci-test-scope.cjs +45 -12
- package/scripts/ci-timeout-report.cjs +230 -0
- package/scripts/docs-guard-registry.cjs +396 -0
- package/scripts/gen-capability-registry.cjs +8 -6
- package/scripts/gen-exit-code-docs.cjs +318 -0
- package/scripts/gen-exit-code-registry.cjs +891 -0
- package/scripts/gen-features.cjs +836 -0
- package/scripts/gen-hooks-cli-exit.cjs +239 -0
- package/scripts/gen-install-tree-fixtures.cjs +2 -2
- package/scripts/gen-loop-host-contract.cjs +134 -1
- package/scripts/gen-scripts-cli-exit.cjs +185 -0
- package/scripts/gen-state-md-docs.cjs +727 -0
- package/scripts/{test-failure-reasons.cjs → gsd-test-gate-reasons.cjs} +6 -0
- package/scripts/lib/ci-job-timing.cjs +72 -0
- package/scripts/lib/cli-exit.cjs +546 -44
- package/scripts/lib/drift-scan.cjs +32 -2
- package/scripts/lib/exit-code-registry.cjs +98 -0
- package/scripts/lib/ndjson-reporter.cjs +119 -0
- package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
- package/scripts/lint-docs-guard-registration.cjs +495 -0
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +193 -0
- package/scripts/lint-eslint-glob-coverage.allowlist.json +4 -0
- package/scripts/{lint-fix-has-regression-test.cjs → lint-fix-has-regression-tests.cjs} +12 -6
- package/scripts/lint-health-diagnostic-rule-table.cjs +65 -8
- package/scripts/lint-mutation-test-derivation-drift.cjs +86 -0
- package/scripts/lint-phase-enumeration-drift.cjs +21 -8
- package/scripts/lint-planning-prompt-drift.cjs +38 -1
- package/scripts/lint-removed-but-needed.cjs +184 -16
- package/scripts/lint-seam-enforcement.cjs +182 -0
- package/scripts/lint-slug-derivation-drift.cjs +921 -0
- package/scripts/lint-source-test-name-collision.cjs +241 -0
- package/scripts/lint-state-write-path-drift.cjs +337 -432
- package/scripts/lint-test-file-count.allowlist.json +122 -4
- package/scripts/lint-test-file-count.cjs +25 -3
- package/scripts/lint-unreachable-guard-drift.cjs +51 -64
- package/scripts/lint-vendored-deps.cjs +208 -35
- package/scripts/mutation-matrix.cjs +599 -50
- package/scripts/prompt-injection-scan.sh +75 -14
- package/scripts/secret-scan.sh +75 -13
- package/scripts/select-docs-guards.cjs +56 -0
- package/scripts/sync-runtime-launcher.cjs +22 -3
- package/skills/gsd-discuss-phase/SKILL.md +1 -1
- package/skills/gsd-import/SKILL.md +1 -1
- package/skills/gsd-quick/SKILL.md +8 -4
- package/vscode/package.json +1 -1
- package/bin/lib/ui-safety-gate.cjs +0 -109
- package/scripts/lint-emitted-drift-ack.cjs +0 -344
- package/scripts/state-write-path-drift-baseline.json +0 -19
|
@@ -20,7 +20,7 @@ Instantly restore full project context so "Where were we?" has an immediate, com
|
|
|
20
20
|
Load all context in one call:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$
|
|
23
|
+
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif _gsd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd_run is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; case "$(gsd_run runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') GSD_IDENTITY_STATUS=ok;; esac; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" did not prove it is @opengsd/gsd-core - it is either a different package or an @opengsd/gsd-core older than the runtime-identity verb. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
|
|
24
24
|
INIT=$(gsd_run query init.resume)
|
|
25
25
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
26
26
|
```
|
|
@@ -133,17 +133,13 @@ fi
|
|
|
133
133
|
Present complete project status to user:
|
|
134
134
|
|
|
135
135
|
```
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
║ Progress: [██████░░░░] XX% ║
|
|
144
|
-
║ ║
|
|
145
|
-
║ Last activity: [date] - [what happened] ║
|
|
146
|
-
╚══════════════════════════════════════════════════════════════╝
|
|
136
|
+
### PROJECT STATUS
|
|
137
|
+
|
|
138
|
+
Building: [one-liner from PROJECT.md "What This Is"]
|
|
139
|
+
Phase: [X] of [Y] - [Phase name]
|
|
140
|
+
Plan: [A] of [B] - [Status]
|
|
141
|
+
Progress: [██████░░░░] XX%
|
|
142
|
+
Last activity: [date] - [what happened]
|
|
147
143
|
|
|
148
144
|
[If incomplete work found:]
|
|
149
145
|
⚠️ Incomplete work detected:
|
|
@@ -14,7 +14,7 @@ A plan that survives review from 2-3 independent AI systems is more robust.
|
|
|
14
14
|
Check which AI CLIs are available on the system:
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$
|
|
17
|
+
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif _gsd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd_run is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; case "$(gsd_run runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') GSD_IDENTITY_STATUS=ok;; esac; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" did not prove it is @opengsd/gsd-core - it is either a different package or an @opengsd/gsd-core older than the runtime-identity verb. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
|
|
18
18
|
# Check each CLI
|
|
19
19
|
command -v gemini >/dev/null 2>&1 && echo "gemini:available" || echo "gemini:missing"
|
|
20
20
|
command -v claude >/dev/null 2>&1 && echo "claude:available" || echo "claude:missing"
|
|
@@ -316,7 +316,11 @@ reintroduce the flag (even spelled out in prose — a regression test bans the l
|
|
|
316
316
|
If `section_manifest` is `null` or `"reviewer-instances-note-2"` is in its `included` list: read and execute `gsd-core/workflows/review/steps/reviewer-instances-note-2.md`. Otherwise skip — do not read the file.
|
|
317
317
|
<!-- /gsd:section -->
|
|
318
318
|
|
|
319
|
-
Lanes run **sequentially
|
|
319
|
+
Lanes run **sequentially by default** — concurrent invocation trips provider rate limits, and a lane
|
|
320
|
+
lost to one is a cross-AI review that quietly went blind in one eye. A project whose providers can
|
|
321
|
+
accept the concurrency opts in with `review.parallel_lanes: true` (#3034): the selected lanes are
|
|
322
|
+
dispatched together and **all** joined before aggregation. The default is unchanged, and convergence
|
|
323
|
+
cycles stay sequential either way — only the lanes *within* one pass overlap.
|
|
320
324
|
|
|
321
325
|
```bash
|
|
322
326
|
# #2962: zsh aborts the block on an unmatched for-list glob (nomatch); bash passes it through. nullglob both.
|
|
@@ -327,6 +331,13 @@ REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
|
327
331
|
# SELECTED_REVIEWERS is the comma-separated result of reviewer selection (ADR-0011 precedence:
|
|
328
332
|
# explicit flags > --all > review.default_reviewers > all detected). Unchanged by this phase.
|
|
329
333
|
|
|
334
|
+
# #3034: opt-in concurrent lane dispatch. STRICT equality on "true" is deliberate — "1", "yes" and
|
|
335
|
+
# "TRUE" must NOT opt in, so a mistyped config gets the conservative behaviour rather than firing
|
|
336
|
+
# concurrent requests at a rate-limited provider. Note the `|| echo "false"` fallback is the
|
|
337
|
+
# OPPOSITE polarity from the commit_docs guard, which fails OPEN: there, failing open preserves the
|
|
338
|
+
# user's intent; here it would fire exactly the requests the default exists to prevent.
|
|
339
|
+
PARALLEL_LANES=$(gsd_run query config-get review.parallel_lanes --raw 2>/dev/null || echo "false")
|
|
340
|
+
|
|
330
341
|
# Shared budget-trim helper. Was defined inside the Ollama leg; it is lane-agnostic, so it is
|
|
331
342
|
# hoisted here now that any lane may declare a promptBudgetKey. Returns non-zero when the budget
|
|
332
343
|
# is too small for the minimum review set (prompt-budget exit 2 / 11).
|
|
@@ -360,7 +371,20 @@ gsd_run query review-lane plan \
|
|
|
360
371
|
--selected "$SELECTED_REVIEWERS" --run-dir "$RUN_DIR" --repo-root "$REPO_ROOT" --json \
|
|
361
372
|
> "$RUN_DIR/gsd-review-lanes.json"
|
|
362
373
|
|
|
363
|
-
|
|
374
|
+
# One lane, start to finish. Hoisted into a function so the sequential and concurrent paths share
|
|
375
|
+
# ONE body: two dispatch bodies kept in sync by hand is the generative-fix divergence ADR-2782 spent
|
|
376
|
+
# a phase deleting, and it is what let #2494/#2605 be filed twice as the same defect.
|
|
377
|
+
#
|
|
378
|
+
# The result goes to a SLUG-SCOPED file, never a shared append. Concurrent O_APPEND is atomic only
|
|
379
|
+
# below PIPE_BUF (4096 on Linux, 512 on some platforms), so a lane result above that bound could
|
|
380
|
+
# interleave — and write_reviews parses this JSONL to render the models:/model_sources: frontmatter,
|
|
381
|
+
# so a torn line is a broken REVIEWS.md, not a cosmetic log defect.
|
|
382
|
+
run_review_lane() {
|
|
383
|
+
# `local` is hygiene, not a live fix: each `&`-dispatched call already forks its own subshell, so
|
|
384
|
+
# concurrent lanes cannot share these today. Scoped anyway so the isolation is a property of this
|
|
385
|
+
# function rather than of the dispatch mechanism happening to fork.
|
|
386
|
+
local SLUG LANE_BUDGET PROMPT_ARG TRIMMED
|
|
387
|
+
SLUG="$1"
|
|
364
388
|
# Per-lane prompt budget. The lane declares its own `promptBudgetKey`; `plan` resolved it,
|
|
365
389
|
# applying #2797's sentinel rule (-1 = unset → fall back to the global budget; 0 legitimately
|
|
366
390
|
# means "do not trim this lane"). Trimming itself stays in prompt-budget, which owns it.
|
|
@@ -378,7 +402,9 @@ for SLUG in $(echo "$SELECTED_REVIEWERS" | tr ',' ' '); do
|
|
|
378
402
|
# response used to (#2605), so leave the skip visible in the review output, not only on stderr.
|
|
379
403
|
echo "$SLUG review skipped: prompt budget (${LANE_BUDGET} tokens) too small for the minimum review set." \
|
|
380
404
|
> "$RUN_DIR/gsd-review-$SLUG.md"
|
|
381
|
-
continue
|
|
405
|
+
# Was `continue` when this was a loop body. Inside a function that keyword is not the loop
|
|
406
|
+
# control it looks like — `return 0` is what skips this lane and leaves it with no result line.
|
|
407
|
+
return 0
|
|
382
408
|
fi
|
|
383
409
|
fi
|
|
384
410
|
|
|
@@ -387,7 +413,50 @@ for SLUG in $(echo "$SELECTED_REVIEWERS" | tr ',' ' '); do
|
|
|
387
413
|
# normal, failing to run one somebody asked for is an error.
|
|
388
414
|
gsd_run query review-lane invoke --slug "$SLUG" \
|
|
389
415
|
--run-dir "$RUN_DIR" --repo-root "$REPO_ROOT" $PROMPT_ARG $EXPLICIT_FLAG --json \
|
|
390
|
-
|
|
416
|
+
> "$RUN_DIR/gsd-review-lane-result-$SLUG.json"
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
# Split ONCE, de-duplicated, and reuse for both loops below. Two reasons, and the second is
|
|
420
|
+
# load-bearing: a slug repeated in SELECTED_REVIEWERS would put TWO concurrent background jobs on
|
|
421
|
+
# `> "$RUN_DIR/gsd-review-lane-result-$SLUG.json"` — the same file, both truncating. The shared-append
|
|
422
|
+
# form this replaced could not corrupt itself that way, so de-duping is what keeps the concurrent
|
|
423
|
+
# path no worse than the sequential one. Selection de-dupes today (the roster is a Set;
|
|
424
|
+
# review.default_reviewers normalizes lowercase-unique), but reachability analysis is not a contract
|
|
425
|
+
# and the next caller should not have to redo it.
|
|
426
|
+
#
|
|
427
|
+
# A plain string accumulator, not an array: zsh and bash disagree on array indexing and this block
|
|
428
|
+
# runs under both (see the nullglob/NULL_GLOB pairing above).
|
|
429
|
+
DISPATCH_SLUGS=""
|
|
430
|
+
for SLUG in $(echo "$SELECTED_REVIEWERS" | tr ',' ' '); do
|
|
431
|
+
case " $DISPATCH_SLUGS " in
|
|
432
|
+
*" $SLUG "*) continue ;;
|
|
433
|
+
esac
|
|
434
|
+
DISPATCH_SLUGS="$DISPATCH_SLUGS $SLUG"
|
|
435
|
+
done
|
|
436
|
+
|
|
437
|
+
for SLUG in $DISPATCH_SLUGS; do
|
|
438
|
+
if [ "$PARALLEL_LANES" = "true" ]; then
|
|
439
|
+
run_review_lane "$SLUG" &
|
|
440
|
+
else
|
|
441
|
+
run_review_lane "$SLUG"
|
|
442
|
+
fi
|
|
443
|
+
done
|
|
444
|
+
|
|
445
|
+
# Join every dispatched lane. A bare `wait` with no background jobs returns 0, so the sequential
|
|
446
|
+
# path needs no guard around it. NOTHING below this line may run before every lane has finished —
|
|
447
|
+
# write_reviews renders REVIEWS.md and the consensus summary from the aggregate below, and a review
|
|
448
|
+
# assembled from a partial set looks complete while silently missing a reviewer.
|
|
449
|
+
wait
|
|
450
|
+
|
|
451
|
+
# Aggregate in SELECTED_REVIEWERS order, NOT completion order, so the JSONL a concurrent run
|
|
452
|
+
# produces is byte-identical to the one a sequential run produces. This is post-join and therefore
|
|
453
|
+
# single-threaded, so `>>` here is safe. A lane that was budget-skipped, or that never started,
|
|
454
|
+
# leaves no result file and correctly contributes no line.
|
|
455
|
+
for SLUG in $DISPATCH_SLUGS; do
|
|
456
|
+
LANE_RESULT="$RUN_DIR/gsd-review-lane-result-$SLUG.json"
|
|
457
|
+
if [ -f "$LANE_RESULT" ]; then
|
|
458
|
+
cat "$LANE_RESULT" >> "$RUN_DIR/gsd-review-lane-results.jsonl"
|
|
459
|
+
fi
|
|
391
460
|
done
|
|
392
461
|
```
|
|
393
462
|
|
|
@@ -404,9 +473,7 @@ blocked, not silently redirected** (ADR-2782 D5).
|
|
|
404
473
|
|
|
405
474
|
Display progress:
|
|
406
475
|
```
|
|
407
|
-
|
|
408
|
-
GSD ► CROSS-AI REVIEW — Phase {N}
|
|
409
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
476
|
+
### GSD ► CROSS-AI REVIEW — Phase {N}
|
|
410
477
|
|
|
411
478
|
◆ Reviewing with {CLI}... done ✓
|
|
412
479
|
◆ Reviewing with {CLI}... done ✓
|
|
@@ -414,6 +481,61 @@ Display progress:
|
|
|
414
481
|
</step>
|
|
415
482
|
|
|
416
483
|
<step name="write_reviews">
|
|
484
|
+
**#3352 (ADR-3473 §8.5): no artifact from failed inputs.** Before rendering anything, gate on
|
|
485
|
+
whether any lane actually produced a result — "every lane failed" is exactly "the aggregate
|
|
486
|
+
JSONL has zero lines" (§`invoke_reviewers`'s aggregation loop already builds this file as a
|
|
487
|
+
byproduct; a lane that never started or was budget-skipped contributes no line either way).
|
|
488
|
+
|
|
489
|
+
```bash
|
|
490
|
+
RUN_DIR="{run_dir}"
|
|
491
|
+
JSONL="$RUN_DIR/gsd-review-lane-results.jsonl"
|
|
492
|
+
LANE_LINES=0
|
|
493
|
+
[ -f "$JSONL" ] && LANE_LINES=$(wc -l < "$JSONL" | tr -d ' ')
|
|
494
|
+
|
|
495
|
+
TOTAL_LANE_FAILURE="false"
|
|
496
|
+
ALL_LANES_SKIPPED="false"
|
|
497
|
+
if [ "${LANE_LINES:-0}" -eq 0 ]; then
|
|
498
|
+
# Zero lines means every dispatched lane left no result JSON — either every one
|
|
499
|
+
# was budget-skipped (N5: a skip is not a failure) or every one actually failed
|
|
500
|
+
# to run. Re-derive the dispatched-slug set the same way invoke_reviewers did
|
|
501
|
+
# (SELECTED_REVIEWERS is a shell block boundary — recompute, do not assume the
|
|
502
|
+
# earlier step's local DISPATCH_SLUGS variable survived into this block).
|
|
503
|
+
DISPATCH_SLUGS=""
|
|
504
|
+
for SLUG in $(echo "$SELECTED_REVIEWERS" | tr ',' ' '); do
|
|
505
|
+
case " $DISPATCH_SLUGS " in
|
|
506
|
+
*" $SLUG "*) continue ;;
|
|
507
|
+
esac
|
|
508
|
+
DISPATCH_SLUGS="$DISPATCH_SLUGS $SLUG"
|
|
509
|
+
done
|
|
510
|
+
# Distinguish by whether every dispatched slug's stub markdown says "skipped":
|
|
511
|
+
# a skip stub always does (see run_review_lane's budget branch, which writes
|
|
512
|
+
# this exact text before returning without ever invoking the lane); a real
|
|
513
|
+
# failure stub does not. If a slug has no stub at all, it is not a skip.
|
|
514
|
+
DISPATCHED_COUNT=0
|
|
515
|
+
SKIPPED_COUNT=0
|
|
516
|
+
for SLUG in $DISPATCH_SLUGS; do
|
|
517
|
+
DISPATCHED_COUNT=$((DISPATCHED_COUNT + 1))
|
|
518
|
+
STUB="$RUN_DIR/gsd-review-$SLUG.md"
|
|
519
|
+
if [ -f "$STUB" ] && grep -q "review skipped: prompt budget" "$STUB" 2>/dev/null; then
|
|
520
|
+
SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
|
|
521
|
+
fi
|
|
522
|
+
done
|
|
523
|
+
if [ "$DISPATCHED_COUNT" -gt 0 ] && [ "$SKIPPED_COUNT" -eq "$DISPATCHED_COUNT" ]; then
|
|
524
|
+
ALL_LANES_SKIPPED="true"
|
|
525
|
+
else
|
|
526
|
+
TOTAL_LANE_FAILURE="true"
|
|
527
|
+
fi
|
|
528
|
+
fi
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
- **If `ALL_LANES_SKIPPED=true`:** do NOT write `REVIEWS.md` and do NOT run the commit below —
|
|
532
|
+
there is nothing to review. Report to the user that every selected lane was budget-skipped
|
|
533
|
+
(not a failure) and stop; do not proceed to `present_results`' summary claiming a review ran.
|
|
534
|
+
- **If `TOTAL_LANE_FAILURE=true`:** do NOT write `REVIEWS.md` and do NOT run the commit below.
|
|
535
|
+
Report the total lane failure to the user (name the lanes that were dispatched and point at
|
|
536
|
+
their `.err`/stub files preserved under `.review-diagnostics/` by `present_results`) and stop.
|
|
537
|
+
- **Otherwise** (at least one lane produced a result — R1, unchanged): proceed exactly as below.
|
|
538
|
+
|
|
417
539
|
Combine all review responses into `{phase_dir}/{padded_phase}-REVIEWS.md`:
|
|
418
540
|
|
|
419
541
|
After all reviewers complete, collect trim metadata files written during the run. For each reviewer that was trimmed (i.e. a `.metadata.json` file exists and `hardFailed` or `omitted` is non-empty, or `projectMdShrunk` is true, or `planTruncationPct > 0`), include a `trimmed_reviewers` block in the frontmatter. Omit the key entirely if no reviewer was trimmed.
|
|
@@ -497,19 +619,33 @@ trimmed_reviewers: # only present if at least one reviewer was trimmed
|
|
|
497
619
|
{where reviewers disagreed — worth investigating}
|
|
498
620
|
```
|
|
499
621
|
|
|
500
|
-
Commit
|
|
622
|
+
Commit (only reached when `TOTAL_LANE_FAILURE` and `ALL_LANES_SKIPPED` are both `false` — the
|
|
623
|
+
gate above):
|
|
501
624
|
```bash
|
|
502
625
|
gsd_run query commit "docs: cross-AI review for phase {N}" --files {phase_dir}/{padded_phase}-REVIEWS.md
|
|
503
626
|
```
|
|
504
627
|
</step>
|
|
505
628
|
|
|
506
629
|
<step name="present_results">
|
|
507
|
-
|
|
630
|
+
**If `write_reviews` set `TOTAL_LANE_FAILURE=true` or `ALL_LANES_SKIPPED=true`, skip the success
|
|
631
|
+
summary below entirely** — no `REVIEWS.md` was written or committed, so there is nothing to
|
|
632
|
+
present as complete. Report instead:
|
|
633
|
+
|
|
634
|
+
```
|
|
635
|
+
### GSD ► REVIEW FAILED
|
|
636
|
+
|
|
637
|
+
Phase {N}: every selected reviewer lane {failed to produce a result|was budget-skipped} — no
|
|
638
|
+
REVIEWS.md was written.
|
|
639
|
+
|
|
640
|
+
{If the preserve+cleanup block below reports success: "Diagnostics preserved:
|
|
641
|
+
{phase_dir}/.review-diagnostics/". If it reports failure: relay its own warning verbatim —
|
|
642
|
+
it names the intact run directory holding the un-preserved evidence instead.}
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
Otherwise (at least one lane succeeded), display summary:
|
|
508
646
|
|
|
509
647
|
```
|
|
510
|
-
|
|
511
|
-
GSD ► REVIEW COMPLETE
|
|
512
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
648
|
+
### GSD ► REVIEW COMPLETE
|
|
513
649
|
|
|
514
650
|
Phase {N} reviewed by {count} AI systems.
|
|
515
651
|
|
|
@@ -522,10 +658,52 @@ To incorporate feedback into planning:
|
|
|
522
658
|
/gsd:plan-phase {N} --reviews
|
|
523
659
|
```
|
|
524
660
|
|
|
525
|
-
|
|
661
|
+
**#3352 (ADR-3473 §8.5, R3): preserve per-lane evidence before destroying it.** Regardless of
|
|
662
|
+
which branch above ran, the run's temp directory is the only record that a lane failed at all —
|
|
663
|
+
copy it beside the phase's artifacts BEFORE cleanup. A lane that produced no output at all (L4)
|
|
664
|
+
leaves nothing to preserve; that is a smaller diagnostics folder, not a fabricated one, and is
|
|
665
|
+
NOT a preservation failure. This copy is deliberately NOT part of the commit above (N6) — that
|
|
666
|
+
step names only `{padded_phase}-REVIEWS.md` explicitly, never a directory glob, so
|
|
667
|
+
`.review-diagnostics/` is never swept into it.
|
|
668
|
+
|
|
669
|
+
Preservation and cleanup MUST run in the same fenced block below (a shell variable cannot
|
|
670
|
+
survive across separate fences — each is its own process). `mkdir -p` and every `cp` are
|
|
671
|
+
exit-status checked; `rm -rf "$RUN_DIR"` runs ONLY if nothing was preserved (nothing to
|
|
672
|
+
preserve is not a failure) or everything that needed preserving was copied successfully. If
|
|
673
|
+
preservation fails partway, `$RUN_DIR` is left intact and a message names it as the location of
|
|
674
|
+
the un-preserved evidence — a leftover temp directory is far cheaper than destroyed evidence:
|
|
526
675
|
|
|
527
676
|
```bash
|
|
528
|
-
|
|
677
|
+
shopt -s nullglob 2>/dev/null; setopt NULL_GLOB 2>/dev/null
|
|
678
|
+
|
|
679
|
+
RUN_DIR="{run_dir}"
|
|
680
|
+
DIAG_DIR="{phase_dir}/.review-diagnostics"
|
|
681
|
+
|
|
682
|
+
_DIAG_MD=( "$RUN_DIR"/gsd-review-*.md )
|
|
683
|
+
_DIAG_ERR=()
|
|
684
|
+
for f in "$RUN_DIR"/gsd-review-*.err; do
|
|
685
|
+
[ -s "$f" ] && _DIAG_ERR+=("$f")
|
|
686
|
+
done
|
|
687
|
+
|
|
688
|
+
_PRESERVE_OK=true
|
|
689
|
+
if [ ${#_DIAG_MD[@]} -gt 0 ] || [ ${#_DIAG_ERR[@]} -gt 0 ]; then
|
|
690
|
+
if mkdir -p "$DIAG_DIR"; then
|
|
691
|
+
if [ ${#_DIAG_MD[@]} -gt 0 ] && ! cp "${_DIAG_MD[@]}" "$DIAG_DIR/"; then
|
|
692
|
+
_PRESERVE_OK=false
|
|
693
|
+
fi
|
|
694
|
+
if [ ${#_DIAG_ERR[@]} -gt 0 ] && ! cp "${_DIAG_ERR[@]}" "$DIAG_DIR/"; then
|
|
695
|
+
_PRESERVE_OK=false
|
|
696
|
+
fi
|
|
697
|
+
else
|
|
698
|
+
_PRESERVE_OK=false
|
|
699
|
+
fi
|
|
700
|
+
fi
|
|
701
|
+
|
|
702
|
+
if [ "$_PRESERVE_OK" = "true" ]; then
|
|
703
|
+
rm -rf "$RUN_DIR"
|
|
704
|
+
else
|
|
705
|
+
echo "WARNING: evidence preservation to $DIAG_DIR failed — leaving the un-preserved run directory intact at: $RUN_DIR" >&2
|
|
706
|
+
fi
|
|
529
707
|
```
|
|
530
708
|
</step>
|
|
531
709
|
|
|
@@ -39,7 +39,7 @@ Exit.
|
|
|
39
39
|
## Step 2: Check for existing documents
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$
|
|
42
|
+
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif _gsd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd_run is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; case "$(gsd_run runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') GSD_IDENTITY_STATUS=ok;; esac; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" did not prove it is @opengsd/gsd-core - it is either a different package or an @opengsd/gsd-core older than the runtime-identity verb. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
|
|
43
43
|
INIT=$(gsd_run query init.map-codebase 2>/dev/null || echo "{}")
|
|
44
44
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
45
45
|
```
|
|
@@ -16,8 +16,8 @@ Valid GSD subagent types (use exact names — do not fall back to 'general-purpo
|
|
|
16
16
|
## 0. Initialize
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$
|
|
20
|
-
RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --default "" 2>/dev/null || echo "")
|
|
19
|
+
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif _gsd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd_run is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; case "$(gsd_run runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') GSD_IDENTITY_STATUS=ok;; esac; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" did not prove it is @opengsd/gsd-core - it is either a different package or an @opengsd/gsd-core older than the runtime-identity verb. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
|
|
20
|
+
RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --raw --default "" 2>/dev/null || echo "")
|
|
21
21
|
INIT=$(gsd_run query init.phase-op "${PHASE_ARG}")
|
|
22
22
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
23
23
|
AGENT_SKILLS_AUDITOR=$(gsd_run query agent-skills gsd-security-auditor)
|
|
@@ -22,7 +22,7 @@ Read all files referenced by the invoking prompt's execution_context before star
|
|
|
22
22
|
Ensure config exists and resolve the workstream-aware config path (mirrors `settings.md`):
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$
|
|
25
|
+
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif _gsd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd_run is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; case "$(gsd_run runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') GSD_IDENTITY_STATUS=ok;; esac; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" did not prove it is @opengsd/gsd-core - it is either a different package or an @opengsd/gsd-core older than the runtime-identity verb. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
|
|
26
26
|
gsd_run query config-ensure-section
|
|
27
27
|
if [[ -z "${GSD_CONFIG_PATH:-}" ]]; then
|
|
28
28
|
if [[ -f .planning/active-workstream ]]; then
|
|
@@ -51,7 +51,7 @@ Planning Tuning:
|
|
|
51
51
|
- `workflow.plan_bounce_passes` (default: `2`)
|
|
52
52
|
- `workflow.plan_bounce_script` (default: `null`)
|
|
53
53
|
- `workflow.subagent_timeout` (default: `300000`)
|
|
54
|
-
- `workflow.inline_plan_threshold` (default: `
|
|
54
|
+
- `workflow.inline_plan_threshold` (default: `2`)
|
|
55
55
|
|
|
56
56
|
Execution Tuning:
|
|
57
57
|
- `workflow.node_repair` (default: `true`)
|
|
@@ -434,7 +434,7 @@ AskUserQuestion([
|
|
|
434
434
|
|
|
435
435
|
If "Other (Group B or custom)" is selected, prompt the user to enter the runtime name as a free-text string.
|
|
436
436
|
If the selected runtime differs from the stored `runtime` key, update `runtime` via
|
|
437
|
-
`
|
|
437
|
+
`gsd_run query config-set runtime <value>` before proceeding to Step C.
|
|
438
438
|
|
|
439
439
|
**Step C — Configure tier overrides for the selected runtime:**
|
|
440
440
|
|
|
@@ -494,7 +494,7 @@ change.
|
|
|
494
494
|
Merge the new settings into the existing config at `$GSD_CONFIG_PATH`. This merge is the
|
|
495
495
|
core correctness invariant: **preserve every unrelated key** — do not clobber siblings.
|
|
496
496
|
|
|
497
|
-
Apply each selected value via `
|
|
497
|
+
Apply each selected value via `gsd_run query config-set <key> <value>` so the central
|
|
498
498
|
validator (`isValidConfigKey`) accepts the write and the deep-merge preserves unrelated
|
|
499
499
|
keys and sibling sub-objects.
|
|
500
500
|
|
|
@@ -567,7 +567,7 @@ anything not listed in Sections 1–8 MUST survive the update):
|
|
|
567
567
|
```
|
|
568
568
|
|
|
569
569
|
Never emit a full overwrite of the file that omits keys the user did not touch. Always
|
|
570
|
-
route each write through `
|
|
570
|
+
route each write through `gsd_run query config-set` so sibling preservation is handled by
|
|
571
571
|
the central setter.
|
|
572
572
|
</step>
|
|
573
573
|
|
|
@@ -747,9 +747,7 @@ Never write a tier the user explicitly chose to keep; the existing value must su
|
|
|
747
747
|
Display:
|
|
748
748
|
|
|
749
749
|
```text
|
|
750
|
-
|
|
751
|
-
GSD ► ADVANCED SETTINGS UPDATED
|
|
752
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
750
|
+
### GSD ► ADVANCED SETTINGS UPDATED
|
|
753
751
|
|
|
754
752
|
| Setting | Value |
|
|
755
753
|
|--------------------------------------------|-------|
|
|
@@ -809,7 +807,7 @@ UI/AI phase gates), use /gsd:settings.
|
|
|
809
807
|
- [ ] Numeric inputs validated — non-numeric rejected and re-prompted
|
|
810
808
|
- [ ] Branch-template inputs validated — non-default must contain a placeholder
|
|
811
809
|
- [ ] Null-allowed fields accept an empty input as a clear
|
|
812
|
-
- [ ] Writes routed through `
|
|
810
|
+
- [ ] Writes routed through `gsd_run query config-set` so unrelated keys are preserved
|
|
813
811
|
- [ ] Section 7 shows current runtime and built-in tier table
|
|
814
812
|
- [ ] Group B runtimes display "(no built-in default — your runtime handles model selection)"
|
|
815
813
|
- [ ] Override set/clear/keep paths all work correctly for each tier
|