@opengsd/gsd-core 1.12.0 → 1.14.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-advisor-researcher.compact.md +85 -0
- package/agents/gsd-ai-researcher.compact.md +96 -0
- package/agents/gsd-assumptions-analyzer.compact.md +81 -0
- package/agents/gsd-code-fixer.compact.md +458 -0
- package/agents/gsd-code-fixer.md +5 -5
- package/agents/gsd-code-reviewer.compact.md +269 -0
- package/agents/gsd-code-reviewer.md +15 -3
- package/agents/gsd-codebase-mapper.compact.md +760 -0
- package/agents/gsd-debug-session-manager.compact.md +345 -0
- package/agents/gsd-doc-classifier.compact.md +192 -0
- package/agents/gsd-doc-synthesizer.compact.md +200 -0
- package/agents/gsd-doc-verifier.compact.md +143 -0
- package/agents/gsd-doc-writer.compact.md +440 -0
- package/agents/gsd-dom-verifier.compact.md +138 -0
- package/agents/gsd-domain-researcher.compact.md +141 -0
- package/agents/gsd-eval-auditor.compact.md +160 -0
- package/agents/gsd-eval-planner.compact.md +137 -0
- package/agents/gsd-executor.md +63 -35
- package/agents/gsd-framework-selector.compact.md +82 -0
- package/agents/gsd-integration-checker.compact.md +245 -0
- package/agents/gsd-intel-updater.compact.md +226 -0
- package/agents/gsd-mempalace-curator.compact.md +45 -0
- package/agents/gsd-nyquist-auditor.compact.md +179 -0
- package/agents/gsd-pattern-mapper.compact.md +275 -0
- package/agents/gsd-plan-checker.md +76 -57
- package/agents/gsd-planner.md +14 -0
- package/agents/gsd-project-researcher.compact.md +587 -0
- package/agents/gsd-research-synthesizer.compact.md +212 -0
- package/agents/gsd-roadmapper.compact.md +454 -0
- package/agents/gsd-roadmapper.md +13 -0
- package/agents/gsd-security-auditor.compact.md +162 -0
- package/agents/gsd-ui-auditor.compact.md +404 -0
- package/agents/gsd-ui-checker.compact.md +277 -0
- package/agents/gsd-ui-checker.md +19 -3
- package/agents/gsd-ui-researcher.compact.md +282 -0
- package/agents/gsd-ui-researcher.md +29 -0
- package/agents/gsd-user-profiler.compact.md +108 -0
- package/agents/gsd-verifier.md +23 -1
- package/bin/install.js +444 -134
- package/commands/gsd/cleanup.md +1 -0
- package/commands/gsd/code-review.md +2 -1
- package/commands/gsd/complete-milestone.md +1 -0
- package/commands/gsd/config.md +1 -0
- package/commands/gsd/debug.md +1 -0
- package/commands/gsd/execute-phase.md +1 -1
- package/commands/gsd/graphify.md +1 -0
- package/commands/gsd/health.md +1 -0
- package/commands/gsd/mempalace-capture.md +1 -0
- package/commands/gsd/mempalace-recall.md +1 -0
- package/commands/gsd/new-milestone.md +1 -0
- package/commands/gsd/new-project.md +1 -0
- package/commands/gsd/next.md +1 -0
- package/commands/gsd/ns-workflow.md +2 -1
- package/commands/gsd/pause-work.md +1 -0
- package/commands/gsd/phase.md +2 -1
- package/commands/gsd/pr-branch.md +1 -0
- package/commands/gsd/quick-batch.md +105 -0
- package/commands/gsd/resume-work.md +1 -0
- package/commands/gsd/review-backlog.md +1 -0
- package/commands/gsd/settings.md +2 -1
- package/commands/gsd/stats.md +1 -0
- package/commands/gsd/surface.md +18 -8
- package/commands/gsd/thread.md +1 -0
- package/commands/gsd/workspace.md +1 -0
- package/commands/gsd/workstreams.md +1 -0
- package/gsd-core/bin/check-latest-version.cjs +8 -3
- package/gsd-core/bin/gsd-tools.cjs +532 -174
- package/gsd-core/bin/lib/adr-parser.cjs +1 -1
- package/gsd-core/bin/lib/artifacts.cjs +2 -1
- package/gsd-core/bin/lib/audit.cjs +39 -22
- package/gsd-core/bin/lib/broken-windows.cjs +168 -49
- package/gsd-core/bin/lib/capability-activation.cjs +27 -0
- package/gsd-core/bin/lib/capability-lifecycle.cjs +10 -6
- package/gsd-core/bin/lib/capability-loader.cjs +135 -1
- package/gsd-core/bin/lib/capability-registry.cjs +528 -116
- package/gsd-core/bin/lib/capability-source.cjs +19 -2
- package/gsd-core/bin/lib/capability-state.cjs +7 -1
- package/gsd-core/bin/lib/capability-validator.cjs +134 -5
- package/gsd-core/bin/lib/capability-writer.cjs +14 -4
- package/gsd-core/bin/lib/check-command-router.cjs +198 -38
- package/gsd-core/bin/lib/claude-orchestration.cjs +10 -25
- package/gsd-core/bin/lib/clusters.cjs +1 -0
- package/gsd-core/bin/lib/code-review-depth.cjs +2 -2
- package/gsd-core/bin/lib/command-aliases.cjs +16 -0
- package/gsd-core/bin/lib/commands.cjs +981 -79
- package/gsd-core/bin/lib/config-loader.cjs +4 -0
- package/gsd-core/bin/lib/config.cjs +153 -38
- package/gsd-core/bin/lib/core-utils.cjs +34 -7
- package/gsd-core/bin/lib/coverage.cjs +1 -1
- package/gsd-core/bin/lib/decisions.cjs +343 -28
- package/gsd-core/bin/lib/edge-probe.cjs +14 -1
- package/gsd-core/bin/lib/external-descriptor-trust.cjs +29 -14
- package/gsd-core/bin/lib/file-overlap-partitioner.cjs +74 -0
- package/gsd-core/bin/lib/frontmatter.cjs +137 -23
- package/gsd-core/bin/lib/gap-checker.cjs +22 -13
- package/gsd-core/bin/lib/git-base-branch.cjs +10 -2
- package/gsd-core/bin/lib/gsd2-import.cjs +1 -2
- 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 +54 -11
- package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +87 -23
- package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +1 -1
- package/gsd-core/bin/lib/host-integration.cjs +57 -5
- package/gsd-core/bin/lib/init-command-router.cjs +14 -0
- package/gsd-core/bin/lib/init.cjs +539 -60
- package/gsd-core/bin/lib/install-engine.cjs +199 -14
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +45 -0
- package/gsd-core/bin/lib/install-profiles.cjs +36 -14
- package/gsd-core/bin/lib/installer-migration-report.cjs +1 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +33 -4
- package/gsd-core/bin/lib/io.cjs +35 -0
- package/gsd-core/bin/lib/loop-resolver.cjs +64 -39
- package/gsd-core/bin/lib/markdown-table.cjs +123 -0
- package/gsd-core/bin/lib/mcp-catalog.cjs +2 -2
- package/gsd-core/bin/lib/milestone.cjs +41 -10
- package/gsd-core/bin/lib/model-resolver.cjs +101 -10
- package/gsd-core/bin/lib/phase-command-router.cjs +20 -7
- package/gsd-core/bin/lib/phase-id.cjs +412 -31
- package/gsd-core/bin/lib/phase-lifecycle.cjs +61 -0
- package/gsd-core/bin/lib/phase.cjs +941 -98
- package/gsd-core/bin/lib/plan-document.cjs +10 -0
- package/gsd-core/bin/lib/planning-inspect.cjs +34 -18
- package/gsd-core/bin/lib/planning-snapshot.cjs +206 -30
- package/gsd-core/bin/lib/planning-workspace.cjs +153 -29
- package/gsd-core/bin/lib/pristine-baseline.cjs +182 -0
- package/gsd-core/bin/lib/prohibition-enforcement.cjs +91 -4
- 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/refactor-trigger-command-router.cjs +61 -2
- package/gsd-core/bin/lib/research-store.cjs +11 -12
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +53 -5
- package/gsd-core/bin/lib/review-lane-invocation.cjs +96 -1
- package/gsd-core/bin/lib/review-lane-runner.cjs +136 -10
- package/gsd-core/bin/lib/reviewer-step-dispatch.cjs +337 -0
- package/gsd-core/bin/lib/roadmap-parser.cjs +555 -41
- package/gsd-core/bin/lib/roadmap.cjs +292 -69
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +260 -43
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +28 -20
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +294 -108
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +408 -47
- package/gsd-core/bin/lib/security.cjs +126 -7
- package/gsd-core/bin/lib/shell-command-projection.cjs +4 -0
- package/gsd-core/bin/lib/smart-entry.cjs +7 -9
- package/gsd-core/bin/lib/state-document.cjs +159 -32
- package/gsd-core/bin/lib/state-md-schema.cjs +44 -27
- package/gsd-core/bin/lib/state-transition.cjs +465 -62
- package/gsd-core/bin/lib/state.cjs +906 -151
- package/gsd-core/bin/lib/surface.cjs +83 -10
- package/gsd-core/bin/lib/task-command-router.cjs +12 -6
- package/gsd-core/bin/lib/tdd-red-evidence.cjs +133 -0
- package/gsd-core/bin/lib/uat.cjs +1420 -516
- package/gsd-core/bin/lib/update-context.cjs +36 -26
- package/gsd-core/bin/lib/validate.cjs +230 -12
- package/gsd-core/bin/lib/vendor/js-yaml.cjs +11 -3
- package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +316 -23
- package/gsd-core/bin/lib/verify-command-grounding.cjs +1 -1
- package/gsd-core/bin/lib/verify-command-router.cjs +1 -0
- package/gsd-core/bin/lib/verify.cjs +531 -36
- package/gsd-core/bin/lib/workstream-inventory.cjs +21 -2
- package/gsd-core/bin/lib/worktree-safety.cjs +21 -7
- package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +13 -0
- package/gsd-core/bin/verify-reapply-patches.cjs +507 -81
- package/gsd-core/references/agent-contracts.md +3 -3
- package/gsd-core/references/compact-content-gate.md +66 -0
- package/gsd-core/references/edge-probe.md +17 -13
- package/gsd-core/references/execute-mvp-tdd.md +18 -16
- package/gsd-core/references/execute-phase-response-language.md +6 -0
- package/gsd-core/references/executor-examples.md +42 -0
- package/gsd-core/references/few-shot-examples/plan-checker.md +15 -15
- package/gsd-core/references/loop-hook-dispatch.md +18 -0
- package/gsd-core/references/model-profiles.md +12 -3
- package/gsd-core/references/mvp-concepts.md +2 -2
- 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-quick-batch.md +71 -0
- package/gsd-core/references/planner-reviews.md +47 -0
- package/gsd-core/references/planner-revision.md +75 -2
- package/gsd-core/references/planning-config.md +5 -1
- package/gsd-core/references/response-language-directive.md +9 -0
- package/gsd-core/references/revision-loop.md +118 -11
- package/gsd-core/references/tdd.md +17 -9
- package/gsd-core/references/thinking-models-planning.md +18 -2
- package/gsd-core/references/verification-patterns.md +17 -4
- package/gsd-core/references/verifier-evidence-gate.md +160 -0
- package/gsd-core/references/worktree-path-safety.md +112 -2
- package/gsd-core/templates/README.md +7 -1
- package/gsd-core/templates/phase-prompt.md +4 -0
- package/gsd-core/templates/state.md +6 -3
- package/gsd-core/templates/summary.compact.md +212 -0
- package/gsd-core/templates/user-setup.compact.md +199 -0
- package/gsd-core/templates/user-setup.md +0 -9
- package/gsd-core/templates/verification-report.md +5 -0
- package/gsd-core/workflows/add-backlog.md +2 -0
- package/gsd-core/workflows/add-phase.md +2 -0
- package/gsd-core/workflows/add-tests.md +1 -1
- package/gsd-core/workflows/add-todo.md +4 -3
- package/gsd-core/workflows/ai-integration-phase.md +1 -1
- package/gsd-core/workflows/analyze-dependencies.md +2 -0
- package/gsd-core/workflows/audit-fix.md +2 -0
- package/gsd-core/workflows/audit-milestone.md +2 -0
- package/gsd-core/workflows/audit-uat.md +2 -0
- package/gsd-core/workflows/autonomous.md +15 -10
- package/gsd-core/workflows/check-todos.md +5 -3
- package/gsd-core/workflows/cleanup.md +4 -2
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +22 -13
- package/gsd-core/workflows/code-review-fix.md +5 -3
- package/gsd-core/workflows/code-review.md +211 -43
- package/gsd-core/workflows/complete-milestone/detail/elaboration.md +274 -0
- package/gsd-core/workflows/complete-milestone.md +40 -254
- package/gsd-core/workflows/debug.md +1 -1
- package/gsd-core/workflows/diagnose-issues.md +5 -1
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +2 -0
- 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 +2 -0
- 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 +2 -0
- 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.md +1 -1
- package/gsd-core/workflows/discuss-phase-power.md +2 -0
- package/gsd-core/workflows/discuss-phase.md +1 -1
- package/gsd-core/workflows/do.md +43 -13
- package/gsd-core/workflows/docs-update/detail/elaboration.md +179 -0
- package/gsd-core/workflows/docs-update.md +15 -156
- package/gsd-core/workflows/edit-phase.md +2 -0
- package/gsd-core/workflows/eval-review.md +1 -1
- package/gsd-core/workflows/execute-phase/detail/elaboration.md +124 -0
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +20 -3
- package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +56 -0
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +24 -3
- package/gsd-core/workflows/execute-phase/steps/executor-progress-policy.md +43 -0
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +8 -2
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +2 -0
- package/gsd-core/workflows/execute-phase/steps/sequential-root-pin.md +35 -0
- package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +25 -0
- package/gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md +2 -0
- package/gsd-core/workflows/execute-phase.md +78 -159
- package/gsd-core/workflows/execute-plan.md +28 -15
- package/gsd-core/workflows/explore.md +2 -0
- package/gsd-core/workflows/extract-learnings.md +2 -0
- package/gsd-core/workflows/fast.md +6 -0
- package/gsd-core/workflows/forensics.md +2 -0
- package/gsd-core/workflows/graduation.md +1 -1
- package/gsd-core/workflows/health.md +1 -1
- 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.compact.md +398 -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 +3 -1
- package/gsd-core/workflows/import.md +3 -3
- package/gsd-core/workflows/inbox.md +1 -1
- package/gsd-core/workflows/ingest-docs.md +1 -1
- package/gsd-core/workflows/insert-phase.md +2 -0
- package/gsd-core/workflows/list-phase-assumptions.md +2 -0
- package/gsd-core/workflows/list-seeds.md +2 -0
- package/gsd-core/workflows/list-workspaces.md +2 -0
- package/gsd-core/workflows/manager.md +3 -3
- package/gsd-core/workflows/map-codebase.md +52 -3
- package/gsd-core/workflows/milestone-summary.md +2 -0
- package/gsd-core/workflows/mvp-phase.md +1 -1
- package/gsd-core/workflows/new-milestone.md +55 -13
- package/gsd-core/workflows/new-project/detail/elaboration.md +216 -0
- package/gsd-core/workflows/new-project.md +37 -205
- package/gsd-core/workflows/new-workspace.md +1 -1
- package/gsd-core/workflows/next.md +2 -0
- 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 +19 -4
- package/gsd-core/workflows/plan-phase/detail/elaboration.md +209 -0
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +100 -18
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +2 -0
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +9 -0
- package/gsd-core/workflows/plan-phase.md +144 -185
- package/gsd-core/workflows/plan-review-convergence.md +102 -10
- package/gsd-core/workflows/plant-seed.md +1 -1
- package/gsd-core/workflows/pr-branch.md +30 -10
- package/gsd-core/workflows/profile-user.md +1 -1
- package/gsd-core/workflows/progress/steps/forensic-audit.md +1 -1
- package/gsd-core/workflows/progress.md +25 -3
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +37 -2
- package/gsd-core/workflows/quick/steps/research-phase.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 +21 -4
- package/gsd-core/workflows/reapply-patches.md +79 -3
- package/gsd-core/workflows/remove-phase.md +2 -0
- package/gsd-core/workflows/remove-workspace.md +1 -1
- package/gsd-core/workflows/resume-project.md +6 -2
- package/gsd-core/workflows/review.md +215 -10
- package/gsd-core/workflows/scan.md +2 -0
- package/gsd-core/workflows/section-manifest.json +12 -0
- package/gsd-core/workflows/secure-phase.md +1 -1
- package/gsd-core/workflows/session-report.md +2 -0
- package/gsd-core/workflows/settings-advanced.md +2 -0
- package/gsd-core/workflows/settings-integrations.md +9 -8
- package/gsd-core/workflows/settings.md +19 -6
- package/gsd-core/workflows/ship.md +10 -10
- package/gsd-core/workflows/sketch-wrap-up.md +2 -0
- package/gsd-core/workflows/sketch.md +1 -1
- package/gsd-core/workflows/smart-entry.md +1 -1
- package/gsd-core/workflows/spec-phase.md +24 -19
- package/gsd-core/workflows/spike-wrap-up.md +2 -0
- package/gsd-core/workflows/spike.md +1 -1
- package/gsd-core/workflows/stats.md +2 -0
- package/gsd-core/workflows/sync-skills.md +12 -4
- package/gsd-core/workflows/thread.md +2 -0
- package/gsd-core/workflows/transition.md +2 -0
- package/gsd-core/workflows/ui-phase.md +26 -5
- package/gsd-core/workflows/ui-review.md +1 -1
- package/gsd-core/workflows/ultraplan-phase.md +2 -0
- package/gsd-core/workflows/undo.md +1 -1
- package/gsd-core/workflows/update.md +48 -43
- package/gsd-core/workflows/validate-phase.md +1 -1
- package/gsd-core/workflows/verify-work/detail/elaboration.md +230 -0
- package/gsd-core/workflows/verify-work.md +68 -182
- package/hooks/dist/gsd-agent-isolation-guard.js +42 -16
- package/hooks/dist/gsd-check-update-worker.js +19 -2
- package/hooks/dist/gsd-context-monitor.js +371 -27
- package/hooks/dist/gsd-cursor-subagent-start.js +34 -14
- package/hooks/dist/gsd-node-runner.sh +1 -0
- package/hooks/dist/gsd-prompt-guard.js +30 -5
- package/hooks/dist/gsd-read-guard.js +2 -0
- package/hooks/dist/gsd-read-injection-scanner.js +5 -5
- package/hooks/dist/gsd-secret-read-guard.js +1105 -0
- package/hooks/dist/gsd-statusline.js +18 -10
- package/hooks/dist/gsd-validate-commit.sh +474 -7
- package/hooks/dist/gsd-workflow-guard.js +2 -1
- package/hooks/dist/gsd-worktree-path-guard.js +25 -14
- package/hooks/dist/gsd-write-guard.js +46 -1
- package/hooks/dist/lib/dispatch-identity.js +187 -0
- package/hooks/dist/lib/filename-classification.js +64 -0
- package/hooks/dist/lib/git-cmd.js +210 -1
- package/hooks/dist/lib/injection-patterns.js +36 -6
- package/hooks/dist/lib/isolation-deny-reason.js +53 -1
- package/hooks/dist/lib/isolation-sentinel.js +58 -19
- package/hooks/dist/managed-hooks-registry.cjs +1 -0
- package/hooks/gsd-agent-isolation-guard.js +42 -16
- package/hooks/gsd-check-update-worker.js +19 -2
- package/hooks/gsd-context-monitor.js +371 -27
- package/hooks/gsd-cursor-subagent-start.js +34 -14
- package/hooks/gsd-node-runner.sh +1 -0
- package/hooks/gsd-prompt-guard.js +30 -5
- package/hooks/gsd-read-guard.js +2 -0
- package/hooks/gsd-read-injection-scanner.js +5 -5
- package/hooks/gsd-secret-read-guard.js +1105 -0
- package/hooks/gsd-statusline.js +18 -10
- package/hooks/gsd-validate-commit.sh +474 -7
- package/hooks/gsd-workflow-guard.js +2 -1
- package/hooks/gsd-worktree-path-guard.js +25 -14
- package/hooks/gsd-write-guard.js +46 -1
- package/hooks/hooks.json +6 -0
- package/hooks/lib/dispatch-identity.js +187 -0
- package/hooks/lib/filename-classification.js +64 -0
- package/hooks/lib/git-cmd.js +210 -1
- package/hooks/lib/injection-patterns.js +36 -6
- package/hooks/lib/isolation-deny-reason.js +53 -1
- package/hooks/lib/isolation-sentinel.js +58 -19
- package/hooks/managed-hooks-registry.cjs +1 -0
- package/package.json +13 -9
- package/scripts/benchmark-compact-content-variants.cjs +298 -0
- package/scripts/benchmark-compact-content.cjs +368 -0
- package/scripts/build-hooks.js +11 -4
- package/scripts/check-contract-drift.cjs +4 -1
- package/scripts/check-env.cjs +36 -8
- package/scripts/check-glossary-refs.cjs +25 -21
- package/scripts/ci-next-health.cjs +271 -0
- package/scripts/ci-prepare-test-scope.cjs +7 -7
- package/scripts/ci-test-scope.cjs +133 -20
- package/scripts/ci-timeout-report.cjs +1 -1
- package/scripts/diff-touches-shipped-paths.cjs +1 -1
- package/scripts/docs-guard-registry.cjs +17 -2
- package/scripts/gen-adr-index.cjs +8 -2
- package/scripts/gen-inventory-manifest.cjs +12 -0
- package/scripts/gen-loop-host-contract.cjs +67 -15
- package/scripts/gen-platform-conformance-tier.cjs +557 -0
- package/scripts/lib/drift-scan.cjs +1 -1
- package/scripts/lib/macos-conformance-tier.generated.cjs +210 -0
- package/scripts/lib/npm-version-check-diagnosis.cjs +59 -0
- package/scripts/lib/platform-conformance-tier.generated.cjs +276 -0
- package/scripts/lib/shellcheck-fetch.cjs +247 -0
- package/scripts/lib/suite-detection.cjs +32 -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-allowed-tools-parity.cjs +221 -0
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +24 -2
- package/scripts/lint-phase-enumeration-drift.cjs +24 -6
- package/scripts/lint-phase-id-drift.cjs +465 -15
- package/scripts/lint-portable-grep.cjs +176 -0
- package/scripts/lint-response-language-coverage.cjs +530 -0
- package/scripts/lint-source-test-name-collision.cjs +1 -1
- package/scripts/lint-test-file-count.allowlist.json +4 -1
- package/scripts/lint-vendored-deps.cjs +128 -17
- package/scripts/lint-workflow-shellcheck-baseline.json +1112 -0
- package/scripts/lint-workflow-shellcheck.cjs +614 -0
- package/scripts/npm-audit-baseline.cjs +376 -0
- package/scripts/prompt-injection-scan.sh +22 -0
- package/scripts/require-issue-link-policy.cjs +16 -1
- package/scripts/workflow-size.cjs +139 -0
- package/skills/gsd-cleanup/SKILL.md +1 -0
- package/skills/gsd-code-review/SKILL.md +2 -1
- package/skills/gsd-complete-milestone/SKILL.md +1 -0
- package/skills/gsd-config/SKILL.md +1 -0
- package/skills/gsd-debug/SKILL.md +1 -0
- package/skills/gsd-execute-phase/SKILL.md +1 -1
- package/skills/gsd-graphify/SKILL.md +1 -0
- package/skills/gsd-health/SKILL.md +1 -0
- package/skills/gsd-mempalace-capture/SKILL.md +1 -0
- package/skills/gsd-mempalace-recall/SKILL.md +1 -0
- package/skills/gsd-new-milestone/SKILL.md +1 -0
- package/skills/gsd-new-project/SKILL.md +1 -0
- package/skills/gsd-next/SKILL.md +1 -0
- package/skills/gsd-ns-workflow/SKILL.md +1 -0
- package/skills/gsd-pause-work/SKILL.md +1 -0
- package/skills/gsd-phase/SKILL.md +2 -1
- package/skills/gsd-pr-branch/SKILL.md +1 -0
- package/skills/gsd-quick-batch/SKILL.md +105 -0
- package/skills/gsd-resume-work/SKILL.md +1 -0
- package/skills/gsd-review-backlog/SKILL.md +1 -0
- package/skills/gsd-settings/SKILL.md +2 -1
- package/skills/gsd-stats/SKILL.md +1 -0
- package/skills/gsd-surface/SKILL.md +18 -8
- package/skills/gsd-thread/SKILL.md +1 -0
- package/skills/gsd-workspace/SKILL.md +1 -0
- package/skills/gsd-workstreams/SKILL.md +1 -0
- package/vscode/package.json +1 -1
- package/gsd-core/templates/claude-md.md +0 -145
- package/gsd-core/templates/codebase/concerns.md +0 -310
- package/gsd-core/templates/codebase/conventions.md +0 -307
- package/gsd-core/templates/codebase/integrations.md +0 -280
- package/gsd-core/templates/codebase/structure.md +0 -285
- package/gsd-core/templates/codebase/testing.md +0 -480
- package/gsd-core/templates/debug-subagent-prompt.md +0 -91
- package/gsd-core/templates/discovery.md +0 -146
|
@@ -119,7 +119,7 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
|
119
119
|
|
|
120
120
|
Parse JSON for: `phase_dir`, `phase_number`, `padded_phase`, `phase_name`, `has_plans`, `plan_count`, `commit_docs`, `text_mode`, `response_language`.
|
|
121
121
|
|
|
122
|
-
**If `response_language` is set:** All user-facing output should be in `{response_language}`.
|
|
122
|
+
**If `response_language` is set:** All user-facing output — narration between tool calls, status updates, progress notes, findings, questions, and report prose — should be in `{response_language}`.
|
|
123
123
|
|
|
124
124
|
Set `TEXT_MODE=true` if `--text` is present in $ARGUMENTS OR `text_mode` from init JSON is `true`. When `TEXT_MODE` is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number.
|
|
125
125
|
|
|
@@ -341,13 +341,20 @@ Run this pass whenever the source-grounding pass ran — it is the second axis o
|
|
|
341
341
|
|
|
342
342
|
**Coverage, never silence.** If STATE.md or CONTEXT.md is absent, that axis is skipped and the skip is recorded in the same "Verification coverage" block. A clean pass must never mean "nothing was compared."
|
|
343
343
|
|
|
344
|
-
After agent returns, verify REVIEWS.md exists
|
|
344
|
+
After agent returns, verify REVIEWS.md exists. Assign the path directly and quote it — an unquoted
|
|
345
|
+
`${phase_dir}` inside `$(ls …)` word-splits and glob-expands, and a discarded stderr hides it (#3899):
|
|
345
346
|
```bash
|
|
346
|
-
|
|
347
|
+
if [ -z "${phase_dir}" ]; then
|
|
348
|
+
echo "ERROR: phase_dir is empty — cannot resolve the expected REVIEWS.md path." >&2
|
|
349
|
+
exit 1
|
|
350
|
+
fi
|
|
351
|
+
REVIEWS_FILE="${phase_dir}/${padded_phase}-REVIEWS.md"
|
|
352
|
+
if [ ! -f "${REVIEWS_FILE}" ] || [ ! -r "${REVIEWS_FILE}" ]; then
|
|
353
|
+
echo "ERROR: expected reviews file is not a readable file: '${REVIEWS_FILE}'. Confirm the phase directory resolved correctly before concluding the review agent produced nothing." >&2
|
|
354
|
+
exit 1
|
|
355
|
+
fi
|
|
347
356
|
```
|
|
348
357
|
|
|
349
|
-
If REVIEWS_FILE is empty: Error — review agent did not produce REVIEWS.md. Exit.
|
|
350
|
-
|
|
351
358
|
### 5b. Extract unresolved counts from CYCLE_SUMMARY Contract
|
|
352
359
|
|
|
353
360
|
**Do NOT grep REVIEWS.md for HIGH or actionable counts.** REVIEWS.md accumulates history across cycles — resolved findings from prior cycles remain in the file as audit trail, inflating a raw grep count and causing false stall detection.
|
|
@@ -390,7 +397,68 @@ if [ "${ACTIONABLE_COUNT}" -gt 0 ] && [ -z "${ACTIONABLE_LINES}" ]; then
|
|
|
390
397
|
fi
|
|
391
398
|
```
|
|
392
399
|
|
|
393
|
-
**
|
|
400
|
+
**Open plan-revision conflicts are part of the converged condition (#3771).** An entry under
|
|
401
|
+
`## Plan-Revision Conflicts` in REVIEWS.md is a checker `fix_hint` that contradicted a locked
|
|
402
|
+
decision, capability guidance, or an existing plan constraint, recorded by `/gsd:plan-phase`
|
|
403
|
+
together with the alternatives the planner considered. It is NOT counted by `CYCLE_SUMMARY`, so
|
|
404
|
+
it must be read from the file directly — evaluate this BEFORE the converged branch below, or a
|
|
405
|
+
run would write `planned-phase` and print the success banner over a conflict nobody resolved:
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
if [ ! -f "${REVIEWS_FILE}" ]; then
|
|
409
|
+
# Fail CLOSED. A missing/non-file REVIEWS.md is "I cannot tell", never "no conflicts".
|
|
410
|
+
echo "BLOCKED: cannot read REVIEWS.md ('${REVIEWS_FILE}') to check for open plan-revision conflicts. Refusing to declare convergence on an unverifiable gate." >&2
|
|
411
|
+
exit 1
|
|
412
|
+
fi
|
|
413
|
+
if OPEN_CONFLICTS=$(awk '
|
|
414
|
+
BEGIN { saw_title = 0; in_owned = 0; saw_heading = 0; done = 0; count = 0 }
|
|
415
|
+
{ sub(/\r$/, "") }
|
|
416
|
+
!saw_title && /^# Cross-AI Plan Review — Phase / { saw_title = 1; next }
|
|
417
|
+
saw_title && !in_owned && !done {
|
|
418
|
+
if ($0 == "") next
|
|
419
|
+
if ($0 == "<!-- gsd:plan-revision-conflicts:begin -->") { in_owned = 1; next }
|
|
420
|
+
exit 2
|
|
421
|
+
}
|
|
422
|
+
in_owned && $0 == "<!-- gsd:plan-revision-conflicts:begin -->" { exit 2 }
|
|
423
|
+
in_owned && !saw_heading && $0 == "" { next }
|
|
424
|
+
in_owned && !saw_heading && $0 == "## Plan-Revision Conflicts" { saw_heading = 1; next }
|
|
425
|
+
in_owned && !saw_heading { exit 2 }
|
|
426
|
+
in_owned && $0 == "<!-- gsd:plan-revision-conflicts:end -->" {
|
|
427
|
+
done = 1
|
|
428
|
+
in_owned = 0
|
|
429
|
+
print count
|
|
430
|
+
exit
|
|
431
|
+
}
|
|
432
|
+
in_owned && /^- \[ \] REVISION_CONFLICT .*required_property:/ { count++ }
|
|
433
|
+
END { if (!done) exit 2 }
|
|
434
|
+
' "${REVIEWS_FILE}"); then
|
|
435
|
+
:
|
|
436
|
+
else
|
|
437
|
+
awk_status=$?
|
|
438
|
+
echo "BLOCKED: could not parse the writer-owned plan-revision conflict block in '${REVIEWS_FILE}' (awk exit ${awk_status}). Refusing to declare convergence on an unverifiable gate." >&2
|
|
439
|
+
exit 1
|
|
440
|
+
fi
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
`/gsd:review` emits exactly one writer-owned slot immediately after the artifact title,
|
|
444
|
+
between `<!-- gsd:plan-revision-conflicts:begin -->` and
|
|
445
|
+
`<!-- gsd:plan-revision-conflicts:end -->`. Inside that slot, `/gsd:plan-phase` records each
|
|
446
|
+
conflict as a `- [ ] REVISION_CONFLICT` checklist line and flips it to
|
|
447
|
+
`- [x] REVISION_CONFLICT` when resolved. The reader counts only the first fixed slot at that
|
|
448
|
+
position and stops at its explicit end delimiter. Reviewer output is rendered after the slot, so
|
|
449
|
+
raw reviewer text containing either the heading or an exact conflict-shaped checklist line cannot
|
|
450
|
+
forge blocking state. There is deliberately no fallback to the prior global line-shape scan: that
|
|
451
|
+
shape never merged to `next`, and accepting both grammars would recreate the reviewer collision.
|
|
452
|
+
|
|
453
|
+
**Only `/gsd:plan-phase` mutates the contents of this slot.** The review agent preserves the
|
|
454
|
+
existing `## Plan-Revision Conflicts` block byte-for-byte between its delimiters; every other
|
|
455
|
+
agent with write access to REVIEWS.md must leave it alone. Appending, editing, reordering or
|
|
456
|
+
deleting a line there forges the state of a blocking gate. Readers read. If `OPEN_CONFLICTS` > 0, convergence has NOT been
|
|
457
|
+
achieved regardless of the counts: skip the converged branch and continue to 5c so the next cycle
|
|
458
|
+
arbitrates. Escalation at `MAX_CYCLES` is unchanged and still terminates the loop, so an
|
|
459
|
+
unresolvable conflict escalates rather than deadlocking.
|
|
460
|
+
|
|
461
|
+
**If HIGH_COUNT == 0 and ACTIONABLE_COUNT == 0 and OPEN_CONFLICTS == 0 (converged):**
|
|
394
462
|
|
|
395
463
|
```bash
|
|
396
464
|
gsd_run state planned-phase --phase "${PHASE}" --name "${phase_name}" --plans "${PLAN_COUNT}"
|
|
@@ -410,11 +478,11 @@ Display:
|
|
|
410
478
|
|
|
411
479
|
Exit — convergence achieved.
|
|
412
480
|
|
|
413
|
-
**If HIGH_COUNT > 0 or ACTIONABLE_COUNT > 0:** Continue to 5c.
|
|
481
|
+
**If HIGH_COUNT > 0 or ACTIONABLE_COUNT > 0 or OPEN_CONFLICTS > 0:** Continue to 5c.
|
|
414
482
|
|
|
415
483
|
### 5c. Stall Detection + Escalation Check
|
|
416
484
|
|
|
417
|
-
Display: `◆ Cycle {cycle}/{MAX_CYCLES} — {HIGH_COUNT} HIGH, {ACTIONABLE_COUNT} actionable non-HIGH review concerns found`
|
|
485
|
+
Display: `◆ Cycle {cycle}/{MAX_CYCLES} — {HIGH_COUNT} HIGH, {ACTIONABLE_COUNT} actionable non-HIGH review concerns, {OPEN_CONFLICTS} open plan-revision conflicts found`
|
|
418
486
|
|
|
419
487
|
**Stall detection:** If `UNRESOLVED_COUNT >= prev_unresolved_count`:
|
|
420
488
|
```text
|
|
@@ -424,6 +492,29 @@ Display: `◆ Cycle {cycle}/{MAX_CYCLES} — {HIGH_COUNT} HIGH, {ACTIONABLE_COUN
|
|
|
424
492
|
|
|
425
493
|
**Max cycles check:** If `cycle >= MAX_CYCLES`:
|
|
426
494
|
|
|
495
|
+
**If `OPEN_CONFLICTS` > 0 (#3771): "Proceed anyway" is never offered.** An open plan-revision
|
|
496
|
+
conflict is a blocker — this loop's whole purpose is to surface it rather than let a success
|
|
497
|
+
banner paper over it, so escalation cannot end in the same silent acceptance a HIGH/actionable
|
|
498
|
+
concern can. Only "Manual review" is available:
|
|
499
|
+
|
|
500
|
+
If `TEXT_MODE` is true, present as plain text:
|
|
501
|
+
```text
|
|
502
|
+
Plan convergence did not complete after {MAX_CYCLES} cycles.
|
|
503
|
+
{OPEN_CONFLICTS} open plan-revision conflict(s) remain — these are blockers and cannot be accepted:
|
|
504
|
+
|
|
505
|
+
{HIGH_LINES}
|
|
506
|
+
|
|
507
|
+
{ACTIONABLE_LINES}
|
|
508
|
+
|
|
509
|
+
Review the concerns in: {REVIEWS_FILE}
|
|
510
|
+
|
|
511
|
+
To replan manually: /gsd:plan-phase {PHASE} --reviews
|
|
512
|
+
To restart loop: /gsd:plan-review-convergence {PHASE} {REVIEWER_FLAGS}
|
|
513
|
+
```
|
|
514
|
+
Exit workflow.
|
|
515
|
+
|
|
516
|
+
**Otherwise (`OPEN_CONFLICTS` == 0):**
|
|
517
|
+
|
|
427
518
|
If `TEXT_MODE` is true, present as plain-text numbered list:
|
|
428
519
|
```text
|
|
429
520
|
Plan convergence did not complete after {MAX_CYCLES} cycles.
|
|
@@ -478,7 +569,7 @@ Display: `◆ Replanning inline with review feedback... (plan-phase runs here in
|
|
|
478
569
|
Skill(skill="gsd-plan-phase", args="{PHASE} --reviews --skip-research {GSD_WS}")
|
|
479
570
|
```
|
|
480
571
|
|
|
481
|
-
Run plan-phase **inline** (do NOT wrap it in Agent()). Same rationale as step 4: the convergence orchestrator runs at depth 0 with Agent available, so inline plan-phase can spawn gsd-planner and gsd-plan-checker at depth 1. Wrapping in Agent() pushes plan-phase to depth 1 where the Agent tool is absent — the replan loop can never produce a revised plan when HIGHs are found. This is the root cause of bug #936. Actionable MEDIUM/LOW findings must be incorporated into executable PLAN.md content or explicitly deferred/rejected in the relevant PLAN.md before convergence can complete. Wait until plan-phase completes (outputs '## PLANNING COMPLETE') and updated PLAN.md files are committed before continuing.
|
|
572
|
+
Run plan-phase **inline** (do NOT wrap it in Agent()). Same rationale as step 4: the convergence orchestrator runs at depth 0 with Agent available, so inline plan-phase can spawn gsd-planner and gsd-plan-checker at depth 1. Wrapping in Agent() pushes plan-phase to depth 1 where the Agent tool is absent — the replan loop can never produce a revised plan when HIGHs are found. This is the root cause of bug #936. Actionable MEDIUM/LOW findings must be incorporated into executable PLAN.md content or explicitly deferred/rejected in the relevant PLAN.md before convergence can complete. The same holds for any open `## Plan-Revision Conflicts` entry (#3771): the replan must resolve it by adopting one of its recorded alternatives, overriding the named constraint, or amending the constraint — and mark the entry resolved. Re-running the planner against an unchanged conflict cannot resolve it and only burns a cycle. Wait until plan-phase completes (outputs '## PLANNING COMPLETE') and updated PLAN.md files are committed before continuing.
|
|
482
573
|
|
|
483
574
|
After plan-phase completes → go back to **step 5a** (review again).
|
|
484
575
|
|
|
@@ -497,7 +588,8 @@ After plan-phase completes → go back to **step 5a** (review again).
|
|
|
497
588
|
- [ ] Abort with clear error if current_actionable is absent or malformed
|
|
498
589
|
- [ ] Warn if ACTIONABLE_COUNT > 0 but ## Current Actionable Non-HIGH Concerns section is absent from return message
|
|
499
590
|
- [ ] The review Agent fully completes gsd-review before returning (plan-phase runs inline — no Agent wrap)
|
|
500
|
-
- [ ] Loop exits on: no HIGH concerns
|
|
591
|
+
- [ ] Loop exits on: no HIGH concerns, no actionable non-HIGH concerns, and OPEN_CONFLICTS == 0 (converged) OR max cycles (escalation)
|
|
592
|
+
- [ ] OPEN_CONFLICTS read from REVIEWS.md and evaluated BEFORE the converged branch writes state or prints the banner
|
|
501
593
|
- [ ] Stall detection reported when total unresolved review concern count is not decreasing
|
|
502
594
|
- [ ] STATE.md updated on convergence completion
|
|
503
595
|
</success_criteria>
|
|
@@ -140,7 +140,7 @@ RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --raw --default "
|
|
|
140
140
|
gsd_run query commit "docs: plant seed — {$IDEA}" --files .planning/seeds/SEED-{PADDED}-{slug}.md
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
-
**If `response_language` is set:** All user-facing questions, prompts, and explanations
|
|
143
|
+
**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.
|
|
144
144
|
</step>
|
|
145
145
|
|
|
146
146
|
<step name="confirm">
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@~/.claude/gsd-core/references/response-language-directive.md
|
|
2
|
+
|
|
1
3
|
<purpose>
|
|
2
4
|
Create a clean branch for pull requests by filtering .planning/ paths out of the
|
|
3
5
|
cherry-picked history. Two modes, selected by the `planning.pr_strict` config key:
|
|
@@ -261,7 +263,10 @@ if [ "$PR_STRICT" = "true" ]; then
|
|
|
261
263
|
FILTER_PATHS=".planning/"
|
|
262
264
|
FORBIDDEN_RE="^\.planning/"
|
|
263
265
|
else
|
|
264
|
-
|
|
266
|
+
# Rewrapped through unquoted command substitution (gsd-core#4109): a bare
|
|
267
|
+
# `$VAR` word-splits under bash but not zsh, collapsing every element onto
|
|
268
|
+
# one iteration there.
|
|
269
|
+
FILTER_PATHS=$(for d in $(printf '%s' "$TRANSIENT_DIRS"); do printf '.planning/%s/ ' "$d"; done)
|
|
265
270
|
FORBIDDEN_RE="^\.planning/($(echo "$TRANSIENT_DIRS" | tr ' ' '|'))/"
|
|
266
271
|
fi
|
|
267
272
|
```
|
|
@@ -273,16 +278,27 @@ For each commit, check what it touches:
|
|
|
273
278
|
FILES=$(git diff-tree --no-commit-id --name-only -r $HASH)
|
|
274
279
|
NON_PLANNING=$(echo "$FILES" | grep -c -v "^\.planning/" || true)
|
|
275
280
|
STRUCTURAL=$(echo "$FILES" | grep -Ec "$STRUCTURAL_RE" || true)
|
|
281
|
+
PLANNING_COUNT=$(echo "$FILES" | grep -c "^\.planning/" || true)
|
|
276
282
|
```
|
|
277
283
|
|
|
278
|
-
Classify
|
|
279
|
-
|
|
280
|
-
- **
|
|
281
|
-
|
|
282
|
-
|
|
284
|
+
Classify, using `NON_PLANNING`, `STRUCTURAL`, and `PLANNING_COUNT` computed above — every arm's
|
|
285
|
+
condition is explicit and computable so no reading of it is ambiguous:
|
|
286
|
+
- **Code commits**: `NON_PLANNING > 0` and `PLANNING_COUNT == 0` → INCLUDE (both modes)
|
|
287
|
+
- **Mixed code+planning commits**: `NON_PLANNING > 0` and `PLANNING_COUNT > 0` → INCLUDE (both
|
|
288
|
+
modes; the planning paths are filtered out by `create_pr_branch`, not the commit)
|
|
289
|
+
- **Structural-only planning commits**: `NON_PLANNING == 0` and `STRUCTURAL == PLANNING_COUNT`
|
|
290
|
+
and `PLANNING_COUNT > 0` (every `.planning/` file touched is structural) → INCLUDE in
|
|
283
291
|
**default** mode; **EXCLUDE** in strict mode, which has no structural carve-out
|
|
284
|
-
- **
|
|
285
|
-
|
|
292
|
+
- **Mixed planning commits (#4447)**: `NON_PLANNING == 0` and `STRUCTURAL > 0` and
|
|
293
|
+
`STRUCTURAL < PLANNING_COUNT` (some but not all `.planning/` files touched are structural —
|
|
294
|
+
the rest are transient and/or the "other" bucket, e.g. `config.json`/`intel/`) → INCLUDE in
|
|
295
|
+
**default** mode (the transient-dir subset of the non-structural paths is filtered out by
|
|
296
|
+
`create_pr_branch`'s universal per-commit filter exactly as for a mixed code+planning commit;
|
|
297
|
+
any "other" non-structural, non-transient path — `config.json`, `intel/`, etc. — is simply
|
|
298
|
+
preserved, same as default mode already does for such paths on any commit); **EXCLUDE** in
|
|
299
|
+
strict mode
|
|
300
|
+
- **Transient-only planning commits**: `NON_PLANNING == 0` and `STRUCTURAL == 0` and
|
|
301
|
+
`PLANNING_COUNT > 0` → EXCLUDE (both modes)
|
|
286
302
|
|
|
287
303
|
In strict mode this collapses to a single rule: `NON_PLANNING > 0` → INCLUDE, else EXCLUDE.
|
|
288
304
|
|
|
@@ -292,6 +308,7 @@ Commits to include: {N} (code changes{, + structural planning — default mode o
|
|
|
292
308
|
Commits to exclude: {N} (planning-only)
|
|
293
309
|
Mixed commits: {N} (code + planning — included, planning paths filtered)
|
|
294
310
|
Structural planning commits: {N} ({included|excluded — strict mode})
|
|
311
|
+
Mixed planning commits: {N} ({included — structural + transient/other, planning paths filtered|excluded — strict mode})
|
|
295
312
|
```
|
|
296
313
|
</step>
|
|
297
314
|
|
|
@@ -322,12 +339,15 @@ touching the same planning path makes `git cherry-pick` abort with *"untracked w
|
|
|
322
339
|
files would be overwritten by merge"*, and every remaining commit is silently dropped.
|
|
323
340
|
|
|
324
341
|
```bash
|
|
325
|
-
|
|
342
|
+
# Rewrapped through unquoted command substitution (gsd-core#4109): a bare
|
|
343
|
+
# `$VAR` word-splits under bash but not zsh, collapsing every element onto
|
|
344
|
+
# one iteration there.
|
|
345
|
+
for HASH in $(printf '%s' "$INCLUDED_COMMITS"); do
|
|
326
346
|
# A modify/delete conflict on a filtered path is EXPECTED and is resolved below — the
|
|
327
347
|
# filtered path is absent from HEAD by construction. Do not treat it as a failure here.
|
|
328
348
|
git cherry-pick --no-commit "$HASH" || true
|
|
329
349
|
|
|
330
|
-
for P in $FILTER_PATHS; do
|
|
350
|
+
for P in $(printf '%s' "$FILTER_PATHS"); do
|
|
331
351
|
git rm -r -f -q --ignore-unmatch -- "$P" 2>/dev/null || true
|
|
332
352
|
git checkout HEAD -- "$P" 2>/dev/null || true
|
|
333
353
|
done
|
|
@@ -19,7 +19,7 @@ _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-pars
|
|
|
19
19
|
RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --raw --default "" 2>/dev/null || echo "")
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
**If `response_language` is set:** All user-facing questions, prompts, and explanations
|
|
22
|
+
**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.
|
|
23
23
|
|
|
24
24
|
## 1. Initialize
|
|
25
25
|
|
|
@@ -89,7 +89,7 @@ Glob every phase directory's SCOPE BOUNDARY log (executor writes out-of-scope di
|
|
|
89
89
|
ls .planning/phases/*/deferred-items.md 2>/dev/null || true
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
For each `deferred-items.md` found, read its entries (bullet list, one entry per top-level
|
|
92
|
+
For each `deferred-items.md` found, read its entries (bullet list, one entry per top-level list item — `-`, `*`, `+` or an ordered marker of one to nine digits terminated by a DOT, where an ordered list counts when it starts at `0.` or `1.` or continues a list already open at its level; `1)` is not a marker and neither is a ten-digit ordinal (`999999999.` counts, `1234567890.` does not) — with continuation lines indented beneath it; fenced code blocks at ANY indent, including deeper than CommonMark's three-space cap, and `* * *`-style separators are not entries; an unclosed fence ends with its own entry and never hides the entries after it; a closed pair of delimiters is a fence whatever sits between them). An entry is RESOLVED only if it carries an explicit `status: resolved` field on one of its lines — the bare key lower-case only, or the bolded `**Status:**` form in any case; the VALUE is case-insensitive in both; every other entry — including one with no `status:` field at all — is UNRESOLVED and must be surfaced (fail-safe: never silently drop a possibly-open item).
|
|
93
93
|
|
|
94
94
|
Emit:
|
|
95
95
|
- ✓ `No unresolved deferred items` — if no `deferred-items.md` files exist, or every entry in every file is `status: resolved`
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@~/.claude/gsd-core/references/response-language-directive.md
|
|
2
|
+
|
|
1
3
|
<purpose>
|
|
2
4
|
Check project progress, summarize recent work and what's ahead, then intelligently route to the next action — either executing an existing plan or creating the next one. Provides situational awareness before continuing work.
|
|
3
5
|
</purpose>
|
|
@@ -18,13 +20,33 @@ INIT=$(gsd_run query init.progress $FORENSIC_PARAM)
|
|
|
18
20
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
19
21
|
```
|
|
20
22
|
|
|
21
|
-
Extract from init JSON: `project_exists`, `roadmap_exists`, `state_exists`, `phases`, `current_phase`, `next_phase`, `milestone_version`, `completed_count`, `phase_count`, `paused_at`, `state_path`, `roadmap_path`, `project_path`, `config_path`, `phase_mvp_mode`.
|
|
23
|
+
Extract from init JSON: `project_exists`, `roadmap_exists`, `state_exists`, `requirements_exists`, `planning_exists`, `milestones_exists`, `init_incomplete`, `phases`, `current_phase`, `next_phase`, `milestone_version`, `completed_count`, `phase_count`, `paused_at`, `state_path`, `roadmap_path`, `project_path`, `config_path`, `phase_mvp_mode`.
|
|
22
24
|
|
|
23
25
|
```bash
|
|
24
26
|
DISCUSS_MODE=$(gsd_run query config-get workflow.discuss_mode --raw 2>/dev/null || echo "discuss")
|
|
25
27
|
```
|
|
26
28
|
|
|
27
|
-
If `
|
|
29
|
+
**If `init_incomplete` is true (#4040 — interrupted bootstrap):**
|
|
30
|
+
|
|
31
|
+
`.planning/` exists but the core initialization artifacts are missing (one or more of `REQUIREMENTS.md`, `ROADMAP.md`, `STATE.md` were never created — a bootstrap that stopped partway, e.g. after PROJECT.md). This is NOT a new project, NOT a missing STATE.md, and NOT a between-milestones state — do not fall through to any of those routes. Route to initialization recovery:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## ⚠ Initialization Incomplete
|
|
37
|
+
|
|
38
|
+
A partial `.planning/` was found: project initialization started but stopped before creating all core artifacts (missing: REQUIREMENTS.md, ROADMAP.md, STATE.md — whichever `requirements_exists` / `roadmap_exists` / `state_exists` report as false).
|
|
39
|
+
|
|
40
|
+
`/clear` then:
|
|
41
|
+
|
|
42
|
+
`/gsd:new-project` — resumes initialization from the first missing artifact; existing PROJECT.md (and any already-created artifacts) are kept, not regenerated.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Exit. (The payload's `init_incomplete` is computed with the between-milestones archive case excluded — `MILESTONES.md` present means missing ROADMAP/REQUIREMENTS is archival, and that state still routes to Route F below.)
|
|
48
|
+
|
|
49
|
+
If `init_incomplete` is false and `planning_exists` is false and `project_exists` is false (no `.planning/` directory at all):
|
|
28
50
|
|
|
29
51
|
```
|
|
30
52
|
No planning structure found.
|
|
@@ -36,7 +58,7 @@ Exit.
|
|
|
36
58
|
|
|
37
59
|
If missing STATE.md: suggest `/gsd:new-project`.
|
|
38
60
|
|
|
39
|
-
**If ROADMAP.md missing but PROJECT.md exists:**
|
|
61
|
+
**If ROADMAP.md missing but PROJECT.md exists (and `init_incomplete` is false):**
|
|
40
62
|
|
|
41
63
|
This means a milestone was completed and archived. Go to **Route F** (between milestones).
|
|
42
64
|
|
|
@@ -56,7 +56,7 @@ Agent(
|
|
|
56
56
|
**Handle checker return:**
|
|
57
57
|
|
|
58
58
|
- **`## VERIFICATION PASSED`:** Display confirmation, proceed to step 6.
|
|
59
|
-
- **`## ISSUES FOUND`:**
|
|
59
|
+
- **`## ISSUES FOUND`:** Count BLOCKER + WARNING entries in the YAML issues block; an entry whose severity is missing or unrecognized counts as a BLOCKER (fail closed). If zero — every entry is explicitly INFO — display `ℹ advisory — {dimension}: {description}` per entry and proceed to step 6; INFO is advisory and never enters the loop (#3724). Otherwise display issues, check iteration count, enter revision loop.
|
|
60
60
|
|
|
61
61
|
**Revision loop (max 2 iterations):**
|
|
62
62
|
|
|
@@ -68,6 +68,8 @@ Display: `Sending back to planner for revision... (iteration ${N}/2)`
|
|
|
68
68
|
|
|
69
69
|
Revision prompt:
|
|
70
70
|
|
|
71
|
+
Reuse the `PLAN_PRE_HOOKS_JSON` snapshot captured by Quick Step 5; do not render hooks again.
|
|
72
|
+
|
|
71
73
|
```markdown
|
|
72
74
|
<revision_context>
|
|
73
75
|
**Mode:** quick-full (revision)
|
|
@@ -78,12 +80,23 @@ Revision prompt:
|
|
|
78
80
|
|
|
79
81
|
${AGENT_SKILLS_PLANNER}
|
|
80
82
|
|
|
83
|
+
{For each active entry in `PLAN_PRE_HOOKS_JSON` where `kind == "contribution"` and `into == "planner"` (in array order): inject the entry's `fragment.inline` verbatim here, plus its resolved `configValues` when the entry carries them. If no active planner contributions exist, omit this block entirely.}
|
|
84
|
+
|
|
81
85
|
**Checker issues:** ${structured_issues_from_checker}
|
|
82
86
|
|
|
83
87
|
</revision_context>
|
|
84
88
|
|
|
85
89
|
<instructions>
|
|
86
90
|
Make targeted updates to address checker issues.
|
|
91
|
+
|
|
92
|
+
`required_property` + evidence + severity BIND. `fix_hint` is ONE non-binding example route: a
|
|
93
|
+
smaller or different mechanism reaching the same property addresses the issue in full — say which
|
|
94
|
+
you used. Re-check ${DISCUSS_MODE ? 'locked decisions in ' + quick_id + '-CONTEXT.md, ' : ''}capability guidance (CLAUDE.md, project skills) and the
|
|
95
|
+
constraints these plans already encode BEFORE editing; if a hint would contradict one, or the
|
|
96
|
+
property is unreachable without breaking one, return `## REVISION_CONFLICT` with the conflict and
|
|
97
|
+
the alternatives rather than applying or working around it. Full contract:
|
|
98
|
+
`gsd-core/references/planner-revision.md`, which you load in revision mode.
|
|
99
|
+
|
|
87
100
|
Do NOT replan from scratch unless issues are fundamental.
|
|
88
101
|
Return what changed.
|
|
89
102
|
</instructions>
|
|
@@ -100,7 +113,29 @@ Agent(
|
|
|
100
113
|
|
|
101
114
|
> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.
|
|
102
115
|
|
|
103
|
-
|
|
116
|
+
**If the planner returns `## REVISION_CONFLICT`:** a conflict is not resolvable by re-running the
|
|
117
|
+
same loop, so it must not consume retry budget. Do NOT increment `iteration_count` and do NOT
|
|
118
|
+
re-spawn the checker yet. Present the conflict table and its alternatives to the user and ask
|
|
119
|
+
which to take: adopt a named alternative / override the named constraint and apply the hint /
|
|
120
|
+
amend the constraint itself. Every option resolves the conflict. Accepting the plan with the
|
|
121
|
+
blocker still open is NOT offered here — the blocking `required_property` still fails, and that
|
|
122
|
+
choice belongs to the max-iteration escalation below, which is unchanged.
|
|
123
|
+
|
|
124
|
+
A quick task has no REVIEWS.md and no phase, so `workflow.plan_review_convergence` has nothing to
|
|
125
|
+
arbitrate over here; the user is the only route. `plan-phase` is where the convergence hand-off
|
|
126
|
+
lives.
|
|
127
|
+
|
|
128
|
+
Re-spawn the planner with the chosen resolution, then **re-evaluate its return from the top of
|
|
129
|
+
this handler** — do not fall through to the checker spawn below. A second conflict is still a
|
|
130
|
+
conflict, not a revised plan.
|
|
131
|
+
|
|
132
|
+
**Bounded:** A conflict naming the SAME `required_property` twice in a row (no successful revision in between) is a stall, and so is the
|
|
133
|
+
THIRD conflict return of this loop whatever property it names — alternating property names
|
|
134
|
+
would otherwise never trip the repeat rule and the path would be unbounded. Stop re-spawning and
|
|
135
|
+
route it to the same iteration-count check below, so declining to spend an iteration cannot make
|
|
136
|
+
this path unbounded.
|
|
137
|
+
|
|
138
|
+
**Otherwise (the planner returns a revised plan, not `## REVISION_CONFLICT`):** spawn checker again, increment `iteration_count`.
|
|
104
139
|
|
|
105
140
|
**If iteration_count >= 2:**
|
|
106
141
|
|
|
@@ -13,7 +13,7 @@ Spawn a single focused researcher (not 4 parallel researchers like full phases
|
|
|
13
13
|
|
|
14
14
|
<!-- #2517 model-omit-on-inherit -->
|
|
15
15
|
|
|
16
|
-
> **Model omission (#2517).** Omit the `model` parameter entirely when the value it would carry (`planner_model`, `checker_model`, `executor_model`, `reviewer_model`, `verifier_model`) is `"inherit"` or empty. An empty value 404s on runtimes without native tier aliases — the default on non-Claude runtimes. Omitting it inherits the orchestrator's model. See @gsd-core/references/model-profile-resolution.md.
|
|
16
|
+
> **Model omission (#2517).** Omit the `model` parameter entirely when the value it would carry (`planner_model`, `checker_model`, `executor_model`, `reviewer_model`, `verifier_model`, `researcher_model`) is `"inherit"` or empty. An empty value 404s on runtimes without native tier aliases — the default on non-Claude runtimes. Omitting it inherits the orchestrator's model. See @gsd-core/references/model-profile-resolution.md.
|
|
17
17
|
|
|
18
18
|
<!-- #2508 runtime-aware-dispatch -->
|
|
19
19
|
|
|
@@ -35,7 +35,7 @@ Agent(
|
|
|
35
35
|
${DISCUSS_MODE ? '- ' + QUICK_DIR + '/' + quick_id + '-CONTEXT.md (User decisions — research should align with these. #3894: when workflow.research_before_questions is enabled research runs BEFORE discussion, so this file will not exist yet — read it only if present)' : ''}
|
|
36
36
|
</required_reading>
|
|
37
37
|
|
|
38
|
-
${
|
|
38
|
+
${AGENT_SKILLS_RESEARCHER}
|
|
39
39
|
|
|
40
40
|
</research_context>
|
|
41
41
|
|
|
@@ -56,7 +56,7 @@ Return: ## RESEARCH COMPLETE with file path
|
|
|
56
56
|
</output>
|
|
57
57
|
",
|
|
58
58
|
subagent_type="gsd-phase-researcher",
|
|
59
|
-
model="{
|
|
59
|
+
model="{researcher_model}",
|
|
60
60
|
description="Research: ${DESCRIPTION}"
|
|
61
61
|
)
|
|
62
62
|
```
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
**Step 2b: Create a new batch (only when `$RESUME_BATCH_ID` is empty)**
|
|
2
|
+
|
|
3
|
+
Skip this step entirely if `$RESUME_BATCH_ID` is set (resume-mode.md owns
|
|
4
|
+
that path instead).
|
|
5
|
+
|
|
6
|
+
**Get the task list.** If `--file <path>` was present in `$ARGUMENTS`, use its
|
|
7
|
+
value as `$TASK_FILE`. Otherwise the remaining, non-flag text of `$ARGUMENTS`
|
|
8
|
+
IS the inline task list (a bulleted/numbered list, ≥2 items — the same
|
|
9
|
+
grammar `parseTaskList` enforces).
|
|
10
|
+
|
|
11
|
+
If `$TASK_FILE` is set:
|
|
12
|
+
```bash
|
|
13
|
+
_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
|
|
14
|
+
QB_CREATE_JSON=$(gsd_run quick-batch create --file "$TASK_FILE" --base-revision "$(git rev-parse HEAD)" --raw)
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Otherwise, the inline list must land on disk first — `quick-batch create`
|
|
18
|
+
only accepts `--file` (path-confined, same as `/gsd:quick-batch`'s own
|
|
19
|
+
security posture): write it to a scratch file under `.planning/` before
|
|
20
|
+
calling the verb.
|
|
21
|
+
```bash
|
|
22
|
+
TASK_FILE="${quick_dir%/quick}/.quick-batch-task-list.tmp"
|
|
23
|
+
mkdir -p "$(dirname "$TASK_FILE")"
|
|
24
|
+
printf '%s\n' "$INLINE_TASK_LIST" > "$TASK_FILE"
|
|
25
|
+
QB_CREATE_JSON=$(gsd_run quick-batch create --file "$TASK_FILE" --base-revision "$(git rev-parse HEAD)" --raw)
|
|
26
|
+
rm -f "$TASK_FILE"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
QB_CREATE_RC=$?
|
|
31
|
+
if [[ "$QB_CREATE_JSON" == @file:* ]]; then QB_CREATE_JSON=$(cat "${QB_CREATE_JSON#@file:}"); fi
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**If `$QB_CREATE_RC` is non-zero:** the task list failed to parse (fewer than
|
|
35
|
+
2 items — row 2/12) or the dependency DAG was invalid. Print the CLI's error
|
|
36
|
+
message verbatim and STOP. Do not dispatch anything.
|
|
37
|
+
|
|
38
|
+
**Otherwise:** parse `$QB_CREATE_JSON` for `batchId` and `manifest` (every
|
|
39
|
+
item starts `pending`, wave `0` — no dependency/file-overlap signal exists
|
|
40
|
+
yet before planning; this is expected, not a bug, per the design's negative-
|
|
41
|
+
space note).
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
BATCH_ID="$batchId"
|
|
45
|
+
BATCH_MANIFEST_JSON=$(printf '%s' "$QB_CREATE_JSON" | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{try{const j=JSON.parse(s);process.stdout.write(JSON.stringify(j.manifest))}catch{process.stdout.write("")}})')
|
|
46
|
+
ITEM_COUNT=$(printf '%s' "$BATCH_MANIFEST_JSON" | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{try{const j=JSON.parse(s);process.stdout.write(String(j.items.length))}catch{process.stdout.write("0")}})')
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Report to user:
|
|
50
|
+
```
|
|
51
|
+
Creating quick batch ${BATCH_ID}: ${ITEM_COUNT} item(s).
|
|
52
|
+
Manifest: .planning/quick-batches/${BATCH_ID}/BATCH.json
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Continue to Step 3 in `quick-batch.md`.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
**Step 9: Completion**
|
|
2
|
+
|
|
3
|
+
For every item that merged successfully in Step 7 AND (NOT `$VALIDATE_MODE`,
|
|
4
|
+
OR Step 8 routed it to `complete`): call `completeQuickItem` via its CLI verb
|
|
5
|
+
— this is the ONLY writer of a "Quick Tasks Completed" STATE.md row and the
|
|
6
|
+
item's `complete` status; both happen inside ONE lock transaction, exactly
|
|
7
|
+
once per item (idempotent — re-running this step for an already-complete
|
|
8
|
+
item is a no-op, same guarantee `/gsd:quick` relies on):
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
_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
|
|
12
|
+
gsd_run quick-batch complete \
|
|
13
|
+
--batch "$BATCH_ID" \
|
|
14
|
+
--quick-id "$quick_id" \
|
|
15
|
+
--description "$description" \
|
|
16
|
+
--date "$date" \
|
|
17
|
+
--commit "$commit_hash" \
|
|
18
|
+
--directory "$ITEM_DIR" \
|
|
19
|
+
--raw
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Items NOT reaching this call — `human_needed`, `failed` (planner/checker/
|
|
23
|
+
merge/verification failure), or still `blocked`/`pending` (a dependency
|
|
24
|
+
failed, row 32) — are left exactly as their respective routing step set
|
|
25
|
+
them. No STATE row, no `complete` status, worktree preserved where
|
|
26
|
+
applicable.
|
|
27
|
+
|
|
28
|
+
**Final commit.** Stage every artifact produced this run (PLAN.md, SUMMARY.md,
|
|
29
|
+
`--research` RESEARCH.md, `--validate` VERIFICATION.md, per item, plus
|
|
30
|
+
`.planning/STATE.md`) and commit:
|
|
31
|
+
`$BATCH_ARTIFACT_FILES` is a bash ARRAY (not a plain string — a plain
|
|
32
|
+
space-joined string re-splits unpredictably under `set -f`/globbing and
|
|
33
|
+
diverges between bash and zsh, the #4109 word-splitting bug class):
|
|
34
|
+
```bash
|
|
35
|
+
COMMIT_DOCS=$(gsd_run query config-get commit_docs --raw 2>/dev/null || echo "true")
|
|
36
|
+
if [ "$COMMIT_DOCS" != "false" ]; then
|
|
37
|
+
git add "${BATCH_ARTIFACT_FILES[@]}" 2>/dev/null
|
|
38
|
+
gsd_run query commit "docs(quick-batch-${BATCH_ID}): ${ITEM_COUNT} item(s)" --files "${BATCH_ARTIFACT_FILES[@]}"
|
|
39
|
+
fi
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Final report.** Re-load the batch (`gsd_run quick-batch resume --batch
|
|
43
|
+
"$BATCH_ID" --raw` — read-only in effect when nothing changed) and summarize
|
|
44
|
+
by status:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
---
|
|
48
|
+
GSD > QUICK BATCH COMPLETE
|
|
49
|
+
|
|
50
|
+
Batch ${BATCH_ID}: ${ITEM_COUNT} item(s)
|
|
51
|
+
Complete: ${complete_count}
|
|
52
|
+
Failed: ${failed_count}${failed_count > 0 ? ' (' + failed_reasons + ')' : ''}
|
|
53
|
+
Needs review: ${human_needed_count}
|
|
54
|
+
Blocked: ${blocked_count}
|
|
55
|
+
|
|
56
|
+
${failed_count + human_needed_count > 0 ? 'Resume after resolving: /gsd:quick-batch --resume ' + BATCH_ID : ''}
|
|
57
|
+
---
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
If EVERY item is `complete`, this is a clean finish — no further action
|
|
61
|
+
needed. If any item is `failed`/`human_needed`/`blocked`, the batch stays
|
|
62
|
+
resumable: fix the underlying issue (or accept the failure), then re-run
|
|
63
|
+
`/gsd:quick-batch --resume ${BATCH_ID}` — `resumeBatch`'s own propagation
|
|
64
|
+
(unmodified from Phase 3) re-evaluates eligibility from the current state, no
|
|
65
|
+
special quick-batch-side recovery logic needed.
|