@opengsd/gsd-core 1.11.0 → 1.13.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 +12 -0
- 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 +78 -42
- 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 +91 -112
- package/agents/gsd-planner.md +20 -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 +82 -7
- package/agents/gsd-ui-researcher.md +70 -3
- package/agents/gsd-verifier.md +24 -2
- package/bin/install.js +847 -200
- package/commands/gsd/discuss-phase.md +1 -1
- package/commands/gsd/execute-phase.md +1 -1
- package/commands/gsd/import.md +1 -1
- package/commands/gsd/ns-workflow.md +2 -1
- package/commands/gsd/phase.md +1 -1
- package/commands/gsd/quick-batch.md +105 -0
- package/commands/gsd/quick.md +8 -4
- package/commands/gsd/surface.md +18 -8
- package/gsd-core/bin/gsd-tools.cjs +761 -100
- 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-activation.cjs +27 -0
- package/gsd-core/bin/lib/capability-lock.cjs +10 -4
- package/gsd-core/bin/lib/capability-registry.cjs +785 -144
- package/gsd-core/bin/lib/capability-state.cjs +25 -4
- package/gsd-core/bin/lib/capability-validator.cjs +321 -18
- package/gsd-core/bin/lib/capability-writer.cjs +14 -4
- package/gsd-core/bin/lib/check-command-router.cjs +229 -6
- package/gsd-core/bin/lib/claude-orchestration.cjs +10 -25
- package/gsd-core/bin/lib/cli-exit.cjs +496 -10
- package/gsd-core/bin/lib/clusters.cjs +1 -0
- 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-aliases.cjs +16 -0
- 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 +877 -54
- package/gsd-core/bin/lib/complexity-trigger.cjs +26 -6
- package/gsd-core/bin/lib/config-loader.cjs +121 -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 +118 -14
- package/gsd-core/bin/lib/decisions.cjs +213 -1
- package/gsd-core/bin/lib/edge-probe.cjs +23 -2
- 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/file-overlap-partitioner.cjs +74 -0
- package/gsd-core/bin/lib/frontmatter.cjs +975 -326
- package/gsd-core/bin/lib/gap-checker.cjs +41 -8
- package/gsd-core/bin/lib/git-base-branch.cjs +182 -39
- package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +7 -3
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +8 -2
- package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +60 -14
- package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +75 -22
- 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 +96 -11
- package/gsd-core/bin/lib/init-command-router.cjs +132 -21
- package/gsd-core/bin/lib/init.cjs +252 -56
- package/gsd-core/bin/lib/install-engine.cjs +252 -15
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +78 -1
- package/gsd-core/bin/lib/install-profiles.cjs +100 -18
- package/gsd-core/bin/lib/installer-migration-report.cjs +4 -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 +195 -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/loop-resolver.cjs +14 -8
- package/gsd-core/bin/lib/markdown-table.cjs +175 -4
- package/gsd-core/bin/lib/milestone.cjs +112 -7
- 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-command-router.cjs +13 -6
- package/gsd-core/bin/lib/phase-estimation.cjs +17 -8
- package/gsd-core/bin/lib/phase-id.cjs +321 -13
- 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 +1175 -115
- package/gsd-core/bin/lib/plan-document.cjs +273 -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 +165 -34
- package/gsd-core/bin/lib/planning-workspace.cjs +159 -28
- 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/quick-batch-command-router.cjs +285 -0
- package/gsd-core/bin/lib/quick-batch-dispatch.cjs +250 -0
- package/gsd-core/bin/lib/quick-batch.cjs +840 -0
- 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 +62 -14
- package/gsd-core/bin/lib/review-lane-invocation.cjs +73 -1
- package/gsd-core/bin/lib/review-lane-runner.cjs +136 -10
- package/gsd-core/bin/lib/roadmap-command-router.cjs +45 -31
- package/gsd-core/bin/lib/roadmap-parser.cjs +577 -41
- package/gsd-core/bin/lib/roadmap.cjs +248 -64
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +329 -41
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +16 -17
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +320 -109
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +487 -83
- 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 +75 -8
- package/gsd-core/bin/lib/smart-entry.cjs +19 -31
- 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 +216 -5
- package/gsd-core/bin/lib/state-md-schema.cjs +231 -0
- package/gsd-core/bin/lib/state-transition.cjs +850 -145
- package/gsd-core/bin/lib/state.cjs +1629 -287
- package/gsd-core/bin/lib/surface.cjs +33 -10
- 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/tdd-red-evidence.cjs +133 -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 +2542 -387
- 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/update-context.cjs +6 -2
- package/gsd-core/bin/lib/validate-command-router.cjs +2 -2
- package/gsd-core/bin/lib/validate.cjs +230 -12
- 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-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +287 -13
- package/gsd-core/bin/lib/verify-command-grounding.cjs +846 -0
- package/gsd-core/bin/lib/verify-command-router.cjs +1 -0
- package/gsd-core/bin/lib/verify.cjs +441 -56
- package/gsd-core/bin/lib/workstream-inventory.cjs +20 -2
- 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 +185 -21
- package/gsd-core/bin/shared/config-defaults.manifest.json +7 -1
- package/gsd-core/bin/shared/config-schema.manifest.json +13 -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/bin/verify-reapply-patches.cjs +70 -3
- package/gsd-core/references/agent-contracts.md +6 -5
- 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 +17 -5
- package/gsd-core/references/execute-mvp-tdd.md +18 -18
- package/gsd-core/references/execute-phase-between-wave-reset.md +9 -12
- package/gsd-core/references/execute-phase-response-language.md +6 -0
- package/gsd-core/references/execute-phase-wave-guard.md +11 -9
- package/gsd-core/references/executor-examples.md +42 -0
- package/gsd-core/references/failing-direction.md +78 -0
- package/gsd-core/references/few-shot-examples/plan-checker.md +15 -15
- 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/mvp-concepts.md +2 -2
- 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/plan-checker-examples.md +41 -0
- package/gsd-core/references/planner-antipatterns.md +25 -0
- package/gsd-core/references/planner-chunked.md +5 -1
- package/gsd-core/references/planner-coupling.md +42 -0
- 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-quick-batch.md +71 -0
- package/gsd-core/references/planner-reviews.md +47 -0
- package/gsd-core/references/planner-revision.md +76 -3
- package/gsd-core/references/planner-verify-command-grounding.md +17 -0
- package/gsd-core/references/planning-config.md +39 -9
- package/gsd-core/references/response-language-directive.md +9 -0
- package/gsd-core/references/reviewer-instances.md +31 -0
- package/gsd-core/references/revision-loop.md +118 -11
- package/gsd-core/references/runtime-aware-dispatch.md +1 -1
- package/gsd-core/references/tdd.md +15 -12
- 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/verifier-evidence-gate.md +160 -0
- 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 +7 -0
- package/gsd-core/templates/state.md +7 -0
- package/gsd-core/templates/verification-report.md +5 -0
- package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
- package/gsd-core/workflows/add-backlog.md +3 -1
- package/gsd-core/workflows/add-phase.md +5 -3
- package/gsd-core/workflows/add-tests.md +4 -9
- package/gsd-core/workflows/add-todo.md +2 -2
- package/gsd-core/workflows/ai-integration-phase.md +5 -10
- package/gsd-core/workflows/analyze-dependencies.md +2 -0
- package/gsd-core/workflows/audit-fix.md +14 -3
- package/gsd-core/workflows/audit-milestone.md +11 -9
- package/gsd-core/workflows/audit-uat.md +19 -2
- package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +2 -2
- package/gsd-core/workflows/autonomous.md +12 -26
- package/gsd-core/workflows/check-todos.md +2 -2
- package/gsd-core/workflows/cleanup.md +3 -3
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +16 -14
- package/gsd-core/workflows/code-review-fix.md +3 -1
- package/gsd-core/workflows/code-review.md +192 -69
- package/gsd-core/workflows/complete-milestone.md +28 -14
- package/gsd-core/workflows/debug.md +6 -4
- package/gsd-core/workflows/diagnose-issues.md +17 -7
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +3 -1
- package/gsd-core/workflows/discuss-phase/modes/all.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/analyze.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/auto.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/batch.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/chain.md +5 -7
- package/gsd-core/workflows/discuss-phase/modes/default.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/power.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/text.md +3 -1
- package/gsd-core/workflows/discuss-phase/templates/context.md +2 -0
- package/gsd-core/workflows/discuss-phase/templates/discussion-log.md +2 -0
- package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +1 -3
- package/gsd-core/workflows/discuss-phase-assumptions.md +3 -3
- package/gsd-core/workflows/discuss-phase-power.md +2 -0
- package/gsd-core/workflows/discuss-phase.md +2 -2
- package/gsd-core/workflows/do.md +46 -19
- package/gsd-core/workflows/docs-update.md +6 -5
- package/gsd-core/workflows/edit-phase.md +3 -1
- package/gsd-core/workflows/eval-review.md +5 -10
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +3 -1
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +129 -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 +29 -5
- 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 +4 -2
- package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +25 -0
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +39 -0
- package/gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md +2 -0
- package/gsd-core/workflows/execute-phase.md +68 -66
- package/gsd-core/workflows/execute-plan.md +25 -20
- package/gsd-core/workflows/explore.md +3 -1
- package/gsd-core/workflows/extract-learnings.md +3 -1
- package/gsd-core/workflows/fast.md +8 -2
- package/gsd-core/workflows/forensics.md +3 -1
- package/gsd-core/workflows/graduation.md +6 -6
- package/gsd-core/workflows/health.md +4 -7
- package/gsd-core/workflows/help/modes/brief.md +2 -0
- package/gsd-core/workflows/help/modes/default.md +2 -0
- package/gsd-core/workflows/help/modes/full.md +12 -0
- package/gsd-core/workflows/help/modes/topic.md +2 -0
- package/gsd-core/workflows/help.md +2 -0
- package/gsd-core/workflows/import.md +17 -14
- package/gsd-core/workflows/inbox.md +5 -6
- package/gsd-core/workflows/ingest-docs.md +45 -12
- package/gsd-core/workflows/insert-phase.md +7 -5
- package/gsd-core/workflows/list-phase-assumptions.md +2 -0
- package/gsd-core/workflows/list-seeds.md +7 -3
- package/gsd-core/workflows/list-workspaces.md +3 -1
- package/gsd-core/workflows/manager.md +15 -26
- package/gsd-core/workflows/map-codebase.md +3 -1
- package/gsd-core/workflows/milestone-summary.md +3 -1
- package/gsd-core/workflows/mvp-phase.md +3 -3
- package/gsd-core/workflows/new-milestone.md +10 -22
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
- package/gsd-core/workflows/new-project.md +17 -29
- package/gsd-core/workflows/new-workspace.md +2 -2
- package/gsd-core/workflows/next.md +4 -2
- package/gsd-core/workflows/node-repair.md +2 -0
- package/gsd-core/workflows/note.md +2 -0
- package/gsd-core/workflows/onboard.md +1 -1
- package/gsd-core/workflows/pause-work.md +20 -5
- 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 +100 -18
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +4 -4
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +12 -3
- package/gsd-core/workflows/plan-phase.md +251 -54
- package/gsd-core/workflows/plan-review-convergence.md +148 -19
- package/gsd-core/workflows/plant-seed.md +3 -3
- package/gsd-core/workflows/pr-branch.md +195 -51
- package/gsd-core/workflows/profile-user.md +17 -15
- package/gsd-core/workflows/progress/steps/forensic-audit.md +1 -1
- package/gsd-core/workflows/progress.md +52 -15
- package/gsd-core/workflows/quick/steps/discussion-phase.md +1 -3
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +38 -5
- package/gsd-core/workflows/quick/steps/quick-verification.md +2 -4
- package/gsd-core/workflows/quick/steps/research-phase.md +5 -7
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +3 -3
- package/gsd-core/workflows/quick-batch/steps/batch-init.md +55 -0
- package/gsd-core/workflows/quick-batch/steps/completion.md +65 -0
- package/gsd-core/workflows/quick-batch/steps/merge-wave.md +100 -0
- package/gsd-core/workflows/quick-batch/steps/plan-checker-loop.md +147 -0
- package/gsd-core/workflows/quick-batch/steps/planner-wave.md +158 -0
- package/gsd-core/workflows/quick-batch/steps/research-phase.md +95 -0
- package/gsd-core/workflows/quick-batch/steps/resume-mode.md +49 -0
- package/gsd-core/workflows/quick-batch/steps/verification-wave.md +73 -0
- package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +169 -0
- package/gsd-core/workflows/quick-batch.md +203 -0
- package/gsd-core/workflows/quick.md +33 -32
- package/gsd-core/workflows/reapply-patches.md +2 -0
- package/gsd-core/workflows/remove-phase.md +6 -4
- package/gsd-core/workflows/remove-workspace.md +3 -3
- package/gsd-core/workflows/resume-project.md +14 -14
- package/gsd-core/workflows/review.md +404 -21
- package/gsd-core/workflows/scan.md +3 -1
- package/gsd-core/workflows/section-manifest.json +12 -0
- package/gsd-core/workflows/secure-phase.md +3 -3
- package/gsd-core/workflows/session-report.md +2 -0
- package/gsd-core/workflows/settings-advanced.md +9 -9
- package/gsd-core/workflows/settings-integrations.md +66 -32
- package/gsd-core/workflows/settings.md +4 -6
- package/gsd-core/workflows/ship.md +22 -16
- package/gsd-core/workflows/sketch-wrap-up.md +13 -17
- package/gsd-core/workflows/sketch.md +13 -19
- package/gsd-core/workflows/smart-entry.md +4 -6
- package/gsd-core/workflows/spec-phase.md +31 -4
- package/gsd-core/workflows/spike-wrap-up.md +9 -11
- package/gsd-core/workflows/spike.md +21 -32
- package/gsd-core/workflows/stats.md +4 -2
- package/gsd-core/workflows/sync-skills.md +13 -5
- package/gsd-core/workflows/thread.md +13 -7
- package/gsd-core/workflows/transition.md +7 -5
- package/gsd-core/workflows/ui-phase.md +36 -21
- package/gsd-core/workflows/ui-review.md +7 -11
- package/gsd-core/workflows/ultraplan-phase.md +7 -13
- package/gsd-core/workflows/undo.md +9 -17
- package/gsd-core/workflows/update.md +47 -48
- package/gsd-core/workflows/validate-phase.md +3 -3
- 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 +106 -21
- package/hooks/dist/gsd-agent-isolation-guard.js +77 -38
- package/hooks/dist/gsd-check-update-worker.js +19 -2
- package/hooks/dist/gsd-config-reload.js +18 -12
- package/hooks/dist/gsd-context-monitor.js +302 -22
- 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 +77 -0
- package/hooks/dist/gsd-phase-boundary.sh +1 -0
- package/hooks/dist/gsd-prompt-guard.js +46 -12
- package/hooks/dist/gsd-read-guard.js +18 -7
- package/hooks/dist/gsd-read-injection-scanner.js +22 -13
- package/hooks/dist/gsd-secret-read-guard.js +1079 -0
- package/hooks/dist/gsd-session-state.sh +1 -0
- package/hooks/dist/gsd-statusline.js +222 -29
- package/hooks/dist/gsd-validate-commit.sh +523 -12
- 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 +36 -17
- 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-cmd.js +210 -1
- package/hooks/dist/lib/git-probe.js +84 -0
- package/hooks/dist/lib/hook-exit.js +81 -0
- package/hooks/dist/lib/injection-patterns.js +36 -6
- package/hooks/dist/managed-hooks-registry.cjs +4 -0
- package/hooks/gsd-agent-isolation-guard.js +77 -38
- package/hooks/gsd-check-update-worker.js +19 -2
- package/hooks/gsd-config-reload.js +18 -12
- package/hooks/gsd-context-monitor.js +302 -22
- 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 +77 -0
- package/hooks/gsd-phase-boundary.sh +1 -0
- package/hooks/gsd-prompt-guard.js +46 -12
- package/hooks/gsd-read-guard.js +18 -7
- package/hooks/gsd-read-injection-scanner.js +22 -13
- package/hooks/gsd-secret-read-guard.js +1079 -0
- package/hooks/gsd-session-state.sh +1 -0
- package/hooks/gsd-statusline.js +222 -29
- package/hooks/gsd-validate-commit.sh +523 -12
- package/hooks/gsd-windsurf-pre-command.js +16 -11
- package/hooks/gsd-windsurf-pre-write.js +22 -13
- package/hooks/gsd-workflow-guard.js +36 -17
- package/hooks/gsd-worktree-path-guard.js +36 -21
- package/hooks/gsd-write-guard.js +35 -25
- package/hooks/hooks.json +6 -0
- package/hooks/lib/cli-exit.js +560 -0
- package/hooks/lib/exit-code-registry.js +98 -0
- package/hooks/lib/git-cmd.js +210 -1
- package/hooks/lib/git-probe.js +84 -0
- package/hooks/lib/hook-exit.js +81 -0
- package/hooks/lib/injection-patterns.js +36 -6
- package/hooks/managed-hooks-registry.cjs +4 -0
- package/package.json +14 -9
- package/scripts/base64-scan.sh +74 -12
- package/scripts/build-hooks.js +12 -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 +52 -12
- package/scripts/ci-timeout-report.cjs +230 -0
- package/scripts/docs-guard-registry.cjs +406 -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 +189 -4
- 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/lib/shellcheck-fetch.cjs +247 -0
- package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -6
- 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-docs-guard-registration.cjs +495 -0
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +198 -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 +45 -14
- package/scripts/lint-phase-id-drift.cjs +133 -8
- package/scripts/lint-planning-prompt-drift.cjs +38 -1
- package/scripts/lint-portable-grep.cjs +176 -0
- package/scripts/lint-removed-but-needed.cjs +184 -16
- package/scripts/lint-response-language-coverage.cjs +524 -0
- 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 +124 -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/lint-workflow-shellcheck-baseline.json +1027 -0
- package/scripts/lint-workflow-shellcheck.cjs +614 -0
- package/scripts/mutation-matrix.cjs +599 -50
- package/scripts/npm-audit-baseline.cjs +376 -0
- package/scripts/prompt-injection-scan.sh +83 -14
- package/scripts/require-issue-link-policy.cjs +16 -1
- 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-execute-phase/SKILL.md +1 -1
- package/skills/gsd-import/SKILL.md +1 -1
- package/skills/gsd-ns-workflow/SKILL.md +1 -0
- package/skills/gsd-phase/SKILL.md +1 -1
- package/skills/gsd-quick/SKILL.md +8 -4
- package/skills/gsd-quick-batch/SKILL.md +105 -0
- package/skills/gsd-surface/SKILL.md +18 -8
- 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
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@~/.claude/gsd-core/references/response-language-directive.md
|
|
2
|
+
|
|
1
3
|
<purpose>
|
|
2
4
|
Review source files changed during a phase for bugs, security issues, and code quality problems. Computes file scope (--files override > SUMMARY.md > git diff fallback), checks config gate, spawns gsd-code-reviewer agent, commits REVIEW.md, and presents results to user. When --fix is passed, delegates to code-review-fix.md after review to auto-apply findings via gsd-code-fixer.
|
|
3
5
|
</purpose>
|
|
@@ -17,7 +19,7 @@ Read all files referenced by the invoking prompt's execution_context before star
|
|
|
17
19
|
Parse arguments and load project state:
|
|
18
20
|
|
|
19
21
|
```bash
|
|
20
|
-
_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 "$
|
|
22
|
+
_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
|
|
21
23
|
PHASE_ARG="${1}"
|
|
22
24
|
|
|
23
25
|
# Parse all code-review flags into a structured IR via code-review-flags.cjs.
|
|
@@ -81,55 +83,35 @@ fi
|
|
|
81
83
|
</step>
|
|
82
84
|
|
|
83
85
|
<step name="check_config_gate">
|
|
84
|
-
Check if code review is active via the capability
|
|
86
|
+
Check if code review is active via `workflow.code_review` (the capability's on/off toggle — independent of `workflow.code_review_point`, the loop-point selector; a manual invocation must work regardless of which automatic point is currently configured):
|
|
85
87
|
|
|
86
88
|
```bash
|
|
87
|
-
|
|
89
|
+
CODE_REVIEW_ENABLED=$(gsd_run query config-get workflow.code_review --raw 2>/dev/null || echo "true")
|
|
88
90
|
```
|
|
89
91
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
If no active code-review step hook exists:
|
|
92
|
+
If `CODE_REVIEW_ENABLED` is not `"true"`:
|
|
93
93
|
```
|
|
94
94
|
Code review skipped (code-review capability inactive)
|
|
95
95
|
```
|
|
96
96
|
Exit workflow.
|
|
97
97
|
|
|
98
|
-
Default is active
|
|
98
|
+
Default is active (`workflow.code_review` schema default is `true`) — only skip when explicitly disabled. This check runs AFTER phase validation so invalid phase errors are shown first.
|
|
99
99
|
</step>
|
|
100
100
|
|
|
101
|
-
<step name="
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
1. DEPTH_OVERRIDE from --depth flag (highest priority)
|
|
105
|
-
2. Config value: `gsd-tools.cjs query config-get workflow.code_review_depth 2>/dev/null`
|
|
106
|
-
3. Default: "standard"
|
|
101
|
+
<step name="compute_file_scope">
|
|
102
|
+
Three-tier scoping with explicit precedence:
|
|
107
103
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
REVIEW_DEPTH="$DEPTH_OVERRIDE"
|
|
111
|
-
else
|
|
112
|
-
CONFIG_DEPTH=$(gsd_run query config-get workflow.code_review_depth 2>/dev/null || echo "")
|
|
113
|
-
REVIEW_DEPTH="${CONFIG_DEPTH:-standard}"
|
|
114
|
-
fi
|
|
115
|
-
```
|
|
104
|
+
Compute the phase's last review commit, if any. This narrows Tiers 2 and 3 below to what
|
|
105
|
+
changed since that review (wave-scoped reviews under `workflow.code_review_point=execute:wave:post`):
|
|
116
106
|
|
|
117
|
-
**Validate depth value:**
|
|
118
107
|
```bash
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
REVIEW_DEPTH="standard"
|
|
126
|
-
;;
|
|
127
|
-
esac
|
|
108
|
+
# #3661: incremental scoping — when this phase has a prior review, later tiers
|
|
109
|
+
# narrow to what changed since it (wave-scoped reviews under
|
|
110
|
+
# workflow.code_review_point=execute:wave:post). Empty on a phase's first review
|
|
111
|
+
# (the entire execute:post-default path), in which case Tiers 2 and 3 below are
|
|
112
|
+
# unchanged from today.
|
|
113
|
+
LAST_REVIEW_COMMIT=$(git log --format=%H -1 -- "${PHASE_DIR}/${PADDED_PHASE}-REVIEW.md" 2>/dev/null)
|
|
128
114
|
```
|
|
129
|
-
</step>
|
|
130
|
-
|
|
131
|
-
<step name="compute_file_scope">
|
|
132
|
-
Three-tier scoping with explicit precedence:
|
|
133
115
|
|
|
134
116
|
**Tier 1 — --files override (highest precedence per D-08):**
|
|
135
117
|
|
|
@@ -170,7 +152,18 @@ if [ -z "$FILES_OVERRIDE" ]; then
|
|
|
170
152
|
REVIEW_FILES=()
|
|
171
153
|
|
|
172
154
|
if [ -n "$SUMMARIES" ]; then
|
|
173
|
-
|
|
155
|
+
# Rewrapped through unquoted command substitution (gsd-core#4109): a bare
|
|
156
|
+
# `$VAR` word-splits under bash but not zsh, collapsing every element onto
|
|
157
|
+
# one iteration there.
|
|
158
|
+
for summary in $(printf '%s' "$SUMMARIES"); do
|
|
159
|
+
# #3661: skip a SUMMARY.md unchanged since the phase's last review — this
|
|
160
|
+
# summary's plan was already reviewed. No-op (every summary is "changed") when
|
|
161
|
+
# LAST_REVIEW_COMMIT is empty. Fails OPEN on any git error (file stays in scope)
|
|
162
|
+
# — never silently drop a file because a git command errored.
|
|
163
|
+
if [ -n "$LAST_REVIEW_COMMIT" ] && git diff --quiet "${LAST_REVIEW_COMMIT}" HEAD -- "$summary" 2>/dev/null; then
|
|
164
|
+
continue
|
|
165
|
+
fi
|
|
166
|
+
|
|
174
167
|
# Extract key_files.created and key_files.modified using node for reliable YAML parsing
|
|
175
168
|
# This avoids fragile awk parsing that breaks on indentation differences
|
|
176
169
|
EXTRACTED=$(node -e "
|
|
@@ -252,17 +245,31 @@ surface — so a partial SUMMARY result can no longer silently mask the rest of
|
|
|
252
245
|
# #3191: stay POSIX-ERE portable — the boundary is the closing paren + colon,
|
|
253
246
|
# never \b (not a POSIX ERE token; under --extended-regexp it silently matches
|
|
254
247
|
# nothing on macOS regex(3), making this fallback dead on Apple platforms).
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
248
|
+
# #3995: a phase number is unique within a MILESTONE, not a repository. The
|
|
249
|
+
# former message grep had no milestone bound, and its tail -1 deliberately
|
|
250
|
+
# selected the OLDEST matching subject — dragging in previous milestones'
|
|
251
|
+
# same-numbered phases and taking a 7-file phase to a 3388-file scope (plus
|
|
252
|
+
# the >50 depth downgrade). The phase's own directory is the unique identity:
|
|
253
|
+
# base = the parent of the first commit that added anything under PHASE_DIR
|
|
254
|
+
# (the same anchor class git-base-branch's phaseStartCommit uses for
|
|
255
|
+
# complexity triggering). Message subjects demonstrably do not carry enough
|
|
256
|
+
# information to identify a phase — this was the grep's fifth failure.
|
|
257
|
+
# KNOWN RESIDUAL: git log -- <dir> does not follow renames, so a LATER
|
|
258
|
+
# milestone that reuses BOTH number and slug re-creates the same literal
|
|
259
|
+
# path and the oldest A-commit is the previous occupant's. Number+slug
|
|
260
|
+
# reuse is the narrow trigger; the reported archived-milestone case (dirs
|
|
261
|
+
# move under milestones/ on archive) is closed.
|
|
262
|
+
PHASE_START=$(git log --format="%H" --diff-filter=A -- "${PHASE_DIR}" 2>/dev/null | tail -1)
|
|
260
263
|
DIFF_BASE=""
|
|
261
|
-
if [ -n "$
|
|
262
|
-
|
|
263
|
-
#
|
|
264
|
-
|
|
265
|
-
|
|
264
|
+
if [ -n "$LAST_REVIEW_COMMIT" ]; then
|
|
265
|
+
# #3661: a prior review exists — narrow the diff base to since that review
|
|
266
|
+
# (wave-scoped) instead of the whole phase.
|
|
267
|
+
DIFF_BASE="$LAST_REVIEW_COMMIT"
|
|
268
|
+
elif [ -n "$PHASE_START" ]; then
|
|
269
|
+
if git rev-parse "${PHASE_START}^" >/dev/null 2>&1; then
|
|
270
|
+
DIFF_BASE="${PHASE_START}^"
|
|
271
|
+
else
|
|
272
|
+
DIFF_BASE="${PHASE_START}"
|
|
266
273
|
fi
|
|
267
274
|
fi
|
|
268
275
|
|
|
@@ -394,12 +401,122 @@ echo "File scope: ${#REVIEW_FILES[@]} files from ${TIER}"
|
|
|
394
401
|
if [ ${#REVIEW_FILES[@]} -gt 50 ]; then
|
|
395
402
|
echo "Warning: ${#REVIEW_FILES[@]} files is a large review scope."
|
|
396
403
|
echo "Consider using --files to narrow scope, or --depth=quick for a faster pass."
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
404
|
+
fi
|
|
405
|
+
```
|
|
406
|
+
</step>
|
|
407
|
+
|
|
408
|
+
<step name="resolve_depth">
|
|
409
|
+
Determine review depth via the path-scoped depth resolver (`code-review-depth.cjs`). This step runs after `compute_file_scope` because rule matching needs the final `REVIEW_FILES` set.
|
|
410
|
+
|
|
411
|
+
```bash
|
|
412
|
+
CONFIG_DEPTH=$(gsd_run query config-get workflow.code_review_depth --raw 2>/dev/null || echo "")
|
|
413
|
+
DEPTH_OVERRIDES=$(gsd_run query config-get workflow.code_review_depth_overrides --default '[]' 2>/dev/null || echo '[]')
|
|
414
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
415
|
+
|
|
416
|
+
# Files travel on stdin, never argv — a 50+-file scope with long paths approaches the
|
|
417
|
+
# Windows execFileSync 32,767-char argv ceiling; stdin has no such bound.
|
|
418
|
+
DEPTH_PAYLOAD=$(printf '%s\n' "${REVIEW_FILES[@]}" | FLAG_DEPTH="$DEPTH_OVERRIDE" CONFIG_DEPTH="$CONFIG_DEPTH" DEPTH_OVERRIDES="$DEPTH_OVERRIDES" REPO_ROOT="$REPO_ROOT" node -e "
|
|
419
|
+
const files = require('fs').readFileSync('/dev/stdin', 'utf-8').split('\n').filter(Boolean);
|
|
420
|
+
process.stdout.write(JSON.stringify({
|
|
421
|
+
flagDepth: process.env.FLAG_DEPTH || '',
|
|
422
|
+
configDepth: process.env.CONFIG_DEPTH || '',
|
|
423
|
+
overrides: JSON.parse(process.env.DEPTH_OVERRIDES || '[]'),
|
|
424
|
+
files,
|
|
425
|
+
repoRoot: process.env.REPO_ROOT || '',
|
|
426
|
+
}));
|
|
427
|
+
")
|
|
428
|
+
|
|
429
|
+
DEPTH_JSON=$(echo "$DEPTH_PAYLOAD" | node -e "
|
|
430
|
+
const { resolveCodeReviewDepth } = require('./gsd-core/bin/lib/code-review-depth.cjs');
|
|
431
|
+
const input = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf-8'));
|
|
432
|
+
process.stdout.write(JSON.stringify(resolveCodeReviewDepth(input)));
|
|
433
|
+
")
|
|
434
|
+
|
|
435
|
+
DEPTH_OK=$(echo "$DEPTH_JSON" | node -e "process.stdout.write(String(JSON.parse(require('fs').readFileSync('/dev/stdin','utf-8')).ok))")
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
The guard and the extraction it protects must run as one shell control-flow decision — a prose sentence between two fenced blocks is not a guard, since fenced blocks do not share shell state. Anything other than the literal string `true` (including an empty `DEPTH_OK`, which is what a crashed or missing resolver produces) is treated as failure, and the failure branch exits before any extraction can run:
|
|
439
|
+
|
|
440
|
+
```bash
|
|
441
|
+
if [ "$DEPTH_OK" = "true" ]; then
|
|
442
|
+
# Single spawn: emit all seven fields as Unit-Separator-delimited (U+001F) values,
|
|
443
|
+
# fixed order. Field '\x1f' (not '\n') is deliberate: bash's `read` treats '\n' as
|
|
444
|
+
# "IFS whitespace" and collapses runs of it, silently dropping an empty field (e.g.
|
|
445
|
+
# DEPTH_MATCHED_RULE_PATH when matchedRule is null) — '\x1f' is not IFS-whitespace,
|
|
446
|
+
# so each empty field survives as its own zero-length token. This is safe only
|
|
447
|
+
# because validateRulePath (src/code-review-depth.cts) rejects any rule path
|
|
448
|
+
# carrying an interior control character, including U+001F itself — so
|
|
449
|
+
# DEPTH_MATCHED_RULE_PATH below can never collide with the delimiter. Do not
|
|
450
|
+
# remove that validation without revisiting this split.
|
|
451
|
+
DEPTH_FIELDS=$(echo "$DEPTH_JSON" | node -e "
|
|
452
|
+
const d = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf-8'));
|
|
453
|
+
const r = d.matchedRule;
|
|
454
|
+
process.stdout.write([
|
|
455
|
+
d.depth,
|
|
456
|
+
d.source,
|
|
457
|
+
r ? String(r.index) : '',
|
|
458
|
+
r ? r.path : '',
|
|
459
|
+
String(!!d.invalidFlagDepth),
|
|
460
|
+
String(!!d.invalidConfigDepth),
|
|
461
|
+
String(!!d.downgraded),
|
|
462
|
+
].join('\x1f'));
|
|
463
|
+
")
|
|
464
|
+
IFS=$'\x1f' read -r -d '' REVIEW_DEPTH DEPTH_SOURCE DEPTH_MATCHED_RULE_INDEX DEPTH_MATCHED_RULE_PATH \
|
|
465
|
+
DEPTH_INVALID_FLAG DEPTH_INVALID_CONFIG DEPTH_DOWNGRADED <<< "$DEPTH_FIELDS" || true
|
|
466
|
+
# <<< always appends a trailing newline to its input; strip it from the last field.
|
|
467
|
+
DEPTH_DOWNGRADED="${DEPTH_DOWNGRADED%$'\n'}"
|
|
468
|
+
|
|
469
|
+
case "$DEPTH_SOURCE" in
|
|
470
|
+
flag) DEPTH_PROVENANCE="from --depth flag" ;;
|
|
471
|
+
rule) DEPTH_PROVENANCE="matched rule ${DEPTH_MATCHED_RULE_INDEX}: ${DEPTH_MATCHED_RULE_PATH}" ;;
|
|
472
|
+
config) DEPTH_PROVENANCE="from workflow.code_review_depth" ;;
|
|
473
|
+
*) DEPTH_PROVENANCE="default" ;;
|
|
474
|
+
esac
|
|
475
|
+
echo "Review depth: ${REVIEW_DEPTH} (${DEPTH_PROVENANCE})"
|
|
476
|
+
|
|
477
|
+
if [ "$DEPTH_INVALID_FLAG" = "true" ]; then
|
|
478
|
+
echo "Warning: Invalid depth '${DEPTH_OVERRIDE}'. Valid values: quick, standard, deep. Using 'standard'."
|
|
479
|
+
fi
|
|
480
|
+
if [ "$DEPTH_INVALID_CONFIG" = "true" ]; then
|
|
481
|
+
echo "Warning: Invalid depth '${CONFIG_DEPTH}'. Valid values: quick, standard, deep. Using 'standard'."
|
|
400
482
|
fi
|
|
483
|
+
|
|
484
|
+
if [ "$DEPTH_DOWNGRADED" = "true" ]; then
|
|
485
|
+
if [ -n "$DEPTH_MATCHED_RULE_INDEX" ]; then
|
|
486
|
+
echo "Switching from deep to standard depth for large file count (overrides matched rule ${DEPTH_MATCHED_RULE_INDEX}: ${DEPTH_MATCHED_RULE_PATH})."
|
|
487
|
+
else
|
|
488
|
+
echo "Switching from deep to standard depth for large file count."
|
|
489
|
+
fi
|
|
490
|
+
fi
|
|
491
|
+
else
|
|
492
|
+
# DEPTH_OK is anything but the literal string "true" — including empty, which is
|
|
493
|
+
# what a crashed or missing resolver produces. workflow.code_review_depth_overrides
|
|
494
|
+
# is misconfigured. Print every collected error — never fall back to a default
|
|
495
|
+
# depth, since silently reviewing a misconfigured sensitive-path policy at
|
|
496
|
+
# `standard` is the exact hole this feature closes — then hard-stop before
|
|
497
|
+
# REVIEW_DEPTH can be read by any later step.
|
|
498
|
+
echo "$DEPTH_JSON" | node -e "
|
|
499
|
+
let parsed;
|
|
500
|
+
try {
|
|
501
|
+
parsed = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf-8'));
|
|
502
|
+
} catch {
|
|
503
|
+
parsed = {};
|
|
504
|
+
}
|
|
505
|
+
const errors = Array.isArray(parsed.errors) ? parsed.errors : [];
|
|
506
|
+
for (const err of errors) {
|
|
507
|
+
const parts = [];
|
|
508
|
+
if (err.ruleIndex !== undefined) parts.push('rule ' + err.ruleIndex);
|
|
509
|
+
if (err.path !== undefined) parts.push('path \"' + err.path + '\"');
|
|
510
|
+
if (err.value !== undefined) parts.push('depth \"' + err.value + '\"');
|
|
511
|
+
console.error('Error: workflow.code_review_depth_overrides' + (parts.length ? ' (' + parts.join(', ') + ')' : '') + ': ' + err.reason);
|
|
512
|
+
}
|
|
513
|
+
"
|
|
514
|
+
echo "Error: Fix workflow.code_review_depth_overrides and retry."
|
|
515
|
+
echo "Error: Depth resolution failed (DEPTH_OK=\"${DEPTH_OK}\"). Halting before agent spawn."
|
|
516
|
+
exit 1
|
|
401
517
|
fi
|
|
402
518
|
```
|
|
519
|
+
This `if`/`else`/`fi` is the entire guard: when `DEPTH_OK` is not the literal string `true`, execution never reaches the `DEPTH_FIELDS`/`REVIEW_DEPTH` extraction — the `else` branch prints the errors, prints the final `Error:` line above, and `exit 1`s out of the fenced block, so `REVIEW_DEPTH` is never set. Exit workflow. Do NOT spawn agent or create REVIEW.md.
|
|
403
520
|
</step>
|
|
404
521
|
|
|
405
522
|
<step name="check_empty_scope">
|
|
@@ -437,22 +554,27 @@ Compute the review output path:
|
|
|
437
554
|
REVIEW_PATH="${PHASE_DIR}/${PADDED_PHASE}-REVIEW.md"
|
|
438
555
|
```
|
|
439
556
|
|
|
440
|
-
Compute DIFF_BASE for agent context (in case agent needs it). #3191/#
|
|
441
|
-
must be the SAME
|
|
442
|
-
the
|
|
557
|
+
Compute DIFF_BASE for agent context (in case agent needs it). #3191/#3995: this
|
|
558
|
+
must be the SAME phase-directory-anchor derivation the Tier-3 scope step uses —
|
|
559
|
+
the reviewer agent consumes `diff_base` exactly
|
|
443
560
|
when `files:` is empty, i.e. the same fail-closed scenario Tier 3 protects, so
|
|
444
561
|
a divergent recomputation here re-arms the mis-scoping one tier down:
|
|
445
562
|
```bash
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
563
|
+
# #3995: a phase number is unique within a MILESTONE, not a repository. The
|
|
564
|
+
# former message grep had no milestone bound, and its tail -1 deliberately
|
|
565
|
+
# selected the OLDEST matching subject — dragging in previous milestones'
|
|
566
|
+
# same-numbered phases and taking a 7-file phase to a 3388-file scope (plus
|
|
567
|
+
# the >50 depth downgrade). The phase's own directory is the unique identity:
|
|
568
|
+
# base = the parent of the first commit that added anything under PHASE_DIR
|
|
569
|
+
# (the same anchor class git-base-branch's phaseStartCommit uses for
|
|
570
|
+
# complexity triggering). Message subjects demonstrably do not carry enough
|
|
571
|
+
# information to identify a phase — this was the grep's fifth failure.
|
|
572
|
+
PHASE_START=$(git log --format="%H" --diff-filter=A -- "${PHASE_DIR}" 2>/dev/null | tail -1)
|
|
573
|
+
if [ -n "$PHASE_START" ]; then
|
|
574
|
+
if git rev-parse "${PHASE_START}^" >/dev/null 2>&1; then
|
|
575
|
+
DIFF_BASE="${PHASE_START}^"
|
|
576
|
+
else
|
|
577
|
+
DIFF_BASE="${PHASE_START}"
|
|
456
578
|
fi
|
|
457
579
|
else
|
|
458
580
|
DIFF_BASE=""
|
|
@@ -610,23 +732,24 @@ TOTAL=$(echo "$FRONTMATTER" | grep "total:" | head -1 | cut -d: -f2 | xargs)
|
|
|
610
732
|
Display inline summary to user:
|
|
611
733
|
|
|
612
734
|
```
|
|
613
|
-
|
|
735
|
+
---
|
|
614
736
|
|
|
615
737
|
Code Review Complete: Phase ${PHASE_NUMBER} (${PHASE_NAME})
|
|
616
738
|
|
|
617
|
-
|
|
739
|
+
---
|
|
618
740
|
|
|
619
|
-
Depth: ${REVIEW_DEPTH}
|
|
741
|
+
Depth: ${REVIEW_DEPTH} (${DEPTH_PROVENANCE})
|
|
620
742
|
Files Reviewed: ${FILES_REVIEWED}
|
|
621
743
|
|
|
622
744
|
Findings:
|
|
623
745
|
Critical: ${CRITICAL}
|
|
624
746
|
Warning: ${WARNING}
|
|
625
747
|
Info: ${INFO}
|
|
626
|
-
|
|
748
|
+
|
|
749
|
+
---
|
|
627
750
|
Total: ${TOTAL}
|
|
628
751
|
|
|
629
|
-
|
|
752
|
+
---
|
|
630
753
|
```
|
|
631
754
|
|
|
632
755
|
If status is "clean":
|
|
@@ -655,7 +778,7 @@ grep -A 3 "^### CR-\|^### BL-\|^### WR-" "${REVIEW_PATH}" | head -n 12
|
|
|
655
778
|
|
|
656
779
|
**Note on tests:** Automated tests for this command and workflow are planned for Phase 4 (Pipeline Integration & Testing, requirement INFR-03). Phase 2 focuses on correct implementation; Phase 4 adds regression coverage across platforms.
|
|
657
780
|
|
|
658
|
-
|
|
781
|
+
---
|
|
659
782
|
</step>
|
|
660
783
|
|
|
661
784
|
</process>
|
|
@@ -675,7 +798,7 @@ If `--files` validation fails unexpectedly on macOS, install coreutils or use ab
|
|
|
675
798
|
|
|
676
799
|
<success_criteria>
|
|
677
800
|
- [ ] Phase validated before config gate check
|
|
678
|
-
- [ ] Capability gate checked (
|
|
801
|
+
- [ ] Capability gate checked (`workflow.code_review` config key)
|
|
679
802
|
- [ ] --fix/--all/--auto flags parsed via code-review-flags.cjs typed IR (not ad-hoc bash)
|
|
680
803
|
- [ ] Depth resolved with validation (quick|standard|deep)
|
|
681
804
|
- [ ] File scope computed with 3 tiers: --files > SUMMARY.md > git diff
|
|
@@ -41,12 +41,12 @@ When a milestone completes:
|
|
|
41
41
|
Before proceeding with milestone close, run the comprehensive open artifact audit.
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
|
-
_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 "$
|
|
45
|
-
RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --default "" 2>/dev/null || echo "")
|
|
44
|
+
_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
|
|
45
|
+
RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --raw --default "" 2>/dev/null || echo "")
|
|
46
46
|
gsd_run query audit-open
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
**If `response_language` is set:** All user-facing questions, prompts, and explanations
|
|
49
|
+
**If `response_language` is set:** All user-facing output of this workflow — narration between tool calls, status updates, progress notes, findings, questions, prompts, and explanations — MUST be presented in `{response_language}`. Technical terms, code, file paths, and subagent prompts stay in English — only user-facing output is translated.
|
|
50
50
|
|
|
51
51
|
If the output contains open items (any section with count > 0):
|
|
52
52
|
|
|
@@ -61,7 +61,7 @@ These items are open. Choose an action:
|
|
|
61
61
|
```
|
|
62
62
|
|
|
63
63
|
If user chooses [A] (Acknowledge):
|
|
64
|
-
1. Re-run `
|
|
64
|
+
1. Re-run `gsd_run query audit-open --json` to get structured data.
|
|
65
65
|
2. Acknowledge every open item through the `audit-open acknowledge` CLI writer — this is what actually suppresses each item starting at the NEXT `audit-open` scan; the STATE.md table in step 3 is a disclosure record only, it is no longer the suppression mechanism. Every acknowledge call's exit status is accumulated (`ACK_FAILURES`); the step HALTS before closing if any failed — a refusal (`unsupported_heading_shape`, `ambiguous`, `not_found`, missing file, etc.) must never be silently discarded and let the close proceed as if everything were suppressed. `AUDIT_JSON` uses the same `@file:` large-payload sentinel handling `INIT_MANAGER` uses in `verify_readiness` below — `io.output` swaps any JSON payload over 50000 chars for a `@file:<path>` marker, and feeding that literal string to `jq` would silently make every loop body below iterate zero times:
|
|
66
66
|
```bash
|
|
67
67
|
AUDIT_JSON=$(gsd_run query audit-open --json)
|
|
@@ -162,8 +162,8 @@ If user chooses [A] (Acknowledge):
|
|
|
162
162
|
exit 1
|
|
163
163
|
fi
|
|
164
164
|
```
|
|
165
|
-
`todos` is the only category the scanner caps (5 entries per scan, with a remainder count for the rest). Re-run `
|
|
166
|
-
3. Re-run `
|
|
165
|
+
`todos` is the only category the scanner caps (5 entries per scan, with a remainder count for the rest). Re-run `gsd_run query audit-open --json` (through the same `@file:` handling above) and repeat the `todos` block until it reports no `todos` items — every other category always returns its full open set in one pass.
|
|
166
|
+
3. Re-run `gsd_run query audit-open --json` once more and write the items just acknowledged as new rows to STATE.md under `## Deferred Items` — append to the existing table (creating the section if absent) rather than overwriting it, preserving rows recorded at earlier milestone closes:
|
|
167
167
|
```markdown
|
|
168
168
|
## Deferred Items
|
|
169
169
|
|
|
@@ -189,7 +189,7 @@ Acknowledging is verdict-preserving and self-invalidating: it never rewrites the
|
|
|
189
189
|
|
|
190
190
|
If output shows all clear (no open items): set `closeout_type=verified_closeout`. If the audit JSON's `acknowledged.total` is `0`, print `All artifact types clear.` and proceed. Otherwise the close is clean only because `{acknowledged.total}` item(s) acknowledged at an earlier milestone close are still being suppressed, not because everything was fixed this time — print `All artifact types clear ({acknowledged.total} previously acknowledged item(s) still suppressed — see STATE.md Deferred Items).` and record `Known verification overrides: 0 newly acknowledged, {acknowledged.total} carried forward from a prior close (see STATE.md Deferred Items)` in the MILESTONES.md entry before proceeding.
|
|
191
191
|
|
|
192
|
-
SECURITY: Audit JSON output is structured data from the `audit-open` query handler (same JSON contract as legacy `
|
|
192
|
+
SECURITY: Audit JSON output is structured data from the `audit-open` query handler (same JSON contract as legacy `gsd_run audit-open`) — validated and sanitized at source. The `audit-open acknowledge` writer is the only path that sets the `audit_acknowledged` suppression marker — it snapshots each artifact's current state itself from the identifiers passed on the command line, so this workflow never hand-authors the marker. When writing the STATE.md disclosure table, item identifiers, statuses, and deferred-item text are sanitized via `sanitizeForDisplay()` before inclusion. Never inject raw user-supplied content into STATE.md without sanitization.
|
|
193
193
|
</step>
|
|
194
194
|
|
|
195
195
|
<step name="verify_readiness">
|
|
@@ -353,7 +353,7 @@ Key accomplishments for this milestone:
|
|
|
353
353
|
|
|
354
354
|
<step name="create_milestone_entry">
|
|
355
355
|
|
|
356
|
-
**Note:** MILESTONES.md entry is now created automatically by `
|
|
356
|
+
**Note:** MILESTONES.md entry is now created automatically by `gsd_run query milestone.complete` in the archive_milestone step. The entry includes version, date, phase/plan/task counts, and accomplishments extracted from SUMMARY.md files.
|
|
357
357
|
|
|
358
358
|
If additional details are needed (e.g., user-provided "Delivered" summary, git range, LOC stats), add them manually after the CLI creates the base entry.
|
|
359
359
|
|
|
@@ -517,12 +517,17 @@ AskUserQuestion: "Archive completed quick tasks into this milestone too?" with o
|
|
|
517
517
|
|
|
518
518
|
If "Yes": set `ARCHIVE_QUICK_FLAG="--archive-quick"`. If "Skip" (or `.planning/quick/` is empty): set `ARCHIVE_QUICK_FLAG=""`.
|
|
519
519
|
|
|
520
|
-
**Delegate archival to `
|
|
520
|
+
**Delegate archival to `gsd_run query milestone.complete`:**
|
|
521
521
|
|
|
522
522
|
```bash
|
|
523
|
-
ARCHIVE=$(gsd_run query milestone.complete "v[X.Y]" --name "[Milestone Name]" $ARCHIVE_QUICK_FLAG)
|
|
523
|
+
ARCHIVE=$(gsd_run query milestone.complete "v[X.Y]" --name "[Milestone Name]" --confirm $ARCHIVE_QUICK_FLAG)
|
|
524
524
|
```
|
|
525
525
|
|
|
526
|
+
`--confirm` is required (#3726): the archive is irreversible (ROADMAP/REQUIREMENTS archived, phase
|
|
527
|
+
directories MOVED, STATE.md rewritten), so `milestone complete` refuses to mutate without it. This
|
|
528
|
+
workflow has already gathered the user's explicit intent by this step, so passing the flag here is
|
|
529
|
+
correct; `--dry-run` previews the exact move list without mutating if a preview is ever needed first.
|
|
530
|
+
|
|
526
531
|
The CLI handles:
|
|
527
532
|
- Creating `.planning/milestones/` directory
|
|
528
533
|
- Archiving ROADMAP.md to `milestones/v[X.Y]-ROADMAP.md`
|
|
@@ -545,7 +550,7 @@ Verify after `--archive-quick` was passed: `✅ Quick tasks archived to .plannin
|
|
|
545
550
|
If the user explicitly wants to keep phase directories in place as raw execution history, invoke `milestone complete` with `--no-archive-phases`:
|
|
546
551
|
|
|
547
552
|
```bash
|
|
548
|
-
gsd_run query milestone complete v[X.Y] --no-archive-phases
|
|
553
|
+
gsd_run query milestone complete v[X.Y] --no-archive-phases --confirm
|
|
549
554
|
```
|
|
550
555
|
|
|
551
556
|
Verify after a default (archived) completion: `✅ Phase directories archived to .planning/milestones/v[X.Y]-phases/`
|
|
@@ -770,7 +775,10 @@ CURRENT_BRANCH=$(git branch --show-current)
|
|
|
770
775
|
git checkout ${BASE_BRANCH}
|
|
771
776
|
|
|
772
777
|
if [ "$BRANCHING_STRATEGY" = "phase" ]; then
|
|
773
|
-
|
|
778
|
+
# Rewrapped through unquoted command substitution (gsd-core#4109): a bare
|
|
779
|
+
# `$VAR` word-splits under bash but not zsh, collapsing every element onto
|
|
780
|
+
# one iteration there.
|
|
781
|
+
for branch in $(printf '%s' "$PHASE_BRANCHES"); do
|
|
774
782
|
git merge --squash "$branch"
|
|
775
783
|
# Strip .planning/ from staging if commit_docs is false
|
|
776
784
|
if [ "$COMMIT_DOCS" = "false" ]; then
|
|
@@ -799,7 +807,10 @@ CURRENT_BRANCH=$(git branch --show-current)
|
|
|
799
807
|
git checkout ${BASE_BRANCH}
|
|
800
808
|
|
|
801
809
|
if [ "$BRANCHING_STRATEGY" = "phase" ]; then
|
|
802
|
-
|
|
810
|
+
# Rewrapped through unquoted command substitution (gsd-core#4109): a bare
|
|
811
|
+
# `$VAR` word-splits under bash but not zsh, collapsing every element onto
|
|
812
|
+
# one iteration there.
|
|
813
|
+
for branch in $(printf '%s' "$PHASE_BRANCHES"); do
|
|
803
814
|
git merge --no-ff --no-commit "$branch"
|
|
804
815
|
# Strip .planning/ from staging if commit_docs is false
|
|
805
816
|
if [ "$COMMIT_DOCS" = "false" ]; then
|
|
@@ -825,7 +836,10 @@ git checkout "$CURRENT_BRANCH"
|
|
|
825
836
|
|
|
826
837
|
```bash
|
|
827
838
|
if [ "$BRANCHING_STRATEGY" = "phase" ]; then
|
|
828
|
-
|
|
839
|
+
# Rewrapped through unquoted command substitution (gsd-core#4109): a bare
|
|
840
|
+
# `$VAR` word-splits under bash but not zsh, collapsing every element onto
|
|
841
|
+
# one iteration there.
|
|
842
|
+
for branch in $(printf '%s' "$PHASE_BRANCHES"); do
|
|
829
843
|
git branch -d "$branch" 2>/dev/null || git branch -D "$branch"
|
|
830
844
|
done
|
|
831
845
|
fi
|
|
@@ -16,7 +16,7 @@ Valid GSD subagent types (use exact names — do not fall back to 'general-purpo
|
|
|
16
16
|
## 0. Initialize Context
|
|
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 "$
|
|
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
20
|
INIT=$(gsd_run query init.debug)
|
|
21
21
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
22
22
|
```
|
|
@@ -30,7 +30,7 @@ One round-trip carries everything this workflow needs (#3149 — this call repla
|
|
|
30
30
|
- `tdd_mode` — used as `{TDD_MODE}` in the session parameter blocks below.
|
|
31
31
|
- `section_manifest` — `null` today, because this workflow declares no applicability-section markers of its own. **When it is `null`, read this workflow in full.** When it is present, read only the files named in its `read` array. `null` and an empty `included` array are NOT the same: `null` means "no manifest for this workflow", an empty `included` means "nothing applies".
|
|
32
32
|
|
|
33
|
-
**If `response_language` is set:** All user-facing questions, prompts, and explanations
|
|
33
|
+
**If `response_language` is set:** All user-facing output of this workflow — narration between tool calls, status updates, progress notes, findings, questions, prompts, and explanations — MUST be presented in `{response_language}`. Technical terms, code, file paths, and subagent prompts stay in English — only user-facing output is translated.
|
|
34
34
|
|
|
35
35
|
## 1a. LIST subcommand
|
|
36
36
|
|
|
@@ -44,7 +44,8 @@ For each file found, parse frontmatter fields (`status`, `trigger`, `updated`) a
|
|
|
44
44
|
|
|
45
45
|
```
|
|
46
46
|
Active Debug Sessions
|
|
47
|
-
|
|
47
|
+
|
|
48
|
+
---
|
|
48
49
|
# Slug Status Updated
|
|
49
50
|
1 auth-token-null investigating 2026-04-12
|
|
50
51
|
hypothesis: JWT decode fails when token contains nested claims
|
|
@@ -53,7 +54,8 @@ Active Debug Sessions
|
|
|
53
54
|
2 form-submit-500 fixing 2026-04-11
|
|
54
55
|
hypothesis: Missing null check on req.body.user
|
|
55
56
|
next: Verify fix passes regression test
|
|
56
|
-
|
|
57
|
+
|
|
58
|
+
---
|
|
57
59
|
Run `/gsd:debug continue <slug>` to resume a session.
|
|
58
60
|
No sessions? `/gsd:debug <description>` to start.
|
|
59
61
|
```
|