@opengsd/gsd-core 1.9.1 → 1.11.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 +2 -3
- package/.opencode/plugins/gsd-core.js +8 -1
- package/agents/gsd-code-fixer.md +27 -3
- package/agents/gsd-debug-session-manager.md +11 -0
- package/agents/gsd-debugger.md +12 -246
- package/agents/gsd-doc-synthesizer.md +2 -4
- package/agents/gsd-executor.md +12 -10
- package/agents/gsd-integration-checker.md +3 -0
- package/agents/gsd-mempalace-curator.md +5 -2
- package/agents/gsd-phase-researcher.md +20 -1
- package/agents/gsd-plan-checker.md +46 -0
- package/agents/gsd-planner.md +49 -54
- package/agents/gsd-roadmapper.md +21 -3
- package/agents/gsd-user-profiler.md +3 -0
- package/agents/gsd-verifier.md +26 -73
- package/bin/install.js +1272 -1238
- package/bin/lib/ui-safety-gate.cjs +2 -0
- package/commands/gsd/code-review.md +1 -1
- package/commands/gsd/execute-phase.md +1 -1
- package/commands/gsd/map-codebase.md +1 -1
- package/commands/gsd/mempalace-capture.md +2 -2
- package/commands/gsd/mempalace-recall.md +1 -1
- package/commands/gsd/new-milestone.md +2 -2
- package/commands/gsd/plan-phase.md +1 -1
- package/commands/gsd/quick.md +1 -1
- package/commands/gsd/review-backlog.md +2 -1
- package/commands/gsd/verify-work.md +1 -1
- package/gsd-core/bin/gsd-tools.cjs +1009 -115
- package/gsd-core/bin/lib/active-workstream-store.cjs +153 -12
- package/gsd-core/bin/lib/agent-install-check.cjs +268 -38
- package/gsd-core/bin/lib/api-coverage.cjs +123 -5
- package/gsd-core/bin/lib/artifacts.cjs +3 -0
- package/gsd-core/bin/lib/assumption-delta.cjs +2 -4
- package/gsd-core/bin/lib/audit-command-router.cjs +9 -2
- package/gsd-core/bin/lib/audit.cjs +926 -202
- package/gsd-core/bin/lib/broken-windows.cjs +36 -6
- package/gsd-core/bin/lib/capability-consent.cjs +149 -15
- package/gsd-core/bin/lib/capability-lifecycle.cjs +45 -0
- package/gsd-core/bin/lib/capability-registry.cjs +608 -148
- package/gsd-core/bin/lib/capability-source.cjs +92 -0
- package/gsd-core/bin/lib/capability-trust.cjs +444 -25
- package/gsd-core/bin/lib/capability-validator.cjs +507 -24
- package/gsd-core/bin/lib/capability-writer.cjs +3 -2
- package/gsd-core/bin/lib/check-command-router.cjs +114 -38
- package/gsd-core/bin/lib/claude-orchestration.cjs +56 -3
- package/gsd-core/bin/lib/codex-agent-toml.cjs +329 -0
- package/gsd-core/bin/lib/command-aliases.cjs +94 -0
- package/gsd-core/bin/lib/command-roster.cjs +44 -1
- package/gsd-core/bin/lib/commands.cjs +665 -99
- package/gsd-core/bin/lib/commonjs-marker.cjs +142 -0
- package/gsd-core/bin/lib/complexity-trigger.cjs +1172 -0
- package/gsd-core/bin/lib/config-loader.cjs +76 -0
- package/gsd-core/bin/lib/config.cjs +22 -2
- package/gsd-core/bin/lib/context-composer.cjs +278 -0
- package/gsd-core/bin/lib/context-predicates.cjs +506 -0
- package/gsd-core/bin/lib/core-utils.cjs +217 -40
- package/gsd-core/bin/lib/decisions.cjs +23 -0
- package/gsd-core/bin/lib/docs.cjs +3 -2
- package/gsd-core/bin/lib/external-job.cjs +19 -4
- package/gsd-core/bin/lib/fallow-runner.cjs +20 -44
- package/gsd-core/bin/lib/frontmatter.cjs +239 -32
- package/gsd-core/bin/lib/gap-checker.cjs +68 -7
- package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +57 -6
- package/gsd-core/bin/lib/git-base-branch.cjs +160 -15
- package/gsd-core/bin/lib/graphify.cjs +142 -27
- package/gsd-core/bin/lib/gsd2-import.cjs +37 -5
- package/gsd-core/bin/lib/health-diagnostic-rules/agent-install.cjs +101 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/config-validation.cjs +348 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +145 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/install-surface-shadowing.cjs +98 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/milestone-archive-hygiene.cjs +100 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +222 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +265 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/root-existence.cjs +161 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +303 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +173 -0
- package/gsd-core/bin/lib/health-diagnostic-types.cjs +68 -0
- package/gsd-core/bin/lib/health-diagnostic.cjs +431 -0
- package/gsd-core/bin/lib/host-integration.cjs +13 -1
- package/gsd-core/bin/lib/host-runtime-detection.cjs +134 -0
- package/gsd-core/bin/lib/init-command-router.cjs +83 -8
- package/gsd-core/bin/lib/init.cjs +1325 -169
- package/gsd-core/bin/lib/install-effort-resolver.cjs +73 -30
- package/gsd-core/bin/lib/install-engine.cjs +805 -264
- package/gsd-core/bin/lib/install-fs-adapter.cjs +262 -0
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +203 -0
- package/gsd-core/bin/lib/install-profiles.cjs +160 -57
- package/gsd-core/bin/lib/install-scope.cjs +270 -0
- package/gsd-core/bin/lib/install-shadow-report.cjs +385 -0
- package/gsd-core/bin/lib/installed-surface-resolver.cjs +381 -0
- package/gsd-core/bin/lib/installer-migration-authoring.cjs +3 -1
- package/gsd-core/bin/lib/installer-migration-report.cjs +4 -0
- package/gsd-core/bin/lib/installer-migrations/007-retire-config-root-commonjs-marker.cjs +149 -0
- package/gsd-core/bin/lib/installer-migrations/008-cursor-retire-commands-surface.cjs +55 -0
- package/gsd-core/bin/lib/installer-migrations/009-pi-retire-reserved-hooks-dir.cjs +199 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +206 -13
- package/gsd-core/bin/lib/io.cjs +38 -3
- package/gsd-core/bin/lib/markdown-sectionizer.cjs +8 -1
- package/gsd-core/bin/lib/markdown-table.cjs +133 -20
- package/gsd-core/bin/lib/mcp-catalog.cjs +518 -0
- package/gsd-core/bin/lib/mcp-server.cjs +135 -3
- package/gsd-core/bin/lib/milestone-lock.cjs +248 -0
- package/gsd-core/bin/lib/milestone.cjs +821 -109
- package/gsd-core/bin/lib/model-catalog.cjs +59 -1
- package/gsd-core/bin/lib/model-resolver.cjs +183 -40
- package/gsd-core/bin/lib/normalize-test-command.cjs +1 -1
- package/gsd-core/bin/lib/pattern.cjs +122 -0
- package/gsd-core/bin/lib/phase-estimation.cjs +1 -1
- package/gsd-core/bin/lib/phase-id.cjs +507 -36
- package/gsd-core/bin/lib/phase-lifecycle.cjs +28 -3
- package/gsd-core/bin/lib/phase-locator.cjs +258 -58
- package/gsd-core/bin/lib/phase.cjs +891 -156
- package/gsd-core/bin/lib/plan-dependency-graph.cjs +303 -0
- package/gsd-core/bin/lib/plan-drift-guard.cjs +120 -0
- package/gsd-core/bin/lib/plan-scan.cjs +86 -2
- package/gsd-core/bin/lib/planning-scope.cjs +31 -0
- package/gsd-core/bin/lib/planning-snapshot.cjs +890 -0
- package/gsd-core/bin/lib/planning-workspace.cjs +60 -6
- package/gsd-core/bin/lib/probe-core.cjs +1 -1
- package/gsd-core/bin/lib/profile-output.cjs +1 -1
- package/gsd-core/bin/lib/prompt-budget.cjs +128 -165
- package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +740 -0
- package/gsd-core/bin/lib/retired-artifact-cleanup.cjs +85 -0
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +108 -0
- package/gsd-core/bin/lib/review-lane-invocation.cjs +30 -0
- package/gsd-core/bin/lib/review-lane-runner.cjs +447 -68
- package/gsd-core/bin/lib/review-reviewer-selection.cjs +13 -18
- package/gsd-core/bin/lib/roadmap-command-router.cjs +76 -9
- package/gsd-core/bin/lib/roadmap-parser.cjs +1035 -194
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +37 -10
- package/gsd-core/bin/lib/roadmap.cjs +405 -84
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +795 -100
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +14 -2
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +440 -57
- package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +3 -2
- package/gsd-core/bin/lib/runtime-homes.cjs +220 -41
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +220 -44
- package/gsd-core/bin/lib/runtime-name-policy.cjs +3 -1
- package/gsd-core/bin/lib/runtime-slash.cjs +27 -9
- package/gsd-core/bin/lib/section-manifest.cjs +209 -0
- package/gsd-core/bin/lib/security.cjs +104 -5
- package/gsd-core/bin/lib/shell-command-projection.cjs +388 -30
- package/gsd-core/bin/lib/smart-entry.cjs +154 -22
- package/gsd-core/bin/lib/state-command-router.cjs +5 -1
- package/gsd-core/bin/lib/state-document.cjs +152 -8
- package/gsd-core/bin/lib/state-transition.cjs +424 -105
- package/gsd-core/bin/lib/state.cjs +1927 -401
- package/gsd-core/bin/lib/surface.cjs +35 -10
- package/gsd-core/bin/lib/text-lines.cjs +80 -0
- package/gsd-core/bin/lib/token-scanner.cjs +76 -0
- package/gsd-core/bin/lib/uat-predicate.cjs +20 -4
- package/gsd-core/bin/lib/uat.cjs +706 -64
- package/gsd-core/bin/lib/ui-frontend-evidence.cjs +157 -0
- package/gsd-core/bin/lib/ui-safety-gate.cjs +14 -5
- package/gsd-core/bin/lib/unusable-input.cjs +33 -0
- package/gsd-core/bin/lib/update-context.cjs +8 -2
- package/gsd-core/bin/lib/user-artifact-staging.cjs +705 -0
- package/gsd-core/bin/lib/validate.cjs +20 -6
- package/gsd-core/bin/lib/vendor/README.md +37 -0
- package/gsd-core/bin/lib/vendor/re2js.cjs +6480 -0
- package/gsd-core/bin/lib/vendor/re2js.d.cts +938 -0
- package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +287 -20
- package/gsd-core/bin/lib/verify.cjs +368 -880
- package/gsd-core/bin/lib/workflow-fragments.cjs +557 -0
- package/gsd-core/bin/lib/workstream-inventory-builder.cjs +203 -19
- package/gsd-core/bin/lib/workstream-inventory.cjs +576 -31
- package/gsd-core/bin/lib/workstream.cjs +8 -2
- package/gsd-core/bin/lib/worktree-base-ref.cjs +50 -6
- package/gsd-core/bin/lib/worktree-safety.cjs +450 -125
- package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +9 -1
- package/gsd-core/references/agent-contracts.md +43 -26
- package/gsd-core/references/artifact-types.md +10 -3
- package/gsd-core/references/autonomous-ui-design-contract.md +42 -0
- package/gsd-core/references/checkpoints.md +2 -2
- package/gsd-core/references/context-budget.md +1 -1
- package/gsd-core/references/debugger-techniques.md +255 -0
- package/gsd-core/references/dispatch-isolation-gate.md +138 -0
- package/gsd-core/references/doc-conflict-engine.md +1 -1
- package/gsd-core/references/execute-mvp-tdd.md +3 -3
- package/gsd-core/references/execute-phase-between-wave-reset.md +6 -2
- package/gsd-core/references/execute-phase-context-guard.md +1 -1
- package/gsd-core/references/execute-phase-response-language.md +1 -1
- package/gsd-core/references/execute-phase-wave-guard.md +6 -2
- package/gsd-core/references/gate-prompts.md +1 -1
- package/gsd-core/references/git-planning-commit.md +2 -1
- package/gsd-core/references/loop-hook-dispatch.md +39 -2
- package/gsd-core/references/model-profiles.md +12 -4
- package/gsd-core/references/mvp-concepts.md +9 -9
- package/gsd-core/references/planner-guidance.md +3 -9
- package/gsd-core/references/planner-preconditions.md +1 -1
- package/gsd-core/references/planner-reviews.md +1 -1
- package/gsd-core/references/planning-config.md +8 -6
- package/gsd-core/references/research-documentation-lookup.md +5 -3
- package/gsd-core/references/revision-loop.md +1 -1
- package/gsd-core/references/specless-probe-fallback.md +8 -7
- package/gsd-core/references/universal-anti-patterns.md +3 -3
- package/gsd-core/references/verifier-phase-gates.md +192 -0
- package/gsd-core/references/verifier-wiring-patterns.md +100 -0
- package/gsd-core/references/verify-mvp-mode.md +1 -1
- package/gsd-core/references/workstream-flag.md +22 -6
- package/gsd-core/references/worktree-branch-check.md +2 -2
- package/gsd-core/templates/discussion-log.md +1 -1
- package/gsd-core/templates/phase-prompt.md +2 -4
- package/gsd-core/templates/state.md +4 -4
- package/gsd-core/templates/summary-complex.md +2 -0
- package/gsd-core/templates/summary-minimal.md +2 -0
- package/gsd-core/templates/summary-standard.md +2 -0
- package/gsd-core/templates/summary.md +2 -0
- package/gsd-core/templates/verification-report.md +9 -1
- package/gsd-core/workflows/ai-integration-phase.md +9 -11
- package/gsd-core/workflows/audit-milestone.md +3 -0
- package/gsd-core/workflows/autonomous/steps/converge-banner.md +1 -0
- package/gsd-core/workflows/autonomous/steps/converge-dispatch-bg.md +11 -0
- package/gsd-core/workflows/autonomous/steps/converge-dispatch-inline.md +7 -0
- package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +21 -0
- package/gsd-core/workflows/autonomous/steps/converge-loop.md +7 -0
- package/gsd-core/workflows/autonomous.md +33 -70
- package/gsd-core/workflows/cleanup.md +62 -3
- package/gsd-core/workflows/code-review/steps/dispatch-fix.md +39 -0
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +93 -0
- package/gsd-core/workflows/code-review-fix.md +37 -10
- package/gsd-core/workflows/code-review.md +74 -166
- package/gsd-core/workflows/complete-milestone/steps/git-tag.md +29 -0
- package/gsd-core/workflows/complete-milestone.md +160 -95
- package/gsd-core/workflows/debug.md +16 -17
- package/gsd-core/workflows/diagnose-issues.md +56 -8
- package/gsd-core/workflows/discuss-phase/modes/chain.md +2 -1
- package/gsd-core/workflows/discuss-phase/modes/default.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +15 -0
- package/gsd-core/workflows/discuss-phase-assumptions.md +7 -17
- package/gsd-core/workflows/docs-update/steps/dispatch-monorepo-packages.md +51 -0
- package/gsd-core/workflows/docs-update.md +8 -51
- package/gsd-core/workflows/edit-phase.md +26 -1
- package/gsd-core/workflows/eval-review.md +3 -5
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +64 -7
- package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +50 -0
- package/gsd-core/workflows/execute-phase/steps/partial-wave.md +31 -0
- package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +77 -0
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +21 -0
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +42 -0
- package/gsd-core/workflows/execute-phase/steps/regression-gate.md +43 -37
- package/gsd-core/workflows/execute-phase.md +103 -187
- package/gsd-core/workflows/execute-plan.md +36 -4
- package/gsd-core/workflows/explore.md +131 -4
- package/gsd-core/workflows/fast.md +10 -2
- package/gsd-core/workflows/health.md +73 -4
- package/gsd-core/workflows/help/modes/full.md +6 -1
- package/gsd-core/workflows/import.md +4 -4
- package/gsd-core/workflows/ingest-docs.md +7 -6
- package/gsd-core/workflows/mvp-phase.md +6 -3
- package/gsd-core/workflows/new-milestone/steps/project-md-milestone-write.md +16 -0
- package/gsd-core/workflows/new-milestone/steps/reset-phase-safety.md +19 -0
- package/gsd-core/workflows/new-milestone.md +35 -47
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +176 -0
- package/gsd-core/workflows/new-project/steps/auto-mode-detection.md +32 -0
- package/gsd-core/workflows/new-project/steps/codebase-map-offer.md +18 -0
- package/gsd-core/workflows/new-project.md +27 -240
- package/gsd-core/workflows/next.md +12 -0
- package/gsd-core/workflows/plan-phase/steps/adr-ingest-express-path.md +15 -0
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +110 -0
- package/gsd-core/workflows/plan-phase/steps/prd-express-gate.md +8 -0
- package/gsd-core/workflows/plan-phase/steps/research-only-early-exit.md +17 -0
- package/gsd-core/workflows/plan-phase/steps/research-only-modifiers.md +16 -0
- package/gsd-core/workflows/plan-phase/steps/reviews-prerequisite.md +17 -0
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +149 -0
- package/gsd-core/workflows/plan-phase.md +89 -209
- package/gsd-core/workflows/plan-review-convergence.md +50 -2
- package/gsd-core/workflows/progress/steps/forensic-audit.md +125 -0
- package/gsd-core/workflows/progress/steps/mvp-display.md +18 -0
- package/gsd-core/workflows/progress.md +45 -159
- package/gsd-core/workflows/quick/steps/discussion-phase.md +124 -0
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +111 -0
- package/gsd-core/workflows/quick/steps/quick-verification.md +67 -0
- package/gsd-core/workflows/quick/steps/research-phase.md +72 -0
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +37 -0
- package/gsd-core/workflows/quick.md +55 -405
- package/gsd-core/workflows/resume-project.md +3 -0
- package/gsd-core/workflows/review/steps/reviewer-instances-note-1.md +4 -0
- package/gsd-core/workflows/review/steps/reviewer-instances-note-2.md +3 -0
- package/gsd-core/workflows/review.md +41 -13
- package/gsd-core/workflows/section-manifest.json +219 -0
- package/gsd-core/workflows/secure-phase.md +1 -1
- package/gsd-core/workflows/session-report.md +2 -1
- package/gsd-core/workflows/settings.md +66 -2
- package/gsd-core/workflows/ship.md +104 -44
- package/gsd-core/workflows/sketch.md +1 -1
- package/gsd-core/workflows/spec-phase.md +41 -20
- package/gsd-core/workflows/spike-wrap-up.md +20 -5
- package/gsd-core/workflows/spike.md +50 -16
- package/gsd-core/workflows/sync-skills.md +106 -13
- package/gsd-core/workflows/transition/steps/workstream-collision-check.md +17 -0
- package/gsd-core/workflows/transition.md +53 -31
- package/gsd-core/workflows/ui-phase.md +13 -12
- package/gsd-core/workflows/ui-review.md +2 -2
- package/gsd-core/workflows/update/steps/channel-banner.md +7 -0
- package/gsd-core/workflows/update.md +19 -8
- package/gsd-core/workflows/validate-phase.md +1 -1
- package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +36 -0
- package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +21 -0
- package/gsd-core/workflows/verify-work.md +17 -65
- package/hooks/dist/gsd-agent-isolation-guard.js +517 -0
- package/hooks/dist/gsd-check-update-worker.js +64 -12
- package/hooks/dist/gsd-check-update.js +19 -1
- package/hooks/dist/gsd-cursor-pre-tool.js +0 -3
- package/hooks/dist/gsd-cursor-subagent-start.js +607 -26
- package/hooks/dist/gsd-cursor-subagent-stop.js +3 -2
- package/hooks/dist/gsd-prompt-guard.js +21 -20
- package/hooks/dist/gsd-read-injection-scanner.js +45 -24
- package/hooks/dist/gsd-statusline.js +90 -6
- package/hooks/dist/gsd-update-banner.js +22 -1
- package/hooks/dist/gsd-workflow-guard.js +134 -36
- package/hooks/dist/gsd-worktree-path-guard.js +2 -1
- package/hooks/dist/gsd-write-guard.js +359 -0
- package/hooks/dist/lib/git-cmd.js +92 -59
- package/hooks/dist/lib/injection-patterns.js +45 -0
- package/hooks/dist/lib/isolation-deny-reason.js +39 -0
- package/hooks/dist/lib/isolation-sentinel.js +277 -0
- package/hooks/dist/managed-hooks-registry.cjs +2 -0
- package/hooks/gsd-agent-isolation-guard.js +517 -0
- package/hooks/gsd-check-update-worker.js +64 -12
- package/hooks/gsd-check-update.js +19 -1
- package/hooks/gsd-cursor-pre-tool.js +0 -3
- package/hooks/gsd-cursor-subagent-start.js +607 -26
- package/hooks/gsd-cursor-subagent-stop.js +3 -2
- package/hooks/gsd-prompt-guard.js +21 -20
- package/hooks/gsd-read-injection-scanner.js +45 -24
- package/hooks/gsd-statusline.js +90 -6
- package/hooks/gsd-update-banner.js +22 -1
- package/hooks/gsd-workflow-guard.js +134 -36
- package/hooks/gsd-worktree-path-guard.js +2 -1
- package/hooks/gsd-write-guard.js +359 -0
- package/hooks/hooks.json +12 -0
- package/hooks/lib/git-cmd.js +92 -59
- package/hooks/lib/injection-patterns.js +45 -0
- package/hooks/lib/isolation-deny-reason.js +39 -0
- package/hooks/lib/isolation-sentinel.js +277 -0
- package/hooks/managed-hooks-registry.cjs +2 -0
- package/package.json +31 -10
- package/pi/gsd.cjs +71 -12
- package/scripts/baselines/planning-prompt-drift-baseline.json +4 -0
- package/scripts/baselines/planning-snapshot-bypass-baseline.json +12 -0
- package/scripts/baselines/unreachable-guard-drift-baseline.json +4 -0
- package/scripts/build-hooks.js +9 -0
- package/scripts/changeset/lint.cjs +68 -6
- package/scripts/changeset/serialize.cjs +5 -1
- package/scripts/check-alias-drift.cjs +7 -43
- package/scripts/check-contract-drift.cjs +297 -0
- package/scripts/ci-test-scope.cjs +19 -2
- package/scripts/command-contract-helpers.cjs +903 -1
- package/scripts/gen-adr-index.cjs +728 -38
- package/scripts/gen-capability-matrix.cjs +1 -1
- package/scripts/gen-capability-registry.cjs +3 -15
- package/scripts/gen-context-index.cjs +439 -0
- package/scripts/gen-health-docs.cjs +390 -0
- package/scripts/gen-inventory-manifest.cjs +150 -4
- package/scripts/gen-loop-host-contract.cjs +4 -24
- package/scripts/gen-prompt-budget-parity-corpus.cjs +645 -0
- package/scripts/gen-registry.cjs +3 -14
- package/scripts/gen-section-manifest.cjs +638 -0
- package/scripts/generate-package-identity.cjs +4 -2
- package/scripts/lib/alias-drift-families.cjs +46 -0
- package/scripts/lib/drift-scan.cjs +278 -0
- package/scripts/lint-allow-test-rule-refs.allowlist.json +15 -54
- package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +4 -0
- package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +3 -0
- package/scripts/lint-canary-version-leak.cjs +73 -0
- package/scripts/lint-command-contract.cjs +96 -13
- package/scripts/lint-compiled-artifact-sync.cjs +6 -1
- package/scripts/lint-completion-predicate-drift.cjs +933 -0
- package/scripts/lint-completion-ratio-drift.cjs +214 -0
- package/scripts/lint-default-flip-documentation.cjs +193 -0
- package/scripts/lint-docs-command-form.cjs +195 -0
- package/scripts/lint-docs-required.cjs +9 -1
- package/scripts/lint-emitted-drift-ack.cjs +215 -20
- package/scripts/lint-eslint-glob-coverage.allowlist.json +34 -0
- package/scripts/lint-eslint-glob-coverage.cjs +340 -0
- package/scripts/lint-example-parser-parity.cjs +395 -0
- package/scripts/lint-frontmatter-scalar-broad-grep.cjs +237 -0
- package/scripts/lint-health-diagnostic-rule-table.cjs +404 -0
- package/scripts/lint-hooks-runtime-build-seam.cjs +262 -0
- package/scripts/lint-milestone-window-drift.cjs +468 -0
- package/scripts/lint-phase-enumeration-drift.cjs +479 -0
- package/scripts/lint-plan-count-drift.cjs +318 -0
- package/scripts/lint-planning-artifact-writer-drift.cjs +398 -0
- package/scripts/lint-planning-prompt-drift.cjs +434 -0
- package/scripts/lint-planning-snapshot-bypass-drift.cjs +544 -0
- package/scripts/lint-regression-test-names.cjs +15 -13
- package/scripts/lint-removed-but-needed.cjs +320 -0
- package/scripts/lint-state-field-drift.cjs +805 -0
- package/scripts/lint-state-write-path-drift.cjs +1045 -0
- package/scripts/lint-test-file-count.allowlist.json +40 -3
- package/scripts/lint-unreachable-guard-drift.cjs +843 -0
- package/scripts/lint-vendored-deps.cjs +124 -0
- package/scripts/mutation-matrix.cjs +13 -0
- package/scripts/pr-changed-files.cjs +63 -0
- package/scripts/pr-template-policy.cjs +14 -4
- package/scripts/prompt-injection-scan.sh +52 -6
- package/scripts/require-issue-link-policy.cjs +192 -0
- package/scripts/state-write-path-drift-baseline.json +19 -0
- package/scripts/sync-runtime-launcher.cjs +2 -4
- package/skills/gsd-autonomous/SKILL.md +0 -1
- package/skills/gsd-code-review/SKILL.md +1 -1
- package/skills/gsd-execute-phase/SKILL.md +1 -2
- package/skills/gsd-map-codebase/SKILL.md +1 -1
- package/skills/gsd-mempalace-capture/SKILL.md +2 -2
- package/skills/gsd-mempalace-recall/SKILL.md +1 -1
- package/skills/gsd-new-milestone/SKILL.md +2 -2
- package/skills/gsd-next/SKILL.md +0 -1
- package/skills/gsd-plan-phase/SKILL.md +1 -2
- package/skills/gsd-progress/SKILL.md +0 -1
- package/skills/gsd-quick/SKILL.md +1 -1
- package/skills/gsd-review-backlog/SKILL.md +2 -1
- package/skills/gsd-stats/SKILL.md +0 -1
- package/skills/gsd-verify-work/SKILL.md +1 -1
- package/vscode/package.json +1 -1
- package/gsd-core/workflows/discovery-phase.md +0 -298
- package/gsd-core/workflows/plan-milestone-gaps.md +0 -281
- package/gsd-core/workflows/verify-phase.md +0 -577
- package/scripts/affected-tests-lib.cjs +0 -554
- package/scripts/gen-emitted-baseline.cjs +0 -145
- package/scripts/lint-allow-test-rule-refs.cjs +0 -162
- package/scripts/run-affected-tests.cjs +0 -7
- package/scripts/run-tests.cjs +0 -1050
|
@@ -19,7 +19,33 @@ Parse arguments and load project state:
|
|
|
19
19
|
```bash
|
|
20
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 "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; 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
21
|
PHASE_ARG="${1}"
|
|
22
|
-
|
|
22
|
+
|
|
23
|
+
# Parse all code-review flags into a structured IR via code-review-flags.cjs.
|
|
24
|
+
# This is the canonical flag-parsing surface — do not replicate inline bash parsing
|
|
25
|
+
# for --fix/--all/--auto here; the module handles all flag extraction and implication
|
|
26
|
+
# logic (e.g., --all and --auto imply --fix). Resolved BEFORE the init call below so
|
|
27
|
+
# the section-manifest gate forwards the RESOLVED (post-implication) fix decision, not
|
|
28
|
+
# just a literal --fix token check.
|
|
29
|
+
FLAGS_JSON=$(node -e "
|
|
30
|
+
const { parseCodeReviewFlags } = require('./gsd-core/bin/lib/code-review-flags.cjs');
|
|
31
|
+
const flags = parseCodeReviewFlags(process.argv.slice(1));
|
|
32
|
+
process.stdout.write(JSON.stringify(flags));
|
|
33
|
+
" -- "$@" 2>/dev/null)
|
|
34
|
+
|
|
35
|
+
# Extract individual flag values from the IR
|
|
36
|
+
FIX_FLAG=$(echo "$FLAGS_JSON" | node -e "process.stdout.write(String(JSON.parse(require('fs').readFileSync('/dev/stdin','utf-8')).fix))")
|
|
37
|
+
FIX_ALL=$(echo "$FLAGS_JSON" | node -e "process.stdout.write(String(JSON.parse(require('fs').readFileSync('/dev/stdin','utf-8')).all))")
|
|
38
|
+
FIX_AUTO=$(echo "$FLAGS_JSON" | node -e "process.stdout.write(String(JSON.parse(require('fs').readFileSync('/dev/stdin','utf-8')).auto))")
|
|
39
|
+
DEPTH_OVERRIDE=$(echo "$FLAGS_JSON" | node -e "process.stdout.write(JSON.parse(require('fs').readFileSync('/dev/stdin','utf-8')).depth)")
|
|
40
|
+
FILES_OVERRIDE=$(echo "$FLAGS_JSON" | node -e "process.stdout.write(JSON.parse(require('fs').readFileSync('/dev/stdin','utf-8')).files)")
|
|
41
|
+
|
|
42
|
+
# Forward the resolved fix decision (--fix itself, or --all/--auto implying it) to
|
|
43
|
+
# init.code-review so section_manifest's flag:--fix gating (dispatch-fix section)
|
|
44
|
+
# matches code-review-flags.cjs's own implication logic rather than a raw token scan.
|
|
45
|
+
FIX_PARAM=""
|
|
46
|
+
if [ "$FIX_FLAG" = "true" ]; then FIX_PARAM="--fix"; fi
|
|
47
|
+
|
|
48
|
+
INIT=$(gsd_run query init.code-review "${PHASE_ARG}" $FIX_PARAM)
|
|
23
49
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
24
50
|
AGENT_SKILLS_REVIEWER=$(gsd_run query agent-skills gsd-code-reviewer)
|
|
25
51
|
# #2072: resolve the routed model so model_overrides / models.verification are honored
|
|
@@ -27,7 +53,7 @@ AGENT_SKILLS_REVIEWER=$(gsd_run query agent-skills gsd-code-reviewer)
|
|
|
27
53
|
REVIEWER_MODEL=$(gsd_run query resolve-model gsd-code-reviewer --raw)
|
|
28
54
|
```
|
|
29
55
|
|
|
30
|
-
Parse from init JSON: `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `padded_phase`, `commit_docs`.
|
|
56
|
+
Parse from init JSON: `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `padded_phase`, `commit_docs`, `fallow_enabled`, `fallow_scope`, `fallow_profile`, `fallow_mcp`, `fallow_max_crap`.
|
|
31
57
|
|
|
32
58
|
**Input sanitization (defense-in-depth):**
|
|
33
59
|
```bash
|
|
@@ -46,27 +72,6 @@ Error: Phase ${PHASE_ARG} not found. Run /gsd:progress to see available phases.
|
|
|
46
72
|
|
|
47
73
|
This runs BEFORE config gate check so user errors are surfaced immediately regardless of config state.
|
|
48
74
|
|
|
49
|
-
Parse optional flags from $ARGUMENTS using the typed flag parser:
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
# Parse all code-review flags into a structured IR via code-review-flags.cjs.
|
|
53
|
-
# This is the canonical flag-parsing surface — do not replicate inline bash parsing
|
|
54
|
-
# for --fix/--all/--auto here; the module handles all flag extraction and implication
|
|
55
|
-
# logic (e.g., --all and --auto imply --fix).
|
|
56
|
-
FLAGS_JSON=$(node -e "
|
|
57
|
-
const { parseCodeReviewFlags } = require('./gsd-core/bin/lib/code-review-flags.cjs');
|
|
58
|
-
const flags = parseCodeReviewFlags(process.argv.slice(1));
|
|
59
|
-
process.stdout.write(JSON.stringify(flags));
|
|
60
|
-
" -- "$@" 2>/dev/null)
|
|
61
|
-
|
|
62
|
-
# Extract individual flag values from the IR
|
|
63
|
-
FIX_FLAG=$(echo "$FLAGS_JSON" | node -e "process.stdout.write(String(JSON.parse(require('fs').readFileSync('/dev/stdin','utf-8')).fix))")
|
|
64
|
-
FIX_ALL=$(echo "$FLAGS_JSON" | node -e "process.stdout.write(String(JSON.parse(require('fs').readFileSync('/dev/stdin','utf-8')).all))")
|
|
65
|
-
FIX_AUTO=$(echo "$FLAGS_JSON" | node -e "process.stdout.write(String(JSON.parse(require('fs').readFileSync('/dev/stdin','utf-8')).auto))")
|
|
66
|
-
DEPTH_OVERRIDE=$(echo "$FLAGS_JSON" | node -e "process.stdout.write(JSON.parse(require('fs').readFileSync('/dev/stdin','utf-8')).depth)")
|
|
67
|
-
FILES_OVERRIDE=$(echo "$FLAGS_JSON" | node -e "process.stdout.write(JSON.parse(require('fs').readFileSync('/dev/stdin','utf-8')).files)")
|
|
68
|
-
```
|
|
69
|
-
|
|
70
75
|
If FILES_OVERRIDE is set, split by comma into array:
|
|
71
76
|
```bash
|
|
72
77
|
if [ -n "$FILES_OVERRIDE" ]; then
|
|
@@ -231,8 +236,27 @@ Additionally, whenever a reliable diff base is available, cross-check the SUMMAR
|
|
|
231
236
|
against the diff and warn about (then add) any changed files the SUMMARY extractor did not
|
|
232
237
|
surface — so a partial SUMMARY result can no longer silently mask the rest of the phase.
|
|
233
238
|
```bash
|
|
234
|
-
# Compute diff base from phase commits — fail closed if no reliable base found
|
|
235
|
-
|
|
239
|
+
# Compute diff base from phase commits — fail closed if no reliable base found.
|
|
240
|
+
# #3503: anchor the grep to GSD's own conventional-commit phase scopes — the
|
|
241
|
+
# subject-line formats this system itself emits (docs(phase-N): from
|
|
242
|
+
# execute-phase.md, plan scopes feat(N-MM):/test(N-MM): from references/tdd.md,
|
|
243
|
+
# bare phase scopes docs(N):). The #2989/#3191 prose anchor "[Pp]hase N"
|
|
244
|
+
# matched free prose in ANY commit body — planning commits forward-reference
|
|
245
|
+
# later phases ("deferred to Phase N per D-09"), doc commits use "### Phase N"
|
|
246
|
+
# as a format example — and tail -1 (oldest match) turned each false positive
|
|
247
|
+
# into a base unboundedly before the phase, while GSD's own scope commits
|
|
248
|
+
# never contain the literal "Phase N" at all. The ^ anchor makes this a
|
|
249
|
+
# subject-line match, so commit-body prose can never capture the base.
|
|
250
|
+
# Workflows emit the UNPADDED roadmap phase number (docs(phase-6):) while
|
|
251
|
+
# PADDED_PHASE is zero-padded ("06") — accept both spellings.
|
|
252
|
+
# #3191: stay POSIX-ERE portable — the boundary is the closing paren + colon,
|
|
253
|
+
# never \b (not a POSIX ERE token; under --extended-regexp it silently matches
|
|
254
|
+
# nothing on macOS regex(3), making this fallback dead on Apple platforms).
|
|
255
|
+
PHASE_SCOPE_NUM="${PADDED_PHASE}"
|
|
256
|
+
case "${PADDED_PHASE}" in
|
|
257
|
+
0[0-9]*) PHASE_SCOPE_NUM="${PADDED_PHASE#0}|${PADDED_PHASE}" ;;
|
|
258
|
+
esac
|
|
259
|
+
PHASE_COMMITS=$(git log --oneline --all --extended-regexp --grep="^[[:alpha:]]+!?\((phase-)?(${PHASE_SCOPE_NUM})(-[0-9]+)?\)!?:" --format="%H" 2>/dev/null)
|
|
236
260
|
DIFF_BASE=""
|
|
237
261
|
if [ -n "$PHASE_COMMITS" ]; then
|
|
238
262
|
DIFF_BASE=$(echo "$PHASE_COMMITS" | tail -1)^
|
|
@@ -296,7 +320,7 @@ fi
|
|
|
296
320
|
|
|
297
321
|
**Post-processing (all tiers):**
|
|
298
322
|
|
|
299
|
-
1. **Expand tilde paths:** SUMMARY.md `key-files` entries may record a `~/...`-prefixed path (e.g. `~/.claude/gsd-core/workflows/verify-
|
|
323
|
+
1. **Expand tilde paths:** SUMMARY.md `key-files` entries may record a `~/...`-prefixed path (e.g. `~/.claude/gsd-core/workflows/verify-work.md`). Bash only tilde-expands a literal `~` written in source text, never one arriving as the value of an already-expanded variable, so every later `[ -f "$file" ]` check must see a real, expanded path or it misclassifies the file as deleted.
|
|
300
324
|
```bash
|
|
301
325
|
EXPANDED_FILES=()
|
|
302
326
|
for file in "${REVIEW_FILES[@]}"; do
|
|
@@ -389,20 +413,7 @@ Exit workflow. Do NOT spawn agent or create REVIEW.md.
|
|
|
389
413
|
<step name="structural_pre_pass">
|
|
390
414
|
Optional structural cross-module pass powered by fallow.
|
|
391
415
|
|
|
392
|
-
|
|
393
|
-
```bash
|
|
394
|
-
FALLOW_ENABLED=$(gsd_run query config-get code_quality.fallow.enabled 2>/dev/null || echo "false")
|
|
395
|
-
FALLOW_SCOPE=$(gsd_run query config-get code_quality.fallow.scope 2>/dev/null || echo "phase")
|
|
396
|
-
FALLOW_PROFILE=$(gsd_run query config-get code_quality.fallow.profile 2>/dev/null || echo "standard")
|
|
397
|
-
FALLOW_MCP=$(gsd_run query config-get code_quality.fallow.mcp 2>/dev/null || echo "false")
|
|
398
|
-
# profile maps to a --max-crap threshold since fallow has no native profile concept.
|
|
399
|
-
# minimal=50 (more lenient), standard=30 (default), strict=15 (tighter).
|
|
400
|
-
case "$FALLOW_PROFILE" in
|
|
401
|
-
minimal) FALLOW_MAX_CRAP=50 ;;
|
|
402
|
-
strict) FALLOW_MAX_CRAP=15 ;;
|
|
403
|
-
*) FALLOW_MAX_CRAP=30 ;; # standard (default)
|
|
404
|
-
esac
|
|
405
|
-
```
|
|
416
|
+
Parse `fallow_enabled`, `fallow_scope`, `fallow_profile`, `fallow_mcp`, `fallow_max_crap` from the init JSON as `FALLOW_ENABLED`, `FALLOW_SCOPE`, `FALLOW_PROFILE`, `FALLOW_MCP`, `FALLOW_MAX_CRAP`. These are resolved once by `init.code-review` at init time — consuming the pre-resolved values here (instead of a `config-get` call inside this step) avoids gating this section's own inclusion on a fact its own body would otherwise compute (see `state:fallow-enabled` in docs/reference/workflow-fragments.md).
|
|
406
417
|
|
|
407
418
|
Defaults are fail-closed and opt-in:
|
|
408
419
|
- `enabled=false` (skip entirely)
|
|
@@ -410,88 +421,9 @@ Defaults are fail-closed and opt-in:
|
|
|
410
421
|
- `profile=standard` (maps to `--max-crap 30`; minimal=50, standard=30, strict=15 — fallow has no native profile concept)
|
|
411
422
|
- `mcp=false`
|
|
412
423
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
```bash
|
|
417
|
-
FALLOW_BIN=$(FALLOW_CWD="$(pwd)" node -e "
|
|
418
|
-
const { resolveFallowBinary } = require('./gsd-core/bin/lib/fallow-runner.cjs');
|
|
419
|
-
const resolved = resolveFallowBinary({ cwd: process.env.FALLOW_CWD });
|
|
420
|
-
if (resolved) process.stdout.write(resolved);
|
|
421
|
-
")
|
|
422
|
-
```
|
|
423
|
-
|
|
424
|
-
2) If binary is missing, fail with actionable message:
|
|
425
|
-
```bash
|
|
426
|
-
if [ -z \"$FALLOW_BIN\" ]; then
|
|
427
|
-
echo \"Error: fallow is enabled but no binary was found.\"
|
|
428
|
-
echo \"Install fallow via \`npm install -D fallow\` or \`cargo install fallow\`.\"
|
|
429
|
-
# Exit workflow
|
|
430
|
-
fi
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
3) Execute structural pass and persist JSON (bounded at 120s). Note: `fallow audit` exits 0 when clean and 1 when issues are found — BOTH are successful runs. Only a timeout (124), usage error (2), or crash yields no usable JSON; success is decided by whether the output parses as a valid fallow report, not by exit code:
|
|
434
|
-
```bash
|
|
435
|
-
FALLOW_JSON_PATH="${PHASE_DIR}/FALLOW.json"
|
|
436
|
-
FALLOW_STDERR_TMP=$(mktemp)
|
|
437
|
-
|
|
438
|
-
# Phase scope uses fallow's native changed-files scoping (--changed-since <base>).
|
|
439
|
-
# Derive the phase base commit; if none is found, fall back to repo scope (fallow
|
|
440
|
-
# auto-detects the base branch).
|
|
441
|
-
FALLOW_SCOPE_ARGS=()
|
|
442
|
-
if [ \"$FALLOW_SCOPE\" = \"phase\" ]; then
|
|
443
|
-
FALLOW_PHASE_COMMITS=$(git log --oneline --all --grep=\"${PADDED_PHASE}\" --format=\"%H\" 2>/dev/null)
|
|
444
|
-
if [ -n \"$FALLOW_PHASE_COMMITS\" ]; then
|
|
445
|
-
FALLOW_BASE=$(echo \"$FALLOW_PHASE_COMMITS\" | tail -1)^
|
|
446
|
-
FALLOW_SCOPE_ARGS=(--changed-since \"$FALLOW_BASE\")
|
|
447
|
-
fi
|
|
448
|
-
fi
|
|
449
|
-
|
|
450
|
-
gsd_run run-with-timeout 120 -- \"$FALLOW_BIN\" audit --format json --quiet --max-crap \"$FALLOW_MAX_CRAP\" \"${FALLOW_SCOPE_ARGS[@]+\"${FALLOW_SCOPE_ARGS[@]}\"}\" > \"${FALLOW_JSON_PATH}.tmp\" 2>\"$FALLOW_STDERR_TMP\"
|
|
451
|
-
FALLOW_EXIT=$?
|
|
452
|
-
|
|
453
|
-
# fallow exits 0 (clean) or 1 (issues found) — BOTH are successful runs that produce a
|
|
454
|
-
# valid JSON report. Only a timeout (124), usage error (2), or crash yields no usable JSON.
|
|
455
|
-
# Decide success by whether the output parses as a fallow report, not by exit code.
|
|
456
|
-
FALLOW_OK=$(FALLOW_TMP=\"${FALLOW_JSON_PATH}.tmp\" node -e \"
|
|
457
|
-
try {
|
|
458
|
-
const fs = require('fs');
|
|
459
|
-
const txt = fs.readFileSync(process.env.FALLOW_TMP, 'utf8');
|
|
460
|
-
const o = JSON.parse(txt);
|
|
461
|
-
process.stdout.write(o && typeof o === 'object' && 'verdict' in o ? '1' : '0');
|
|
462
|
-
} catch { process.stdout.write('0'); }
|
|
463
|
-
\")
|
|
464
|
-
if [ \"$FALLOW_OK\" != \"1\" ]; then
|
|
465
|
-
FALLOW_STDERR_SUMMARY=$(head -5 \"$FALLOW_STDERR_TMP\")
|
|
466
|
-
rm -f \"${FALLOW_JSON_PATH}.tmp\" \"$FALLOW_STDERR_TMP\"
|
|
467
|
-
# #2667: distinguish a hard EXECUTION failure (the binary was found at step 1
|
|
468
|
-
# but would not run) from the binary-missing path (step 2). Exit 124 = timeout,
|
|
469
|
-
# 2 = usage error, 125 = spawn failure (e.g. Windows EINVAL on a .cmd shim —
|
|
470
|
-
# CVE-2024-27980, now mediated by run-with-timeout), 126/127 = not executable /
|
|
471
|
-
# not found. A non-zero exit here with a resolved binary means fallow is
|
|
472
|
-
# installed but did not produce a report — surface that loudly so a Windows
|
|
473
|
-
# user does not mistake it for "fallow absent".
|
|
474
|
-
case \"$FALLOW_EXIT\" in
|
|
475
|
-
124) FALLOW_FAIL_KIND=\"timed out\" ;;
|
|
476
|
-
2) FALLOW_FAIL_KIND=\"usage error\" ;;
|
|
477
|
-
125) FALLOW_FAIL_KIND=\"spawn failure (the binary was found but did not start — e.g. a Windows .cmd shim; run-with-timeout mediates this)\" ;;
|
|
478
|
-
126) FALLOW_FAIL_KIND=\"not executable\" ;;
|
|
479
|
-
127) FALLOW_FAIL_KIND=\"not found\" ;;
|
|
480
|
-
*) FALLOW_FAIL_KIND=\"crashed\" ;;
|
|
481
|
-
esac
|
|
482
|
-
echo \"WARNING: fallow structural pre-pass failed (${FALLOW_FAIL_KIND}, exit ${FALLOW_EXIT}): ${FALLOW_STDERR_SUMMARY}\"
|
|
483
|
-
FALLOW_JSON_PATH=\"\"
|
|
484
|
-
else
|
|
485
|
-
mv \"${FALLOW_JSON_PATH}.tmp\" \"$FALLOW_JSON_PATH\"
|
|
486
|
-
rm -f \"$FALLOW_STDERR_TMP\"
|
|
487
|
-
fi
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
On any failure of the structural pre-pass (binary missing at step 2, or an execution failure here — timeout, spawn failure, crash, empty output, or unparseable JSON), the workflow continues with no `<structural_findings>` injection; the reviewer agent receives a normal review request. The WARNING above names the failure KIND so a hard execution failure (e.g. a Windows `.cmd` spawn failure) is not mistaken for an absent optional dependency.
|
|
491
|
-
|
|
492
|
-
4) Optional MCP bridge path (runtime-dependent):
|
|
493
|
-
- If `FALLOW_MCP=true`, set reviewer input mode to MCP-backed structural findings.
|
|
494
|
-
- Otherwise pass static JSON findings from `FALLOW.json`.
|
|
424
|
+
<!-- gsd:section id="structural-pre-pass" when="state:fallow-enabled" -->
|
|
425
|
+
If `section_manifest` is `null` or `"structural-pre-pass"` is in its `included` list: read and execute `gsd-core/workflows/code-review/steps/structural-pre-pass.md`. Otherwise skip — do not read the file.
|
|
426
|
+
<!-- /gsd:section -->
|
|
495
427
|
|
|
496
428
|
When disabled, set:
|
|
497
429
|
```bash
|
|
@@ -505,17 +437,29 @@ Compute the review output path:
|
|
|
505
437
|
REVIEW_PATH="${PHASE_DIR}/${PADDED_PHASE}-REVIEW.md"
|
|
506
438
|
```
|
|
507
439
|
|
|
508
|
-
Compute DIFF_BASE for agent context (in case agent needs it):
|
|
440
|
+
Compute DIFF_BASE for agent context (in case agent needs it). #3191/#3503: this
|
|
441
|
+
must be the SAME anchored, POSIX-portable conventional-commit-scope derivation
|
|
442
|
+
the Tier-3 scope step uses — the reviewer agent consumes `diff_base` exactly
|
|
443
|
+
when `files:` is empty, i.e. the same fail-closed scenario Tier 3 protects, so
|
|
444
|
+
a divergent recomputation here re-arms the mis-scoping one tier down:
|
|
509
445
|
```bash
|
|
510
|
-
|
|
446
|
+
PHASE_SCOPE_NUM="${PADDED_PHASE}"
|
|
447
|
+
case "${PADDED_PHASE}" in
|
|
448
|
+
0[0-9]*) PHASE_SCOPE_NUM="${PADDED_PHASE#0}|${PADDED_PHASE}" ;;
|
|
449
|
+
esac
|
|
450
|
+
PHASE_COMMITS=$(git log --oneline --all --extended-regexp --grep="^[[:alpha:]]+!?\((phase-)?(${PHASE_SCOPE_NUM})(-[0-9]+)?\)!?:" --format="%H" 2>/dev/null)
|
|
511
451
|
if [ -n "$PHASE_COMMITS" ]; then
|
|
512
452
|
DIFF_BASE=$(echo "$PHASE_COMMITS" | tail -1)^
|
|
453
|
+
# Verify the parent commit exists (first commit in repo has no parent)
|
|
454
|
+
if ! git rev-parse "${DIFF_BASE}" >/dev/null 2>&1; then
|
|
455
|
+
DIFF_BASE=$(echo "$PHASE_COMMITS" | tail -1)
|
|
456
|
+
fi
|
|
513
457
|
else
|
|
514
458
|
DIFF_BASE=""
|
|
515
459
|
fi
|
|
516
460
|
```
|
|
517
461
|
|
|
518
|
-
Build
|
|
462
|
+
Build required_reading block for agent:
|
|
519
463
|
```bash
|
|
520
464
|
FILES_TO_READ=""
|
|
521
465
|
for file in "${REVIEW_FILES[@]}"; do
|
|
@@ -570,9 +514,9 @@ Print: `◆ Spawning code reviewer... (runs in a subagent — no output until it
|
|
|
570
514
|
|
|
571
515
|
```
|
|
572
516
|
Agent(subagent_type="gsd-code-reviewer", model="{REVIEWER_MODEL}", prompt="
|
|
573
|
-
<
|
|
517
|
+
<required_reading>
|
|
574
518
|
${FILES_TO_READ}
|
|
575
|
-
</
|
|
519
|
+
</required_reading>
|
|
576
520
|
|
|
577
521
|
${STRUCTURAL_FINDINGS_BLOCK}
|
|
578
522
|
|
|
@@ -636,45 +580,9 @@ fi
|
|
|
636
580
|
```
|
|
637
581
|
</step>
|
|
638
582
|
|
|
639
|
-
|
|
640
|
-
If
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
This step runs AFTER `commit_review` so REVIEW.md is guaranteed to be on disk before the fixer
|
|
644
|
-
is invoked. If REVIEW.md was not created (agent failed, scope was empty, etc.), the `code-review-fix.md`
|
|
645
|
-
workflow handles the missing-review error and exits cleanly.
|
|
646
|
-
|
|
647
|
-
```bash
|
|
648
|
-
if [ "$FIX_FLAG" = "true" ]; then
|
|
649
|
-
echo ""
|
|
650
|
-
echo "─────────────────────────────────────────────────────────────────"
|
|
651
|
-
echo " --fix: delegating to code-review-fix.md"
|
|
652
|
-
echo "─────────────────────────────────────────────────────────────────"
|
|
653
|
-
echo ""
|
|
654
|
-
|
|
655
|
-
# Build the fix sub-arguments: pass phase arg plus any --all/--auto flags
|
|
656
|
-
FIX_ARGS="${PHASE_ARG}"
|
|
657
|
-
if [ "$FIX_ALL" = "true" ]; then
|
|
658
|
-
FIX_ARGS="${FIX_ARGS} --all"
|
|
659
|
-
fi
|
|
660
|
-
if [ "$FIX_AUTO" = "true" ]; then
|
|
661
|
-
FIX_ARGS="${FIX_ARGS} --auto"
|
|
662
|
-
fi
|
|
663
|
-
|
|
664
|
-
# Load and execute the code-review-fix workflow.
|
|
665
|
-
# The fix workflow is the canonical implementation for all fix logic:
|
|
666
|
-
# gsd-code-fixer agent dispatch, --auto iteration loop, REVIEW-FIX.md commit,
|
|
667
|
-
# and result presentation. Do not duplicate that logic here.
|
|
668
|
-
Workflow(workflow="gsd-core/workflows/code-review-fix.md", args="${FIX_ARGS}")
|
|
669
|
-
|
|
670
|
-
# Exit after fix workflow completes — present_results is for review-only output.
|
|
671
|
-
# The fix workflow has its own present_results step.
|
|
672
|
-
# Exit workflow.
|
|
673
|
-
fi
|
|
674
|
-
```
|
|
675
|
-
|
|
676
|
-
If `FIX_FLAG` is false, skip this step entirely and proceed to `present_results`.
|
|
677
|
-
</step>
|
|
583
|
+
<!-- gsd:section id="dispatch-fix" when="flag:--fix" -->
|
|
584
|
+
If `section_manifest` is `null` or `"dispatch-fix"` is in its `included` list: read and execute `gsd-core/workflows/code-review/steps/dispatch-fix.md`. Otherwise skip — do not read the file; proceed to `present_results`.
|
|
585
|
+
<!-- /gsd:section -->
|
|
678
586
|
|
|
679
587
|
<step name="present_results">
|
|
680
588
|
Read the REVIEW.md YAML frontmatter to extract finding counts.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<step name="git_tag">
|
|
2
|
+
|
|
3
|
+
Create git tag:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
# Pre-check: skip if tag already exists (prevents silent failure on retry)
|
|
7
|
+
if git rev-parse "v[X.Y]" >/dev/null 2>&1; then echo "Tag v[X.Y] already exists, skipping"; exit 0; fi
|
|
8
|
+
git tag -a v[X.Y] -m "v[X.Y] [Name]
|
|
9
|
+
|
|
10
|
+
Delivered: [One sentence]
|
|
11
|
+
|
|
12
|
+
Key accomplishments:
|
|
13
|
+
- [Item 1]
|
|
14
|
+
- [Item 2]
|
|
15
|
+
- [Item 3]
|
|
16
|
+
|
|
17
|
+
See .planning/MILESTONES.md for full details."
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Confirm: "Tagged: v[X.Y]"
|
|
21
|
+
|
|
22
|
+
Ask: "Push tag to remote? (y/n)"
|
|
23
|
+
|
|
24
|
+
If yes:
|
|
25
|
+
```bash
|
|
26
|
+
git push origin v[X.Y]
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
</step>
|