@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
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"workflow.plan_chunked",
|
|
36
36
|
"workflow.specless_probe_fallback",
|
|
37
37
|
"workflow.plan_review_convergence",
|
|
38
|
+
"workflow.agent_hint_routing",
|
|
38
39
|
"code_quality.fallow.enabled",
|
|
39
40
|
"code_quality.fallow.scope",
|
|
40
41
|
"code_quality.fallow.profile",
|
|
@@ -63,6 +64,8 @@
|
|
|
63
64
|
"workflow.context_guard_mode",
|
|
64
65
|
"executor.stall_detect_interval_minutes",
|
|
65
66
|
"executor.stall_threshold_minutes",
|
|
67
|
+
"planner.stall_detect_interval_minutes",
|
|
68
|
+
"planner.stall_threshold_minutes",
|
|
66
69
|
"workflow.inline_plan_threshold",
|
|
67
70
|
"hooks.context_warnings",
|
|
68
71
|
"hooks.workflow_guard",
|
|
@@ -178,7 +181,12 @@
|
|
|
178
181
|
{
|
|
179
182
|
"topLevel": "model_policy",
|
|
180
183
|
"source": "^model_policy\\.runtime_tiers\\.[a-zA-Z0-9_-]+\\.(opus|sonnet|haiku)$",
|
|
181
|
-
"description": "model_policy.runtime_tiers.<runtime>.<opus|sonnet|haiku>"
|
|
184
|
+
"description": "model_policy.runtime_tiers.<runtime>.<opus|sonnet|haiku> (#3587)"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"topLevel": "phase_commit_docs",
|
|
188
|
+
"source": "^phase_commit_docs\\.\\d+[A-Z]?(?:\\.\\d+)*$",
|
|
189
|
+
"description": "phase_commit_docs.<phase-id> — per-phase commit_docs override (#3587). The <phase-id> segment is a hand-copy of the canonical PHASE_NUMBER_TOKEN_SOURCE grammar owned by src/phase-id.cts (#2128); this manifest is hand-maintained JSON so it cannot import that constant. Pinned against drift by the behavioral parity test in tests/commit-docs-bypass.test.cjs (folded 'phase-commit-docs' block, describe block 'E', #3587) — do not hand-edit this pattern without updating that test."
|
|
182
190
|
}
|
|
183
191
|
]
|
|
184
192
|
}
|
|
@@ -8,38 +8,55 @@ This doc describes what IS, not what should be. Casing inconsistencies are docum
|
|
|
8
8
|
|
|
9
9
|
## Agent Registry
|
|
10
10
|
|
|
11
|
-
| Agent | Role | Completion Markers |
|
|
12
|
-
|
|
13
|
-
| gsd-
|
|
14
|
-
| gsd-
|
|
15
|
-
| gsd-
|
|
16
|
-
| gsd-
|
|
17
|
-
| gsd-
|
|
18
|
-
| gsd-
|
|
19
|
-
| gsd-
|
|
20
|
-
| gsd-
|
|
21
|
-
| gsd-
|
|
22
|
-
| gsd-
|
|
23
|
-
| gsd-ui-
|
|
24
|
-
| gsd-
|
|
25
|
-
| gsd-
|
|
26
|
-
| gsd-
|
|
27
|
-
| gsd-
|
|
28
|
-
| gsd-
|
|
29
|
-
| gsd-
|
|
30
|
-
| gsd-
|
|
31
|
-
| gsd-
|
|
32
|
-
| gsd-
|
|
33
|
-
| gsd-
|
|
34
|
-
| gsd-
|
|
11
|
+
| Agent | Role | Completion Markers | Consumed by | Kind |
|
|
12
|
+
|-------|------|--------------------|--------------|------|
|
|
13
|
+
| gsd-ai-researcher | AI framework research | No marker (writes the AI-SPEC.md framework section via Edit) | `gsd-core/workflows/ai-integration-phase.md` reads the AI-SPEC.md section after the agent returns | artifact+query |
|
|
14
|
+
| gsd-planner | Plan creation | `## PLANNING COMPLETE`, `## OUTLINE COMPLETE`, `## PHASE SPLIT RECOMMENDED`, `## ⚠ Source Audit`, `## CHECKPOINT REACHED`, `## PLANNING INCONCLUSIVE` | `gsd-core/workflows/plan-phase.md`, `gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md`, `gsd-core/workflows/plan-review-convergence.md`, `gsd-core/workflows/quick.md` | sentinel-match |
|
|
15
|
+
| gsd-executor | Plan execution | `## PLAN COMPLETE`, `## CHECKPOINT REACHED` | `gsd-core/workflows/plan-phase.md`, `gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md`, `agents/gsd-debug-session-manager.md`, `agents/gsd-debugger.md` | sentinel-match |
|
|
16
|
+
| gsd-phase-researcher | Phase-scoped research | `## RESEARCH COMPLETE`, `## RESEARCH BLOCKED` | `gsd-core/workflows/plan-phase.md`, `gsd-core/workflows/quick/steps/research-phase.md`, `agents/gsd-project-researcher.md` | sentinel-match |
|
|
17
|
+
| gsd-project-researcher | Project-wide research | `## RESEARCH COMPLETE`, `## RESEARCH BLOCKED` | `gsd-core/workflows/plan-phase.md`, `gsd-core/workflows/quick/steps/research-phase.md`, `agents/gsd-phase-researcher.md` | sentinel-match |
|
|
18
|
+
| gsd-plan-checker | Plan validation | `## VERIFICATION PASSED`, `## ISSUES FOUND` | `gsd-core/workflows/plan-phase.md`, `gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md`, `gsd-core/workflows/quick/steps/plan-checker-loop.md`, `gsd-core/workflows/ui-phase.md`, `gsd-core/workflows/verify-work.md`, `agents/gsd-ui-checker.md` | sentinel-match |
|
|
19
|
+
| gsd-research-synthesizer | Multi-research synthesis | `## SYNTHESIS COMPLETE`, `## SYNTHESIS BLOCKED` (unconsumed: blocked-research return — spawners detect failure via the #222 SUMMARY.md-on-disk check, no dispatch branch keys on the marker) | `gsd-core/workflows/new-milestone.md`, `gsd-core/workflows/new-project.md` | sentinel-match |
|
|
20
|
+
| gsd-debugger | Debug investigation | `## DEBUG COMPLETE`, `## ROOT CAUSE FOUND`, `## CHECKPOINT REACHED`, `## INVESTIGATION INCONCLUSIVE`, `## TDD CHECKPOINT`, `## FIX REJECTED BY GUARDRAIL` | `agents/gsd-debug-session-manager.md`, `gsd-core/workflows/diagnose-issues.md`, `gsd-core/workflows/plan-phase.md`, `agents/gsd-executor.md` | sentinel-match |
|
|
21
|
+
| gsd-debug-session-manager | Debug checkpoint loop | `## DEBUG SESSION COMPLETE`, `## CONTINUE_REQUIRED` | `gsd-core/workflows/debug.md` | sentinel-match |
|
|
22
|
+
| gsd-roadmapper | Roadmap creation/revision | `## ROADMAP CREATED`, `## ROADMAP REVISED`, `## ROADMAP BLOCKED`, `## ROADMAP DRAFT` (unconsumed: draft-presentation format the shipped execution flow never invokes — Step 8 returns `## ROADMAP CREATED`; retained for interactive draft review) | `gsd-core/workflows/new-milestone.md`, `gsd-core/workflows/new-project.md` | sentinel-match |
|
|
23
|
+
| gsd-ui-auditor | UI review | `## UI REVIEW COMPLETE` | `gsd-core/workflows/ui-review.md` | sentinel-match |
|
|
24
|
+
| gsd-ui-checker | UI validation | `## ISSUES FOUND`, `## UI-SPEC VERIFIED` | `gsd-core/workflows/plan-phase.md`, `gsd-core/workflows/quick/steps/plan-checker-loop.md`, `gsd-core/workflows/ui-phase.md`, `gsd-core/workflows/verify-work.md`, `agents/gsd-plan-checker.md` | sentinel-match |
|
|
25
|
+
| gsd-ui-researcher | UI spec creation | `## UI-SPEC COMPLETE`, `## UI-SPEC BLOCKED` | `gsd-core/workflows/ui-phase.md` | sentinel-match |
|
|
26
|
+
| gsd-verifier | Post-execution verification | `## Verification Complete` (unconsumed: Marker Rule 2 recorded decision — intentional title-case marker; completion is detected via the artifact route, nothing matches the marker) | `*-VERIFICATION.md` artifact + `gsd_run query verification.status` in `gsd-core/workflows/verify-work.md` | artifact+query |
|
|
27
|
+
| gsd-integration-checker | Cross-phase integration check | `## Integration Check Complete` (unconsumed: Marker Rule 2 recorded decision — intentional title-case marker; the auditor reads the inline report, nothing matches the marker) | `gsd-core/workflows/audit-milestone.md` reads the agent's inline return text directly (agent has no Write tool -- it cannot write an artifact) | structured-return |
|
|
28
|
+
| gsd-nyquist-auditor | Sampling audit | `## PARTIAL`, `## ESCALATE`, `## GAPS FILLED` (non-standard) | `gsd-core/workflows/validate-phase.md`, `gsd-core/workflows/secure-phase.md`, `agents/gsd-security-auditor.md` | sentinel-match |
|
|
29
|
+
| gsd-security-auditor | Security audit | `## OPEN_THREATS`, `## ESCALATE`, `## SECURED` (non-standard) | `gsd-core/workflows/secure-phase.md`, `gsd-core/workflows/validate-phase.md`, `agents/gsd-nyquist-auditor.md` | sentinel-match |
|
|
30
|
+
| gsd-codebase-mapper | Codebase analysis | No marker (writes docs directly) | `.planning/codebase/*.md` artifacts, checked via `ls`/`wc -l` in `gsd-core/workflows/map-codebase.md` | artifact+query |
|
|
31
|
+
| gsd-code-fixer | Applies code-review fixes | No marker (fix commits + REVIEW.md updates) | `gsd-core/workflows/code-review-fix.md` reads REVIEW.md resolution state + git log | artifact+query |
|
|
32
|
+
| gsd-code-reviewer | Source-code review | No marker (writes REVIEW.md) | `gsd-core/workflows/code-review.md` reads REVIEW.md | artifact+query |
|
|
33
|
+
| gsd-assumptions-analyzer | Assumption extraction | No marker (returns `## Assumptions` sections) | `gsd-core/workflows/discuss-phase-assumptions.md` reads the inline `## Assumptions` sections from the agent's return | structured-return |
|
|
34
|
+
| gsd-doc-classifier | Planning-doc classification | No marker (writes `.planning/intel/classifications/*.json`) | `gsd-core/workflows/ingest-docs.md` reads the classification JSON | artifact+query |
|
|
35
|
+
| gsd-doc-verifier | Doc validation | No marker (writes JSON to `.planning/tmp/`) | `.planning/tmp/verify-{doc_filename}.json` artifact, read by `gsd-core/workflows/docs-update.md` | artifact+query |
|
|
36
|
+
| gsd-doc-writer | Doc generation | No marker (writes docs directly) | generated doc files, consumed by `gsd-core/workflows/docs-update.md` and `gsd-core/workflows/docs-update/steps/dispatch-monorepo-packages.md` | artifact+query |
|
|
37
|
+
| gsd-domain-researcher | Domain research | No marker (writes the AI-SPEC.md domain section via Edit) | `gsd-core/workflows/ai-integration-phase.md` reads the AI-SPEC.md section after the agent returns | artifact+query |
|
|
38
|
+
| gsd-eval-auditor | Evaluation coverage audit | No marker (writes the REVIEW.md audit section) | `gsd-core/workflows/eval-review.md` reads REVIEW.md | artifact+query |
|
|
39
|
+
| gsd-eval-planner | Evaluation strategy design | No marker (writes the AI-SPEC.md evaluation section via Edit) | `gsd-core/workflows/ai-integration-phase.md` reads the AI-SPEC.md section after the agent returns | artifact+query |
|
|
40
|
+
| gsd-framework-selector | Framework decision matrix | No marker (returns the interactive decision matrix inline) | `gsd-core/workflows/ai-integration-phase.md` reads the returned matrix | structured-return |
|
|
41
|
+
| gsd-advisor-researcher | Advisory research | No marker (utility agent) | `gsd-core/workflows/discuss-phase/modes/advisor.md` reads the inline comparison table from the agent's return | structured-return |
|
|
42
|
+
| gsd-user-profiler | User profiling | No marker (returns JSON in analysis tags) | `gsd-core/workflows/profile-user.md` extracts the inline `<analysis>` JSON block from the agent's return | structured-return |
|
|
43
|
+
| gsd-intel-updater | Codebase intelligence analysis | No marker (`.planning/intel/*.json` artifacts) | `.planning/intel/*.json` artifacts, read via `gsd_run intel query` / `intel validate` (no `*.md` workflow currently spawns this agent -- see `docs/adr/22-plan-drift-guard.md`, "never auto-spawned") | artifact+query |
|
|
44
|
+
| gsd-mempalace-curator | Ship-time MemPalace curation | No marker (writes the session diary + cross-links) | `gsd-core/workflows/ship.md` reads the diary artifacts | artifact+query |
|
|
45
|
+
| gsd-pattern-mapper | Codebase pattern mapping | `## PATTERN MAPPING COMPLETE` | `gsd-core/workflows/plan-phase.md` (also spawned by `gsd-core/workflows/settings.md`) | sentinel-match |
|
|
46
|
+
| gsd-doc-synthesizer | Doc synthesis for `/gsd:ingest-docs` | No marker (SYNTHESIS.md and INGEST-CONFLICTS.md artifacts) | `.planning/intel/SYNTHESIS.md` and `.planning/INGEST-CONFLICTS.md` artifacts, read by `gsd-core/workflows/ingest-docs.md` | artifact+query |
|
|
35
47
|
|
|
36
48
|
## Marker Rules
|
|
37
49
|
|
|
38
50
|
1. **ALL-CAPS markers** (e.g., `## PLANNING COMPLETE`) are the standard convention
|
|
39
|
-
2. **Title-case markers
|
|
51
|
+
2. **Title-case markers in gsd-verifier and gsd-integration-checker are intentional as-is, not bugs — a recorded decision.** Their rows are `artifact+query`/`structured-return` (completion is detected through the row's `Kind` route), and the markers are carried as `(unconsumed: Marker Rule 2 recorded decision …)` annotations: an auditable exemption, never deleted and never silently passed. `## Synthesis Complete` in gsd-doc-synthesizer was NOT covered by this rule; #3565 deleted it deliberately because it case-collides with gsd-research-synthesizer's `## SYNTHESIS COMPLETE` and nothing matched it
|
|
40
52
|
3. **Non-standard markers** (e.g., `## PARTIAL`, `## ESCALATE`) in audit agents indicate partial results requiring orchestrator judgment
|
|
41
|
-
4.
|
|
53
|
+
4. **`Kind` describes how a caller actually detects an agent's completion, and is exactly one of:**
|
|
54
|
+
- `sentinel-match` -- a workflow, command, or another agent detects completion by an exact-case string match against a declared marker
|
|
55
|
+
- `artifact+query` -- the agent writes a file (report, JSON, generated doc) and the caller reads or queries that artifact instead of matching any marker text
|
|
56
|
+
- `structured-return` -- the agent has no way to write files (no `Write` tool) or simply doesn't; it returns parseable sections, a table, or JSON inline, and the caller reads that return text directly
|
|
42
57
|
5. Markers must appear as H2 headings (`## `) at the start of a line in the agent's final output
|
|
58
|
+
6. The `Consumed by` / `Kind` columns are machine-enforced by `check:contract-drift` (`scripts/check-contract-drift.cjs`), which cross-checks this table against what each `agents/*.md` file actually emits in-fence and what every `gsd-core/workflows/**`, `commands/**`, and `agents/**` file actually consumes. Update this table whenever an agent's return contract changes -- a stale row is a violation the check will report, not something to leave for later.
|
|
59
|
+
7. A marker entry annotated `(unconsumed: <reason>)` is emitted deliberately but matched by no workflow, command, or agent — e.g. `## ROADMAP DRAFT`, a presentation format a human approves interactively. The check still verifies the marker is declared **and** emitted, and still counts it for case-collision purposes; only the consumer requirement is waived. Use it for display formats, never to silence a real orphan.
|
|
43
60
|
|
|
44
61
|
## Key Handoff Contracts
|
|
45
62
|
|
|
@@ -43,6 +43,13 @@ reads is inert — the consumption mechanism is what gives an artifact meaning.
|
|
|
43
43
|
- **Lifecycle**: Created at plan completion → Read by subsequent plans in same phase
|
|
44
44
|
- **Location**: `.planning/phases/XX-name/XX-YY-SUMMARY.md`
|
|
45
45
|
- **Consumed by**: Orchestrator (progress), planner (context for future plans), `milestone-summary`
|
|
46
|
+
- **`status:`** — `complete` (default) or **`halted`**. `halted` records a *designed stop*:
|
|
47
|
+
the plan ran and answered its question, but the answer means the work it was gating cannot
|
|
48
|
+
proceed (a spike that returns "no", for example). It is a success, not a failure — the plan
|
|
49
|
+
did its job. Marking a SUMMARY `halted` propagates transitively over `depends_on`: every
|
|
50
|
+
plan that depends on it, directly or through a chain, is reported as **blocked** rather than
|
|
51
|
+
offered to the executor as ordinary incomplete work, and is named with its cause. Any other
|
|
52
|
+
value — including no `status:` field at all — reads as complete. (#2830)
|
|
46
53
|
|
|
47
54
|
### HANDOFF.json / .continue-here.md
|
|
48
55
|
- **Shape**: Structured pause state (JSON machine-readable + Markdown human-readable)
|
|
@@ -72,11 +79,11 @@ reads is inert — the consumption mechanism is what gives an artifact meaning.
|
|
|
72
79
|
- **Location**: `.planning/spikes/SPIKE-NNN/`
|
|
73
80
|
- **Consumed by**: Planner when spike is referenced; `pause-work` for spike context handoff
|
|
74
81
|
|
|
75
|
-
### Spike README.md / MANIFEST.md (per-
|
|
76
|
-
- **Shape**: YAML frontmatter (spike, name, validates, verdict, related, tags) + run instructions + results
|
|
82
|
+
### Spike README.md (per-spike) / MANIFEST.md (per-project index, via /gsd:spike)
|
|
83
|
+
- **Shape**: README — YAML frontmatter (spike, idea, name, validates, verdict, related, tags) + run instructions + results. MANIFEST.md — one `### {idea-key}` section per idea under `## Ideas` (idea paragraph + its own scoped Requirements), plus one durable `## Spikes` table (with an Idea column) indexing every spike across every idea.
|
|
77
84
|
- **Lifecycle**: Created by `/gsd:spike` → Verified → Wrapped up by `/gsd-spike-wrap-up`
|
|
78
85
|
- **Location**: `.planning/spikes/NNN-name/README.md`, `.planning/spikes/MANIFEST.md`
|
|
79
|
-
- **Consumed by**: `/gsd-spike-wrap-up` for curation; `pause-work` for spike context handoff
|
|
86
|
+
- **Consumed by**: `/gsd-spike-wrap-up` for curation (Requirements pulled only from the idea key(s) it wraps); `pause-work` for spike context handoff
|
|
80
87
|
|
|
81
88
|
### Sketch README.md / MANIFEST.md / index.html (per-sketch)
|
|
82
89
|
- **Shape**: YAML frontmatter (sketch, name, question, winner, tags) + variants as tabbed HTML
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# UI Design Contract (Frontend Phases) — Autonomous Mode
|
|
2
|
+
|
|
3
|
+
Step 3a.5 of `/gsd:autonomous`: resolve whether the current phase needs a UI-SPEC.md generated before planning, and generate one via active `plan:pre` step hooks if so. Always non-blocking — proceeds to step 3b (Plan) regardless of outcome.
|
|
4
|
+
|
|
5
|
+
**Inputs:** `PHASE_NUM`, `PHASE_DIR` from execute_phase.
|
|
6
|
+
|
|
7
|
+
Resolve active `plan:pre` hooks:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
UI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-UI-SPEC.md 2>/dev/null | head -1)
|
|
11
|
+
HOOKS_JSON=$(gsd_run loop render-hooks plan:pre --raw)
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Read the `activeHooks` array directly from `HOOKS_JSON` (in-context — do NOT invoke a shell pipeline). **Compute the active UI step hooks** = entries from `activeHooks` where `kind == "step"` and `ref.skill` is set. **If there are NO active step hooks → skip silently to 3b.** (This covers `workflow.ui_phase=false` — including configurations where only a gate-only entry is present, e.g. `ui_phase=false` + `ui_safety_gate=true` produces `activeHooks=[{kind:"gate"}]`. Autonomous never runs the plan:pre gate — it is always pipeline mode — so a gate-only active set is equivalent to no active step and is silently skipped here. This matches OLD §3a.5 behaviour.)
|
|
15
|
+
|
|
16
|
+
(At least one active step hook ⇒ `workflow.ui_phase` is on.) Run the UI-SPEC gate:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
GATE=$(gsd_run check ui-plan-gate "${PHASE_NUM}" --raw)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Read `frontend` and `hasUiSpec` from `GATE` (in-context).
|
|
23
|
+
|
|
24
|
+
**If `frontend` is false:** Skip silently to 3b.
|
|
25
|
+
|
|
26
|
+
**If `hasUiSpec` is true (UI-SPEC already exists):** Skip silently to 3b.
|
|
27
|
+
|
|
28
|
+
**Otherwise (frontend phase + no UI-SPEC):** For each active step hook (the `kind == "step"` set from above, in array order):
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
Skill(skill="gsd-${ref.skill}", args="${PHASE_NUM}")
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
(Prepend `gsd-` to `ref.skill` — so `ui-phase` → `gsd-ui-phase`. Bare `${PHASE_NUM}` args — autonomous style, same pattern as the verify:post dispatch.) Entries where `kind == "gate"` are silently ignored — autonomous is always pipeline mode, there is no blocking gate here.
|
|
35
|
+
|
|
36
|
+
After all step hooks return, re-read:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
UI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-UI-SPEC.md 2>/dev/null | head -1)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**If `UI_SPEC_FILE` is still empty:** Display warning `Phase ${PHASE_NUM}: UI-SPEC generation did not produce output — continuing without design contract.` and proceed to 3b. NON-BLOCKING.
|
|
@@ -9,14 +9,14 @@ Plans execute autonomously. Checkpoints formalize interaction points where human
|
|
|
9
9
|
3. **User only does what requires human judgment** - Visual checks, UX evaluation, "does this feel right?"
|
|
10
10
|
4. **Secrets come from user, automation comes from Claude** - Ask for API keys, then Claude uses them via CLI
|
|
11
11
|
5. **Auto-mode bypasses verification/decision checkpoints** — When `workflow._auto_chain_active` or `workflow.auto_advance` is true in config: human-verify auto-approves, decision auto-selects first option, human-action still stops (auth gates cannot be automated)
|
|
12
|
-
6. **`gate="blocking-human"` is never auto-approved** — a checkpoint carrying this gate stops for a human in *every* mode, including auto-mode, regardless of its type. Rule 5 does not apply to it.
|
|
12
|
+
6. **`gate="blocking-human"` is never auto-approved** — a checkpoint carrying this gate stops for a human in *every* mode, including auto-mode, regardless of its type. Rule 5 does not apply to it. The executor's precondition-unmet checkpoint (a task's `<precondition>` evaluated false — unmet `user_setup` step, missing env var, absent prior-phase artifact) reports this gate (#3210).
|
|
13
13
|
|
|
14
14
|
**The `gate` attribute:**
|
|
15
15
|
|
|
16
16
|
| Value | Auto-mode behavior | Use for |
|
|
17
17
|
|-------|--------------------|---------|
|
|
18
18
|
| `gate="blocking"` | Bypassed per rule 5 (human-verify auto-approves, decision auto-selects) | The default. Post-hoc verification and implementation choices that are safe to take the recommended path on when unattended. |
|
|
19
|
-
| `gate="blocking-human"` | **Never bypassed.** Stops for a human in auto-mode too. | Irreversible or trust-establishing steps a human must actually see: package-legitimacy verification before install,
|
|
19
|
+
| `gate="blocking-human"` | **Never bypassed.** Stops for a human in auto-mode too. | Irreversible or trust-establishing steps a human must actually see: package-legitimacy verification before install, any decision whose default answer would be wrong to assume, and unmet `<precondition>` facts the executor cannot establish on its own (#3210). |
|
|
20
20
|
|
|
21
21
|
Reach for `gate="blocking-human"` whenever auto-approving the checkpoint would defeat its purpose. If the checkpoint exists because a human must *decide* something, `blocking` is the wrong gate — auto-mode will decide it for them.
|
|
22
22
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Standard rules for keeping orchestrator context lean. Reference this in workflows that spawn subagents or read significant content.
|
|
4
4
|
|
|
5
|
-
See also: `references/universal-anti-patterns.md` for the complete set of universal rules.
|
|
5
|
+
See also: `gsd-core/references/universal-anti-patterns.md` for the complete set of universal rules.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# Debugger technique catalog
|
|
2
|
+
|
|
3
|
+
Full technique bodies for `agents/gsd-debugger.md`, extracted per
|
|
4
|
+
`DEFECT.AGENT-FILE-SIZE-CAP-BREACH` (issue #2995, epic #1671 Phase 6.4). The agent
|
|
5
|
+
keeps each technique's name and routing entry; the step-by-step detail lives here.
|
|
6
|
+
|
|
7
|
+
## Binary Search / Divide and Conquer
|
|
8
|
+
|
|
9
|
+
**When:** Large codebase, long execution path, many possible failure points.
|
|
10
|
+
|
|
11
|
+
**How:** Cut problem space in half repeatedly until you isolate the issue.
|
|
12
|
+
|
|
13
|
+
1. Identify boundaries (where works, where fails)
|
|
14
|
+
2. Add logging/testing at midpoint
|
|
15
|
+
3. Determine which half contains the bug
|
|
16
|
+
4. Repeat until you find exact line
|
|
17
|
+
|
|
18
|
+
**Example:** API returns wrong data
|
|
19
|
+
- Test: Data leaves database correctly? YES
|
|
20
|
+
- Test: Data reaches frontend correctly? NO
|
|
21
|
+
- Test: Data leaves API route correctly? YES
|
|
22
|
+
- Test: Data survives serialization? NO
|
|
23
|
+
- **Found:** Bug in serialization layer (4 tests eliminated 90% of code)
|
|
24
|
+
|
|
25
|
+
## Rubber Duck Debugging
|
|
26
|
+
|
|
27
|
+
**When:** Stuck, confused, mental model doesn't match reality.
|
|
28
|
+
|
|
29
|
+
**How:** Explain the problem out loud in complete detail.
|
|
30
|
+
|
|
31
|
+
Write or say:
|
|
32
|
+
1. "The system should do X"
|
|
33
|
+
2. "Instead it does Y"
|
|
34
|
+
3. "I think this is because Z"
|
|
35
|
+
4. "The code path is: A -> B -> C -> D"
|
|
36
|
+
5. "I've verified that..." (list what you tested)
|
|
37
|
+
6. "I'm assuming that..." (list assumptions)
|
|
38
|
+
|
|
39
|
+
Often you'll spot the bug mid-explanation: "Wait, I never verified that B returns what I think it does."
|
|
40
|
+
|
|
41
|
+
## Delta Debugging
|
|
42
|
+
|
|
43
|
+
**When:** Large change set is suspected (many commits, a big refactor, or a complex feature that broke something). Also when "comment out everything" is too slow.
|
|
44
|
+
|
|
45
|
+
**How:** Binary search over the change space — not just the code, but the commits, configs, and inputs.
|
|
46
|
+
|
|
47
|
+
**Over commits (use git bisect):**
|
|
48
|
+
Already covered under Git Bisect. But delta debugging extends it: after finding the breaking commit, delta-debug the commit itself — identify which of its N changed files/lines actually causes the failure.
|
|
49
|
+
|
|
50
|
+
**Over code (systematic elimination):**
|
|
51
|
+
1. Identify the boundary: a known-good state (commit, config, input) vs the broken state
|
|
52
|
+
2. List all differences between good and bad states
|
|
53
|
+
3. Split the differences in half. Apply only half to the good state.
|
|
54
|
+
4. If broken: bug is in the applied half. If not: bug is in the other half.
|
|
55
|
+
5. Repeat until you have the minimal change set that causes the failure.
|
|
56
|
+
|
|
57
|
+
**Over inputs:**
|
|
58
|
+
1. Find a minimal input that triggers the bug (strip out unrelated data fields)
|
|
59
|
+
2. The minimal input reveals which code path is exercised
|
|
60
|
+
|
|
61
|
+
**When to use:**
|
|
62
|
+
- "This worked yesterday, something changed" → delta debug commits
|
|
63
|
+
- "Works with small data, fails with real data" → delta debug inputs
|
|
64
|
+
- "Works without this config change, fails with it" → delta debug config diff
|
|
65
|
+
|
|
66
|
+
**Example:** 40-file commit introduces bug
|
|
67
|
+
```
|
|
68
|
+
Split into two 20-file halves.
|
|
69
|
+
Apply first 20: still works → bug in second half.
|
|
70
|
+
Split second half into 10+10.
|
|
71
|
+
Apply first 10: broken → bug in first 10.
|
|
72
|
+
... 6 splits later: single file isolated.
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Minimal Reproduction
|
|
76
|
+
|
|
77
|
+
**When:** Complex system, many moving parts, unclear which part fails.
|
|
78
|
+
|
|
79
|
+
**How:** Strip away everything until smallest possible code reproduces the bug.
|
|
80
|
+
|
|
81
|
+
1. Copy failing code to new file
|
|
82
|
+
2. Remove one piece (dependency, function, feature)
|
|
83
|
+
3. Test: Does it still reproduce? YES = keep removed. NO = put back.
|
|
84
|
+
4. Repeat until bare minimum
|
|
85
|
+
5. Bug is now obvious in stripped-down code
|
|
86
|
+
6. **Shrinking (input-space bugs)** — when the bug triggers on a class of inputs, wrap it in a property (fast-check for JS/TS, Hypothesis for Python) and let the shrinker auto-minimize the counterexample; store the **minimized** input as the regression seed. See `gsd-core/references/debugger-repro-hardening.md`.
|
|
87
|
+
|
|
88
|
+
**Example:**
|
|
89
|
+
```jsx
|
|
90
|
+
// Start: 500-line React component with 15 props, 8 hooks, 3 contexts
|
|
91
|
+
// End after stripping:
|
|
92
|
+
function MinimalRepro() {
|
|
93
|
+
const [count, setCount] = useState(0);
|
|
94
|
+
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
setCount(count + 1); // Bug: infinite loop, missing dependency array
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return <div>{count}</div>;
|
|
100
|
+
}
|
|
101
|
+
// The bug was hidden in complexity. Minimal reproduction made it obvious.
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Working Backwards
|
|
105
|
+
|
|
106
|
+
**When:** You know correct output, don't know why you're not getting it.
|
|
107
|
+
|
|
108
|
+
**How:** Start from desired end state, trace backwards.
|
|
109
|
+
|
|
110
|
+
1. Define desired output precisely
|
|
111
|
+
2. What function produces this output?
|
|
112
|
+
3. Test that function with expected input - does it produce correct output?
|
|
113
|
+
- YES: Bug is earlier (wrong input)
|
|
114
|
+
- NO: Bug is here
|
|
115
|
+
4. Repeat backwards through call stack
|
|
116
|
+
5. Find divergence point (where expected vs actual first differ)
|
|
117
|
+
|
|
118
|
+
**Example:** UI shows "User not found" when user exists
|
|
119
|
+
```
|
|
120
|
+
Trace backwards:
|
|
121
|
+
1. UI displays: user.error → Is this the right value to display? YES
|
|
122
|
+
2. Component receives: user.error = "User not found" → Correct? NO, should be null
|
|
123
|
+
3. API returns: { error: "User not found" } → Why?
|
|
124
|
+
4. Database query: SELECT * FROM users WHERE id = 'undefined' → AH!
|
|
125
|
+
5. FOUND: User ID is 'undefined' (string) instead of a number
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Differential Debugging
|
|
129
|
+
|
|
130
|
+
**When:** Something used to work and now doesn't. Works in one environment but not another.
|
|
131
|
+
|
|
132
|
+
**Time-based (worked, now doesn't):**
|
|
133
|
+
- What changed in code since it worked?
|
|
134
|
+
- What changed in environment? (Node version, OS, dependencies)
|
|
135
|
+
- What changed in data?
|
|
136
|
+
- What changed in configuration?
|
|
137
|
+
|
|
138
|
+
**Environment-based (works in dev, fails in prod):**
|
|
139
|
+
- Configuration values
|
|
140
|
+
- Environment variables
|
|
141
|
+
- Network conditions (latency, reliability)
|
|
142
|
+
- Data volume
|
|
143
|
+
- Third-party service behavior
|
|
144
|
+
|
|
145
|
+
**Process:** List differences, test each in isolation, find the difference that causes failure.
|
|
146
|
+
|
|
147
|
+
**Example:** Works locally, fails in CI
|
|
148
|
+
```
|
|
149
|
+
Differences:
|
|
150
|
+
- Node version: Same ✓
|
|
151
|
+
- Environment variables: Same ✓
|
|
152
|
+
- Timezone: Different! ✗
|
|
153
|
+
|
|
154
|
+
Test: Set local timezone to UTC (like CI)
|
|
155
|
+
Result: Now fails locally too
|
|
156
|
+
FOUND: Date comparison logic assumes local timezone
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Observability First
|
|
160
|
+
|
|
161
|
+
**When:** Always. Before making any fix.
|
|
162
|
+
|
|
163
|
+
**Add visibility before changing behavior:**
|
|
164
|
+
|
|
165
|
+
```javascript
|
|
166
|
+
// Strategic logging (useful):
|
|
167
|
+
console.log('[handleSubmit] Input:', { email, password: '***' });
|
|
168
|
+
console.log('[handleSubmit] Validation result:', validationResult);
|
|
169
|
+
console.log('[handleSubmit] API response:', response);
|
|
170
|
+
|
|
171
|
+
// Assertion checks:
|
|
172
|
+
console.assert(user !== null, 'User is null!');
|
|
173
|
+
console.assert(user.id !== undefined, 'User ID is undefined!');
|
|
174
|
+
|
|
175
|
+
// Timing measurements:
|
|
176
|
+
console.time('Database query');
|
|
177
|
+
const result = await db.query(sql);
|
|
178
|
+
console.timeEnd('Database query');
|
|
179
|
+
|
|
180
|
+
// Stack traces at key points:
|
|
181
|
+
console.log('[updateUser] Called from:', new Error().stack);
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Workflow:** Add logging -> Run code -> Observe output -> Form hypothesis -> Then make changes.
|
|
185
|
+
|
|
186
|
+
## Comment Out Everything
|
|
187
|
+
|
|
188
|
+
**When:** Many possible interactions, unclear which code causes issue.
|
|
189
|
+
|
|
190
|
+
**How:**
|
|
191
|
+
1. Comment out everything in function/file
|
|
192
|
+
2. Verify bug is gone
|
|
193
|
+
3. Uncomment one piece at a time
|
|
194
|
+
4. After each uncomment, test
|
|
195
|
+
5. When bug returns, you found the culprit
|
|
196
|
+
|
|
197
|
+
**Example:** Some middleware breaks requests, but you have 8 middleware functions
|
|
198
|
+
```javascript
|
|
199
|
+
app.use(helmet()); // Uncomment, test → works
|
|
200
|
+
app.use(cors()); // Uncomment, test → works
|
|
201
|
+
app.use(compression()); // Uncomment, test → works
|
|
202
|
+
app.use(bodyParser.json({ limit: '50mb' })); // Uncomment, test → BREAKS
|
|
203
|
+
// FOUND: Body size limit too high causes memory issues
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Git Bisect
|
|
207
|
+
|
|
208
|
+
**When:** Feature worked in past, broke at unknown commit.
|
|
209
|
+
|
|
210
|
+
**How:** Binary search through git history.
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
git bisect start
|
|
214
|
+
git bisect bad # Current commit is broken
|
|
215
|
+
git bisect good abc123 # This commit worked
|
|
216
|
+
# Git checks out middle commit
|
|
217
|
+
git bisect bad # or good, based on testing
|
|
218
|
+
# Repeat until culprit found
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
100 commits between working and broken: ~7 tests to find exact breaking commit.
|
|
222
|
+
|
|
223
|
+
## Follow the Indirection
|
|
224
|
+
|
|
225
|
+
**When:** Code constructs paths, URLs, keys, or references from variables — and the constructed value might not point where you expect.
|
|
226
|
+
|
|
227
|
+
**The trap:** You read code that builds a path like `path.join(configDir, 'hooks')` and assume it's correct because it looks reasonable. But you never verified that the constructed path matches where another part of the system actually writes/reads.
|
|
228
|
+
|
|
229
|
+
**How:**
|
|
230
|
+
1. Find the code that **produces** the value (writer/installer/creator)
|
|
231
|
+
2. Find the code that **consumes** the value (reader/checker/validator)
|
|
232
|
+
3. Trace the actual resolved value in both — do they agree?
|
|
233
|
+
4. Check every variable in the path construction — where does each come from? What's its actual value at runtime?
|
|
234
|
+
|
|
235
|
+
**Common indirection bugs:**
|
|
236
|
+
- Path A writes to `dir/sub/hooks/` but Path B checks `dir/hooks/` (directory mismatch)
|
|
237
|
+
- Config value comes from cache/template that wasn't updated
|
|
238
|
+
- Variable is derived differently in two places (e.g., one adds a subdirectory, the other doesn't)
|
|
239
|
+
- Template placeholder (`{{VERSION}}`) not substituted in all code paths
|
|
240
|
+
|
|
241
|
+
**Example:** Stale hook warning persists after update
|
|
242
|
+
```
|
|
243
|
+
Check code says: hooksDir = path.join(configDir, 'hooks')
|
|
244
|
+
configDir = ~/.claude
|
|
245
|
+
→ checks ~/.claude/hooks/
|
|
246
|
+
|
|
247
|
+
Installer says: hooksDest = path.join(targetDir, 'hooks')
|
|
248
|
+
targetDir = ~/.claude/gsd-core
|
|
249
|
+
→ writes to ~/.claude/gsd-core/hooks/
|
|
250
|
+
|
|
251
|
+
MISMATCH: Checker looks in wrong directory → hooks "not found" → reported as stale
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**The discipline:** Never assume a constructed path is correct. Resolve it to its actual value and verify the other side agrees. When two systems share a resource (file, directory, key), trace the full path in both.
|
|
255
|
+
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Dispatch isolation gate (ADR-1239 / #2584)
|
|
2
|
+
|
|
3
|
+
The single source of truth for **how a dispatch site decides whether it may run an agent
|
|
4
|
+
isolated**. Every workflow that spawns an executor-like subagent reads this file and follows
|
|
5
|
+
it, rather than restating the rule inline (#2652).
|
|
6
|
+
|
|
7
|
+
`ISOLATION` — not `RUNTIME` — is the decision variable. **Never branch a dispatch site on a
|
|
8
|
+
runtime id.** Isolation is a negotiated capability declared per host; a runtime-name test
|
|
9
|
+
silently diverges the moment a new host declares support, which is exactly how #2652 happened:
|
|
10
|
+
`quick.md` and `diagnose-issues.md` kept a `RUNTIME != "claude"` gate after #2584 migrated the
|
|
11
|
+
phase scheduler, so Codex — which declares `orchestrator-worktree` — was refused isolation it
|
|
12
|
+
had in fact negotiated.
|
|
13
|
+
|
|
14
|
+
## Resolve ISOLATION
|
|
15
|
+
|
|
16
|
+
Run this in the dispatch site's config-gate step, right after `RUNTIME` / `USE_WORKTREES` are
|
|
17
|
+
read. It requires `gsd_run` to be defined (the standard shim preamble).
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Isolation is a NEGOTIATED CAPABILITY, not a runtime id (#2584). Fail-closed to none.
|
|
21
|
+
# #3045: this call PERSISTS the resolution to the run-scoped sentinel the isolation
|
|
22
|
+
# guard hooks read, as an unconditional side effect of resolving it.
|
|
23
|
+
# Keep the resolver's own failure DISTINGUISHABLE from a genuine `none`. Both
|
|
24
|
+
# fail closed — that policy is right — but only one of them may claim the host
|
|
25
|
+
# declared no primitive. A shim-resolution failure, a non-zero exit or empty
|
|
26
|
+
# stdout is NOT a capability verdict, and reporting it as one tells a Claude
|
|
27
|
+
# Code user their runtime "declares no executor-isolation primitive", which is
|
|
28
|
+
# false (#2652 review).
|
|
29
|
+
_ISOLATION_RAW=$(gsd_run query dispatch-isolation --raw 2>/dev/null)
|
|
30
|
+
_ISOLATION_RC=$?
|
|
31
|
+
if [ $_ISOLATION_RC -ne 0 ] || [ -z "$_ISOLATION_RAW" ]; then
|
|
32
|
+
ISOLATION=none
|
|
33
|
+
ISOLATION_RESOLVED=false # fail closed, but we did NOT learn a verdict
|
|
34
|
+
else
|
|
35
|
+
ISOLATION="$_ISOLATION_RAW"
|
|
36
|
+
ISOLATION_RESOLVED=true
|
|
37
|
+
fi
|
|
38
|
+
case "$ISOLATION" in
|
|
39
|
+
harness-worktree|orchestrator-worktree|none) ;;
|
|
40
|
+
*) ISOLATION=none; ISOLATION_RESOLVED=false ;; # out of vocabulary is not a verdict either
|
|
41
|
+
esac
|
|
42
|
+
|
|
43
|
+
# Project-level opt-out wins on every host; a host with no primitive fails closed.
|
|
44
|
+
[ "$USE_WORKTREES" = "false" ] && ISOLATION=none
|
|
45
|
+
if [ "$ISOLATION" = "none" ] && [ "$USE_WORKTREES" != "false" ]; then
|
|
46
|
+
if [ "$ISOLATION_RESOLVED" = "true" ]; then
|
|
47
|
+
echo "FATAL: runtime '$RUNTIME' declares no executor-isolation primitive (dispatch.isolation=none) — agents would run unisolated against the main checkout. Set workflow.use_worktrees=false." >&2
|
|
48
|
+
else
|
|
49
|
+
echo "FATAL: could not resolve this runtime's executor-isolation capability — 'gsd_run query dispatch-isolation' failed or returned nothing, so GSD cannot tell whether isolation is available. Refusing to dispatch rather than guess (a guard that cannot verify must not answer 'safe'). Re-run once the gsd-tools shim resolves, or set workflow.use_worktrees=false to run sequentially on purpose." >&2
|
|
50
|
+
fi
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# Re-record: the opt-out above is decided in shell, where the resolver cannot see
|
|
55
|
+
# it, so the sentinel still asserts the naturally-resolved mode. See "Re-record
|
|
56
|
+
# after every degrade" below — this is the first of the mandatory calls.
|
|
57
|
+
gsd_run query dispatch-isolation --raw --force-isolation "$ISOLATION" >/dev/null 2>&1 || true
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
| `ISOLATION` | Meaning | What a dispatch site does |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| `harness-worktree` | The host's own harness creates and binds a worktree per agent. | Pass the host's declared `harnessFlag` on the dispatch. GSD runs no git. |
|
|
63
|
+
| `orchestrator-worktree` | No harness primitive, but a headless exec accepting a working directory. | GSD creates the worktree and process-spawns the agent into it. GSD performs every git operation. |
|
|
64
|
+
| `none` | No isolation primitive. | Run inline, sequentially. |
|
|
65
|
+
|
|
66
|
+
Fail-closed is the invariant: an undeclared, unknown, or unresolvable declaration degrades to
|
|
67
|
+
`none`, never to an unsafe parallel path.
|
|
68
|
+
|
|
69
|
+
## Resolve the harness flag (harness-worktree only)
|
|
70
|
+
|
|
71
|
+
The flag is descriptor data — never hardcode `isolation="worktree"`, which is Claude Code's
|
|
72
|
+
literal and wrong on any other harness-worktree host (Cursor declares the same capability).
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
HARNESS_FLAG=""
|
|
76
|
+
if [ "$ISOLATION" = "harness-worktree" ]; then
|
|
77
|
+
HARNESS_FLAG=$(gsd_run query dispatch-isolation --json 2>/dev/null \
|
|
78
|
+
| node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{try{const j=JSON.parse(s);process.stdout.write(j&&j.harnessFlag?j.harnessFlag:"")}catch{process.stdout.write("")}})')
|
|
79
|
+
[ -n "$HARNESS_FLAG" ] || { echo "FATAL: runtime declares dispatch.isolation=harness-worktree but no harnessIsolationFlag — refusing to dispatch an agent that would believe it is isolated." >&2; exit 1; }
|
|
80
|
+
fi
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Substitute `$HARNESS_FLAG` for the `{harnessFlag}` placeholder in the dispatch call. On Claude
|
|
84
|
+
Code it resolves to literally `isolation="worktree"`.
|
|
85
|
+
|
|
86
|
+
## Single-agent dispatch sites
|
|
87
|
+
|
|
88
|
+
`quick.md` and `diagnose-issues.md` spawn through the host's own subagent tool, which can only
|
|
89
|
+
express the `harness-worktree` model. On an `orchestrator-worktree` host they must degrade to
|
|
90
|
+
sequential rather than pass a harness flag the host will ignore — dispatching unisolated while
|
|
91
|
+
reporting isolation is the one outcome worse than running sequentially:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
if [ "$ISOLATION" = "orchestrator-worktree" ]; then
|
|
95
|
+
echo "⚠ Runtime '$RUNTIME' declares dispatch.isolation=orchestrator-worktree, which requires GSD-driven process spawning. This dispatch site uses the host subagent tool, so it is running sequentially on the main working tree instead. Parallel wave execution (/gsd:execute-phase) is unaffected." >&2
|
|
96
|
+
ISOLATION=none
|
|
97
|
+
USE_WORKTREES=false
|
|
98
|
+
gsd_run query dispatch-isolation --raw --force-isolation none >/dev/null 2>&1 || true
|
|
99
|
+
fi
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Re-record after every degrade
|
|
103
|
+
|
|
104
|
+
**Any block that changes `$ISOLATION` after the resolve above MUST re-record it before
|
|
105
|
+
dispatch.** This is not optional bookkeeping — it is what keeps the dispatch legal.
|
|
106
|
+
|
|
107
|
+
`query dispatch-isolation` writes the mode it resolved into a run-scoped sentinel
|
|
108
|
+
(`.gsd/dispatch-isolation-sentinel.json`) as an unconditional side effect, and the shipped
|
|
109
|
+
`PreToolUse` isolation guards read that sentinel at the instant of the dispatch call
|
|
110
|
+
(`hooks/gsd-agent-isolation-guard.js`, `hooks/gsd-cursor-subagent-start.js`, shared reader
|
|
111
|
+
`hooks/lib/isolation-sentinel.js`, #3045). Every degrade in this file is decided **in shell**,
|
|
112
|
+
where the resolver cannot see it. Degrade without re-recording and the sentinel still asserts
|
|
113
|
+
`harness-worktree` while the dispatch correctly omits the harness flag — the guard reads that
|
|
114
|
+
as a dropped isolation flag and **denies the dispatch with exit 2**. The task does not run
|
|
115
|
+
unisolated; it does not run at all.
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
gsd_run query dispatch-isolation --raw --force-isolation "$ISOLATION" >/dev/null 2>&1 || true
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
`--force-isolation` pushes the final, shell-computed value through the same single write path
|
|
122
|
+
(`none` also clears the stored `harnessFlag`, since none applies to sequential dispatch). It is
|
|
123
|
+
idempotent and last-write-wins, so a site that degrades more than once simply calls it again —
|
|
124
|
+
record immediately before dispatch so the sentinel is always fresh. Best-effort by design: a
|
|
125
|
+
write failure must never fail the dispatch, since the guards' sentinel-absent fallback is safe,
|
|
126
|
+
just less precise.
|
|
127
|
+
|
|
128
|
+
Wave sites re-record per plan rather than per phase — see
|
|
129
|
+
`gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md`.
|
|
130
|
+
|
|
131
|
+
Wave fan-out sites (`execute-phase`) implement both models — see
|
|
132
|
+
`gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md`.
|
|
133
|
+
|
|
134
|
+
## Base divergence
|
|
135
|
+
|
|
136
|
+
Any site that ends up with `ISOLATION != none` must also run the `worktree.base-check`
|
|
137
|
+
auto-degrade before dispatch (#683, #1369, #1941), or the agent's `worktree_branch_check` guard
|
|
138
|
+
halts on a stale fork base. `quick.md` and `execute-phase` do this today.
|