@opengsd/gsd-core 1.13.0 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.ja-JP.md +3 -3
- package/README.ko-KR.md +3 -3
- package/README.pt-BR.md +3 -3
- package/README.zh-CN.md +3 -3
- package/agents/gsd-advisor-researcher.compact.md +85 -0
- package/agents/gsd-ai-researcher.compact.md +96 -0
- package/agents/gsd-assumptions-analyzer.compact.md +81 -0
- package/agents/gsd-code-fixer.compact.md +459 -0
- package/agents/gsd-code-fixer.md +9 -8
- package/agents/gsd-code-reviewer.compact.md +269 -0
- package/agents/gsd-code-reviewer.md +15 -3
- package/agents/gsd-codebase-mapper.compact.md +760 -0
- package/agents/gsd-debug-session-manager.compact.md +360 -0
- package/agents/gsd-debug-session-manager.md +17 -2
- package/agents/gsd-debugger.md +2 -2
- package/agents/gsd-doc-classifier.compact.md +192 -0
- package/agents/gsd-doc-synthesizer.compact.md +200 -0
- package/agents/gsd-doc-verifier.compact.md +143 -0
- package/agents/gsd-doc-writer.compact.md +440 -0
- package/agents/gsd-dom-verifier.compact.md +138 -0
- package/agents/gsd-domain-researcher.compact.md +141 -0
- package/agents/gsd-eval-auditor.compact.md +160 -0
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-eval-planner.compact.md +137 -0
- package/agents/gsd-executor.md +13 -8
- package/agents/gsd-framework-selector.compact.md +82 -0
- package/agents/gsd-integration-checker.compact.md +245 -0
- package/agents/gsd-intel-updater.compact.md +226 -0
- package/agents/gsd-intel-updater.md +1 -1
- package/agents/gsd-mempalace-curator.compact.md +45 -0
- package/agents/gsd-nyquist-auditor.compact.md +179 -0
- package/agents/gsd-pattern-mapper.compact.md +275 -0
- package/agents/gsd-phase-researcher.md +19 -11
- package/agents/gsd-plan-checker.md +8 -7
- package/agents/gsd-planner.md +12 -8
- package/agents/gsd-project-researcher.compact.md +587 -0
- package/agents/gsd-project-researcher.md +1 -1
- package/agents/gsd-research-synthesizer.compact.md +212 -0
- package/agents/gsd-research-synthesizer.md +1 -1
- package/agents/gsd-roadmapper.compact.md +454 -0
- package/agents/gsd-roadmapper.md +13 -0
- package/agents/gsd-security-auditor.compact.md +162 -0
- package/agents/gsd-ui-auditor.compact.md +404 -0
- package/agents/gsd-ui-auditor.md +155 -17
- package/agents/gsd-ui-checker.compact.md +277 -0
- package/agents/gsd-ui-researcher.compact.md +282 -0
- package/agents/gsd-ui-researcher.md +1 -1
- package/agents/gsd-user-profiler.compact.md +108 -0
- package/agents/gsd-verifier.md +10 -9
- package/bin/install.js +848 -163
- package/commands/gsd/autonomous.md +2 -2
- package/commands/gsd/capture.md +1 -1
- package/commands/gsd/cleanup.md +1 -0
- package/commands/gsd/code-review.md +2 -1
- package/commands/gsd/complete-milestone.md +1 -0
- package/commands/gsd/config.md +1 -0
- package/commands/gsd/debug.md +1 -0
- package/commands/gsd/graphify.md +1 -0
- package/commands/gsd/health.md +1 -0
- package/commands/gsd/mempalace-capture.md +8 -3
- package/commands/gsd/mempalace-recall.md +1 -0
- package/commands/gsd/new-milestone.md +1 -0
- package/commands/gsd/new-project.md +1 -0
- package/commands/gsd/next.md +1 -0
- package/commands/gsd/pause-work.md +1 -0
- package/commands/gsd/phase.md +1 -0
- package/commands/gsd/plan-review-convergence.md +6 -6
- package/commands/gsd/pr-branch.md +1 -0
- package/commands/gsd/progress.md +1 -1
- package/commands/gsd/quick-batch.md +1 -1
- package/commands/gsd/resume-work.md +1 -0
- package/commands/gsd/review-backlog.md +1 -0
- package/commands/gsd/review.md +2 -3
- package/commands/gsd/settings.md +2 -1
- package/commands/gsd/stats.md +1 -0
- package/commands/gsd/thread.md +1 -0
- package/commands/gsd/workspace.md +1 -0
- package/commands/gsd/workstreams.md +1 -0
- package/gsd-core/bin/check-latest-version.cjs +8 -3
- package/gsd-core/bin/gsd-tools.cjs +672 -146
- package/gsd-core/bin/lib/adr-parser.cjs +4 -2
- package/gsd-core/bin/lib/artifacts.cjs +2 -1
- package/gsd-core/bin/lib/audit.cjs +119 -34
- package/gsd-core/bin/lib/broken-windows.cjs +168 -49
- package/gsd-core/bin/lib/capability-lifecycle.cjs +10 -6
- package/gsd-core/bin/lib/capability-loader.cjs +135 -1
- package/gsd-core/bin/lib/capability-registry.cjs +96 -189
- package/gsd-core/bin/lib/capability-source.cjs +19 -2
- package/gsd-core/bin/lib/capability-validator.cjs +14 -2
- package/gsd-core/bin/lib/check-command-router.cjs +213 -49
- package/gsd-core/bin/lib/code-review-depth.cjs +2 -2
- package/gsd-core/bin/lib/codex-agent-toml.cjs +21 -25
- package/gsd-core/bin/lib/commands.cjs +823 -112
- package/gsd-core/bin/lib/config-loader.cjs +66 -4
- package/gsd-core/bin/lib/config.cjs +186 -45
- package/gsd-core/bin/lib/coverage.cjs +1 -1
- package/gsd-core/bin/lib/decisions.cjs +164 -45
- package/gsd-core/bin/lib/external-descriptor-trust.cjs +29 -14
- package/gsd-core/bin/lib/frontmatter.cjs +13 -0
- package/gsd-core/bin/lib/graphify.cjs +10 -2
- package/gsd-core/bin/lib/gsd2-import.cjs +1 -2
- package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +12 -1
- package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +1 -1
- package/gsd-core/bin/lib/host-runtime-detection.cjs +9 -0
- package/gsd-core/bin/lib/init.cjs +614 -86
- package/gsd-core/bin/lib/install-engine.cjs +29 -3
- package/gsd-core/bin/lib/install-profiles.cjs +14 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +41 -5
- package/gsd-core/bin/lib/loop-resolver.cjs +50 -31
- package/gsd-core/bin/lib/mcp-catalog.cjs +2 -2
- package/gsd-core/bin/lib/milestone.cjs +37 -13
- package/gsd-core/bin/lib/model-resolver.cjs +253 -53
- package/gsd-core/bin/lib/phase-command-router.cjs +16 -2
- package/gsd-core/bin/lib/phase-id-card.cjs +32 -0
- package/gsd-core/bin/lib/phase-id-display.cjs +78 -0
- package/gsd-core/bin/lib/phase-id.cjs +268 -27
- package/gsd-core/bin/lib/phase-lifecycle.cjs +61 -0
- package/gsd-core/bin/lib/phase-locator.cjs +29 -10
- package/gsd-core/bin/lib/phase.cjs +393 -88
- package/gsd-core/bin/lib/plan-document.cjs +49 -1
- package/gsd-core/bin/lib/planning-document.cjs +459 -0
- package/gsd-core/bin/lib/planning-inspect.cjs +52 -19
- package/gsd-core/bin/lib/planning-snapshot.cjs +61 -12
- package/gsd-core/bin/lib/planning-workspace.cjs +57 -3
- package/gsd-core/bin/lib/pr-branch-patterns.cjs +57 -0
- package/gsd-core/bin/lib/pristine-baseline.cjs +182 -0
- package/gsd-core/bin/lib/probe-core.cjs +7 -1
- package/gsd-core/bin/lib/prohibition-enforcement.cjs +91 -4
- package/gsd-core/bin/lib/project-root.cjs +41 -2
- package/gsd-core/bin/lib/quick-batch.cjs +1 -1
- package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +61 -2
- package/gsd-core/bin/lib/research-store.cjs +11 -12
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +10 -30
- package/gsd-core/bin/lib/review-lane-invocation.cjs +23 -0
- package/gsd-core/bin/lib/review-reviewer-selection.cjs +2 -2
- package/gsd-core/bin/lib/reviewer-step-dispatch.cjs +337 -0
- package/gsd-core/bin/lib/roadmap-command-router.cjs +12 -4
- package/gsd-core/bin/lib/roadmap-parser.cjs +219 -18
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +1539 -13
- package/gsd-core/bin/lib/roadmap.cjs +356 -42
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +310 -41
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +15 -4
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +13 -5
- package/gsd-core/bin/lib/runtime-homes.cjs +4 -0
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +408 -37
- package/gsd-core/bin/lib/runtime-name-policy.cjs +111 -1
- package/gsd-core/bin/lib/security.cjs +126 -7
- package/gsd-core/bin/lib/shell-command-projection.cjs +10 -6
- package/gsd-core/bin/lib/state-document.cjs +130 -28
- package/gsd-core/bin/lib/state-md-schema.cjs +21 -14
- package/gsd-core/bin/lib/state-transition.cjs +181 -30
- package/gsd-core/bin/lib/state.cjs +265 -27
- package/gsd-core/bin/lib/surface.cjs +77 -3
- package/gsd-core/bin/lib/task-command-router.cjs +12 -6
- package/gsd-core/bin/lib/tdd-red-evidence.cjs +78 -5
- package/gsd-core/bin/lib/uat-predicate.cjs +47 -4
- package/gsd-core/bin/lib/uat.cjs +9 -1
- package/gsd-core/bin/lib/ui-consideration-probe.cjs +15 -2
- package/gsd-core/bin/lib/ui-frontend-evidence.cjs +100 -9
- package/gsd-core/bin/lib/undo-commit-selection.cjs +131 -0
- package/gsd-core/bin/lib/update-context.cjs +30 -24
- package/gsd-core/bin/lib/vendor/js-yaml.cjs +11 -3
- package/gsd-core/bin/lib/verification.cjs +315 -30
- package/gsd-core/bin/lib/verify-command-grounding.cjs +47 -3
- package/gsd-core/bin/lib/verify.cjs +320 -48
- package/gsd-core/bin/lib/workstream-inventory.cjs +1 -0
- package/gsd-core/bin/lib/worktree-base-ref.cjs +482 -73
- package/gsd-core/bin/lib/worktree-safety.cjs +797 -58
- package/gsd-core/bin/shared/config-defaults.manifest.json +4 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +6 -0
- package/gsd-core/bin/verify-reapply-patches.cjs +439 -80
- package/gsd-core/references/checkpoints.md +5 -3
- package/gsd-core/references/compact-content-gate.md +66 -0
- package/gsd-core/references/edge-probe-fixtures/01-round-half-even/expected-coverage.json +28 -3
- package/gsd-core/references/edge-probe-fixtures/02-merge-intervals/expected-coverage.json +37 -4
- package/gsd-core/references/edge-probe-fixtures/03-truncate-graphemes/expected-coverage.json +28 -3
- package/gsd-core/references/edge-probe-fixtures/04-money-rounding/expected-coverage.json +28 -3
- package/gsd-core/references/edge-probe-fixtures/05-list-dedupe/expected-coverage.json +37 -4
- package/gsd-core/references/edge-probe-fixtures/06-resolved-mixed/expected-coverage.json +37 -4
- package/gsd-core/references/edge-probe.md +195 -21
- package/gsd-core/references/execute-phase-between-wave-reset.md +7 -6
- package/gsd-core/references/execute-phase-wave-guard.md +22 -11
- package/gsd-core/references/gsd-run-resolver.md +1 -1
- package/gsd-core/references/loop-hook-dispatch.md +18 -0
- package/gsd-core/references/model-profiles.md +13 -4
- package/gsd-core/references/phase-argument-parsing.md +9 -7
- package/gsd-core/references/phase-id-convention.md +28 -0
- package/gsd-core/references/planner-gap-closure.md +2 -0
- package/gsd-core/references/planner-load-graph-context.md +24 -13
- package/gsd-core/references/planner-verify-command-grounding.md +14 -0
- package/gsd-core/references/planning-config.md +14 -2
- package/gsd-core/references/tdd.md +30 -4
- package/gsd-core/references/thinking-models-planning.md +18 -2
- package/gsd-core/references/ui-consideration-probe.md +10 -5
- package/gsd-core/references/verification-patterns.md +17 -4
- package/gsd-core/references/verify-command-path-resolvability.md +10 -2
- package/gsd-core/references/worktree-path-safety.md +433 -2
- package/gsd-core/templates/README.md +7 -1
- package/gsd-core/templates/state.md +6 -3
- package/gsd-core/templates/summary.compact.md +212 -0
- package/gsd-core/templates/user-setup.compact.md +199 -0
- package/gsd-core/templates/user-setup.md +0 -9
- package/gsd-core/templates/verification-report.md +1 -1
- package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
- package/gsd-core/workflows/add-backlog.md +1 -1
- package/gsd-core/workflows/add-phase.md +1 -1
- package/gsd-core/workflows/add-tests.md +2 -2
- package/gsd-core/workflows/add-todo.md +6 -5
- package/gsd-core/workflows/ai-integration-phase.md +11 -3
- package/gsd-core/workflows/audit-fix.md +1 -1
- package/gsd-core/workflows/audit-milestone.md +1 -1
- package/gsd-core/workflows/audit-uat.md +1 -1
- package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +9 -18
- package/gsd-core/workflows/autonomous.md +29 -16
- package/gsd-core/workflows/check-todos.md +6 -4
- package/gsd-core/workflows/cleanup.md +5 -3
- package/gsd-core/workflows/code-review/steps/dispatch-fix.md +4 -3
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +8 -1
- package/gsd-core/workflows/code-review-fix.md +108 -22
- package/gsd-core/workflows/code-review.md +216 -73
- package/gsd-core/workflows/complete-milestone/detail/elaboration.md +274 -0
- package/gsd-core/workflows/complete-milestone.md +41 -264
- package/gsd-core/workflows/debug.md +3 -3
- package/gsd-core/workflows/diagnose-issues.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/chain.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions.md +1 -1
- package/gsd-core/workflows/discuss-phase.md +1 -1
- package/gsd-core/workflows/do.md +2 -2
- package/gsd-core/workflows/docs-update/detail/elaboration.md +179 -0
- package/gsd-core/workflows/docs-update.md +17 -158
- package/gsd-core/workflows/edit-phase.md +1 -1
- package/gsd-core/workflows/eval-review.md +10 -3
- package/gsd-core/workflows/execute-phase/detail/elaboration.md +124 -0
- package/gsd-core/workflows/execute-phase/steps/code-review-disposition.md +1017 -0
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +19 -4
- package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +56 -0
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +43 -4
- package/gsd-core/workflows/execute-phase/steps/executor-progress-policy.md +43 -0
- package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/partial-wave.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +46 -9
- package/gsd-core/workflows/execute-phase/steps/protected-branch.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/ready-wave-gate.md +37 -0
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/sequential-root-pin.md +35 -0
- package/gsd-core/workflows/execute-phase/steps/stale-reverification.md +24 -0
- package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/threat-id-gate.md +28 -0
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/worktree-base-check.md +25 -0
- package/gsd-core/workflows/execute-phase.md +83 -172
- package/gsd-core/workflows/execute-plan.md +24 -10
- package/gsd-core/workflows/explore.md +3 -3
- package/gsd-core/workflows/extract-learnings.md +2 -1
- package/gsd-core/workflows/fast.md +1 -1
- package/gsd-core/workflows/forensics.md +1 -1
- package/gsd-core/workflows/graduation.md +1 -1
- package/gsd-core/workflows/health.md +2 -2
- package/gsd-core/workflows/help/modes/full.compact.md +398 -0
- package/gsd-core/workflows/help/modes/full.md +5 -5
- package/gsd-core/workflows/help/modes/topic.md +15 -5
- package/gsd-core/workflows/help.md +1 -1
- package/gsd-core/workflows/import.md +2 -2
- package/gsd-core/workflows/inbox.md +2 -2
- package/gsd-core/workflows/ingest-docs.md +3 -3
- package/gsd-core/workflows/insert-phase.md +1 -1
- package/gsd-core/workflows/list-seeds.md +1 -1
- package/gsd-core/workflows/list-workspaces.md +1 -1
- package/gsd-core/workflows/manager.md +2 -2
- package/gsd-core/workflows/map-codebase.md +52 -5
- package/gsd-core/workflows/milestone-summary.md +1 -1
- package/gsd-core/workflows/mvp-phase.md +1 -1
- package/gsd-core/workflows/new-milestone.md +56 -14
- package/gsd-core/workflows/new-project/detail/elaboration.md +216 -0
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +3 -3
- package/gsd-core/workflows/new-project/steps/codebase-map-offer.md +1 -1
- package/gsd-core/workflows/new-project.md +39 -209
- package/gsd-core/workflows/new-workspace.md +2 -2
- package/gsd-core/workflows/next.md +1 -1
- package/gsd-core/workflows/note.md +1 -1
- package/gsd-core/workflows/onboard.md +1 -1
- package/gsd-core/workflows/pause-work.md +1 -1
- package/gsd-core/workflows/plan-phase/detail/elaboration.md +209 -0
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +17 -5
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +23 -5
- package/gsd-core/workflows/plan-phase.md +45 -187
- package/gsd-core/workflows/plan-review-convergence.md +21 -5
- package/gsd-core/workflows/plant-seed.md +62 -20
- package/gsd-core/workflows/pr-branch.md +132 -20
- package/gsd-core/workflows/profile-user.md +2 -2
- package/gsd-core/workflows/progress.md +1 -1
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +25 -0
- package/gsd-core/workflows/quick/steps/quick-verification.md +1 -1
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/batch-init.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/completion.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/merge-wave.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/planner-wave.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/research-phase.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/resume-mode.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/verification-wave.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +1 -1
- package/gsd-core/workflows/quick-batch.md +1 -1
- package/gsd-core/workflows/quick.md +29 -10
- package/gsd-core/workflows/reapply-patches.md +86 -6
- package/gsd-core/workflows/remove-phase.md +1 -1
- package/gsd-core/workflows/remove-workspace.md +2 -2
- package/gsd-core/workflows/resume-project.md +1 -1
- package/gsd-core/workflows/review.md +31 -16
- package/gsd-core/workflows/scan.md +1 -1
- package/gsd-core/workflows/secure-phase.md +3 -2
- package/gsd-core/workflows/settings-advanced.md +30 -10
- package/gsd-core/workflows/settings-integrations.md +2 -3
- package/gsd-core/workflows/settings.md +22 -9
- package/gsd-core/workflows/ship.md +3 -2
- package/gsd-core/workflows/sketch-wrap-up.md +1 -1
- package/gsd-core/workflows/sketch.md +1 -1
- package/gsd-core/workflows/smart-entry.md +2 -2
- package/gsd-core/workflows/spec-phase.md +15 -5
- package/gsd-core/workflows/spike-wrap-up.md +1 -1
- package/gsd-core/workflows/spike.md +1 -1
- package/gsd-core/workflows/stats.md +1 -1
- package/gsd-core/workflows/sync-skills.md +5 -5
- package/gsd-core/workflows/thread.md +1 -1
- package/gsd-core/workflows/transition.md +1 -1
- package/gsd-core/workflows/ui-phase.md +44 -8
- package/gsd-core/workflows/ui-review.md +18 -4
- package/gsd-core/workflows/ultraplan-phase.md +1 -1
- package/gsd-core/workflows/undo.md +339 -20
- package/gsd-core/workflows/update.md +14 -12
- package/gsd-core/workflows/validate-phase.md +3 -2
- package/gsd-core/workflows/verify-work/detail/elaboration.md +230 -0
- package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +1 -1
- package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +1 -1
- package/gsd-core/workflows/verify-work.md +101 -196
- package/hooks/dist/gsd-agent-isolation-guard.js +66 -16
- package/hooks/dist/gsd-context-monitor.js +88 -15
- package/hooks/dist/gsd-cursor-subagent-start.js +34 -14
- package/hooks/dist/gsd-secret-read-guard.js +71 -19
- package/hooks/dist/gsd-statusline.js +81 -20
- package/hooks/dist/gsd-validate-commit.sh +97 -8
- package/hooks/dist/gsd-worktree-path-guard.js +25 -14
- package/hooks/dist/gsd-write-guard.js +46 -1
- package/hooks/dist/lib/dispatch-identity.js +187 -0
- package/hooks/dist/lib/filename-classification.js +64 -0
- package/hooks/dist/lib/isolation-deny-reason.js +53 -1
- package/hooks/dist/lib/isolation-sentinel.js +58 -19
- package/hooks/gsd-agent-isolation-guard.js +66 -16
- package/hooks/gsd-context-monitor.js +88 -15
- package/hooks/gsd-cursor-subagent-start.js +34 -14
- package/hooks/gsd-secret-read-guard.js +71 -19
- package/hooks/gsd-statusline.js +81 -20
- package/hooks/gsd-validate-commit.sh +97 -8
- package/hooks/gsd-worktree-path-guard.js +25 -14
- package/hooks/gsd-write-guard.js +46 -1
- package/hooks/lib/dispatch-identity.js +187 -0
- package/hooks/lib/filename-classification.js +64 -0
- package/hooks/lib/isolation-deny-reason.js +53 -1
- package/hooks/lib/isolation-sentinel.js +58 -19
- package/package.json +11 -6
- package/scripts/benchmark-compact-content-variants.cjs +298 -0
- package/scripts/benchmark-compact-content.cjs +368 -0
- package/scripts/build-hooks.js +15 -6
- package/scripts/check-contract-drift.cjs +131 -12
- package/scripts/check-env.cjs +36 -8
- package/scripts/check-glossary-refs.cjs +25 -21
- package/scripts/ci-next-health.cjs +271 -0
- package/scripts/ci-prepare-test-scope.cjs +7 -7
- package/scripts/ci-test-scope.cjs +126 -20
- package/scripts/ci-timeout-report.cjs +1 -1
- package/scripts/command-contract-helpers.cjs +3 -0
- package/scripts/diff-touches-shipped-paths.cjs +1 -1
- package/scripts/docs-guard-registry.cjs +35 -2
- package/scripts/gen-adr-index.cjs +8 -2
- package/scripts/gen-inventory-manifest.cjs +12 -0
- package/scripts/gen-loop-host-contract.cjs +69 -0
- package/scripts/gen-platform-conformance-tier.cjs +557 -0
- package/scripts/lib/drift-scan.cjs +1 -1
- package/scripts/lib/macos-conformance-tier.generated.cjs +224 -0
- package/scripts/lib/ndjson-reporter.cjs +3 -2
- package/scripts/lib/npm-version-check-diagnosis.cjs +59 -0
- package/scripts/lib/platform-conformance-tier.generated.cjs +287 -0
- package/scripts/lib/suite-detection.cjs +32 -0
- package/scripts/lint-allowed-tools-parity.cjs +221 -0
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +47 -3
- package/scripts/lint-phase-arg-assignment.cjs +257 -0
- package/scripts/lint-phase-id-drift.cjs +623 -13
- package/scripts/lint-pr-branch-pattern-drift.cjs +148 -0
- package/scripts/lint-response-language-coverage.cjs +9 -3
- package/scripts/lint-retired-runtime-name.cjs +619 -0
- package/scripts/lint-source-test-name-collision.cjs +1 -1
- package/scripts/lint-state-write-path-drift.cjs +93 -0
- package/scripts/lint-test-file-count.allowlist.json +29 -9
- package/scripts/lint-vendored-deps.cjs +128 -17
- package/scripts/lint-workflow-shellcheck-baseline.json +100 -0
- package/scripts/prompt-injection-scan.sh +18 -0
- package/scripts/release-tarball-smoke.cjs +194 -1
- package/scripts/workflow-size.cjs +139 -0
- package/skills/gsd-autonomous/SKILL.md +2 -2
- package/skills/gsd-capture/SKILL.md +1 -1
- package/skills/gsd-cleanup/SKILL.md +1 -0
- package/skills/gsd-code-review/SKILL.md +2 -1
- package/skills/gsd-complete-milestone/SKILL.md +1 -0
- package/skills/gsd-config/SKILL.md +1 -0
- package/skills/gsd-debug/SKILL.md +1 -0
- package/skills/gsd-graphify/SKILL.md +1 -0
- package/skills/gsd-health/SKILL.md +1 -0
- package/skills/gsd-mempalace-capture/SKILL.md +8 -3
- package/skills/gsd-mempalace-recall/SKILL.md +1 -0
- package/skills/gsd-new-milestone/SKILL.md +1 -0
- package/skills/gsd-new-project/SKILL.md +1 -0
- package/skills/gsd-next/SKILL.md +1 -0
- package/skills/gsd-pause-work/SKILL.md +1 -0
- package/skills/gsd-phase/SKILL.md +1 -0
- package/skills/gsd-plan-review-convergence/SKILL.md +5 -5
- package/skills/gsd-pr-branch/SKILL.md +1 -0
- package/skills/gsd-progress/SKILL.md +1 -1
- package/skills/gsd-quick-batch/SKILL.md +1 -1
- package/skills/gsd-resume-work/SKILL.md +1 -0
- package/skills/gsd-review/SKILL.md +2 -3
- package/skills/gsd-review-backlog/SKILL.md +1 -0
- package/skills/gsd-settings/SKILL.md +2 -1
- package/skills/gsd-stats/SKILL.md +1 -0
- package/skills/gsd-thread/SKILL.md +1 -0
- package/skills/gsd-workspace/SKILL.md +1 -0
- package/skills/gsd-workstreams/SKILL.md +1 -0
- package/vscode/package.json +1 -1
- package/gsd-core/templates/claude-md.md +0 -145
- package/gsd-core/templates/codebase/concerns.md +0 -310
- package/gsd-core/templates/codebase/conventions.md +0 -307
- package/gsd-core/templates/codebase/integrations.md +0 -280
- package/gsd-core/templates/codebase/structure.md +0 -285
- package/gsd-core/templates/codebase/testing.md +0 -480
- package/gsd-core/templates/debug-subagent-prompt.md +0 -91
- package/gsd-core/templates/discovery.md +0 -146
|
@@ -37,6 +37,12 @@
|
|
|
37
37
|
* colon-namespace leaks (WORKFLOW_BODY_COLON_LEAK).
|
|
38
38
|
* This check populates result.details with counters but does NOT return a
|
|
39
39
|
* failure code by default; it is informational until enforcement is enabled.
|
|
40
|
+
*
|
|
41
|
+
* Configured-entrypoint checks (Cycle 4 — #4154):
|
|
42
|
+
* For each runtime in entrypointRuntimes, runs the tarball-installed
|
|
43
|
+
* installer into a throwaway HOME, then re-reads that runtime's own written
|
|
44
|
+
* config files and asserts every GSD-managed script path they name resolves
|
|
45
|
+
* to a file (ENTRYPOINT_UNRESOLVED). Requires fixtureDir.
|
|
40
46
|
*/
|
|
41
47
|
|
|
42
48
|
'use strict';
|
|
@@ -47,6 +53,8 @@ const os = require('os');
|
|
|
47
53
|
const path = require('path');
|
|
48
54
|
const { PACKAGE_NAME } = require('../gsd-core/bin/lib/package-identity.cjs');
|
|
49
55
|
const { ExitError, runMain } = require('./lib/cli-exit.cjs');
|
|
56
|
+
const shellCmdProjection = require('../gsd-core/bin/lib/shell-command-projection.cjs');
|
|
57
|
+
const { escapeRegex } = require('../gsd-core/bin/lib/pattern.cjs');
|
|
50
58
|
// 120 s proved too tight for cold-cache `npm install -g` of a 1499-file tarball:
|
|
51
59
|
// spawnSync fires SIGTERM at the deadline and returns { status: null, stdout: '',
|
|
52
60
|
// stderr: '' } (Node docs: status is null when a subprocess is terminated by a
|
|
@@ -86,6 +94,8 @@ const SMOKE = Object.freeze({
|
|
|
86
94
|
INIT_FAILED: 'init_failed',
|
|
87
95
|
// Cycle 3 code
|
|
88
96
|
WORKFLOW_BODY_COLON_LEAK: 'workflow_body_colon_leak',
|
|
97
|
+
// Cycle 4 code (#4154)
|
|
98
|
+
ENTRYPOINT_UNRESOLVED: 'entrypoint_unresolved',
|
|
89
99
|
});
|
|
90
100
|
|
|
91
101
|
// ---------------------------------------------------------------------------
|
|
@@ -274,6 +284,106 @@ function scanWorkflowColonLeak(filePath, cmdNames) {
|
|
|
274
284
|
return null;
|
|
275
285
|
}
|
|
276
286
|
|
|
287
|
+
// ---------------------------------------------------------------------------
|
|
288
|
+
// Cycle 4 helpers: configured-entrypoint resolution (#4154)
|
|
289
|
+
// ---------------------------------------------------------------------------
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Top-level config files this scan reads. These are the surfaces that carry
|
|
293
|
+
* every GSD-managed launch path for the runtimes Cycle 4 actually installs
|
|
294
|
+
* (`entrypointRuntimes`, default claude + codex): claude registers into
|
|
295
|
+
* settings.json, codex into hooks.json and config.toml.
|
|
296
|
+
*
|
|
297
|
+
* This is NOT an exhaustive map of where GSD writes launch paths across all
|
|
298
|
+
* runtimes, and the scan is top-level only by design. Two known surfaces sit
|
|
299
|
+
* outside it: Cline registers its hook at `.clinerules/hooks/PreToolUse` (a
|
|
300
|
+
* subdirectory, and not one of these names — see writeClineArtifacts in
|
|
301
|
+
* src/runtime-hooks-surface.cts), and Kimi's native `[[hooks]]` config.toml
|
|
302
|
+
* lives under `resolveKimiHooksTomlDir()` (`~/.kimi`), a directory separate
|
|
303
|
+
* from Kimi's own GSD configDir. Adding either runtime to entrypointRuntimes
|
|
304
|
+
* requires teaching scanConfiguredEntrypoints about its surface first,
|
|
305
|
+
* otherwise the scan reports zero entrypoints and silently proves nothing.
|
|
306
|
+
*/
|
|
307
|
+
const RUNTIME_CONFIG_FILES = Object.freeze(['settings.json', 'hooks.json', 'config.toml']);
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Extract every script path `text` names underneath `configDir`.
|
|
311
|
+
*
|
|
312
|
+
* #4249 (antigravity review): anchored on the literal, already-known
|
|
313
|
+
* `configDir` prefix instead of a generic "any absolute path" character
|
|
314
|
+
* class. The prior version excluded whitespace from the match to avoid
|
|
315
|
+
* swallowing a shell command's trailing args, which also truncated any
|
|
316
|
+
* legitimate path containing a space (e.g. `/Users/John Doe/.claude`) —
|
|
317
|
+
* `scanConfiguredEntrypoints` would then silently report zero checked
|
|
318
|
+
* paths. Anchoring on `configDir` removes the ambiguity outright: a match
|
|
319
|
+
* can only start where the known prefix literally occurs in the text, so
|
|
320
|
+
* an interpreter path concatenated ahead of it (`"/usr/bin/node
|
|
321
|
+
* /configDir/hooks/foo.js"`) is never swallowed either, and interior
|
|
322
|
+
* whitespace inside `configDir` or the script's own path segments is safe
|
|
323
|
+
* to allow. This still scans raw, unparsed config text on purpose (see
|
|
324
|
+
* scanConfiguredEntrypoints's doc comment) — it catches a writer that
|
|
325
|
+
* embeds a launch path without registering it, which a structured
|
|
326
|
+
* JSON.parse of the expected schema would miss entirely.
|
|
327
|
+
*
|
|
328
|
+
* Windows configs store paths with backslashes, which JSON/TOML doubles on
|
|
329
|
+
* write; collapsing `\\` to `\` first makes the raw text scan work on both
|
|
330
|
+
* platforms without parsing each config format separately (POSIX text has no
|
|
331
|
+
* backslashes, so the collapse is a no-op there).
|
|
332
|
+
*
|
|
333
|
+
* Every writer bakes `configDir` through the same posixNormalize seam
|
|
334
|
+
* (src/runtime-hooks-surface.cts) before writing it into config text, on
|
|
335
|
+
* every platform — so the anchor must match that projection, not the
|
|
336
|
+
* OS-native `configDir` string this function receives.
|
|
337
|
+
*/
|
|
338
|
+
function configuredEntrypointsIn(text, configDir) {
|
|
339
|
+
const normalizedPrefix = shellCmdProjection.posixNormalize(configDir).replace(/\/+$/, '') + '/';
|
|
340
|
+
const scriptPathRe = new RegExp(`${escapeRegex(normalizedPrefix)}[^"']{0,400}?\\.(?:js|cjs|mjs|sh|cmd|ps1)`, 'g');
|
|
341
|
+
const found = new Set();
|
|
342
|
+
for (const match of text.replace(/\\\\/g, '\\').matchAll(scriptPathRe)) {
|
|
343
|
+
found.add(path.resolve(match[0]));
|
|
344
|
+
}
|
|
345
|
+
return [...found];
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Throwaway HOME the Cycle 4 install for `runtime` runs against. Exported so a
|
|
350
|
+
* test can seed that runtime's config before the install rather than
|
|
351
|
+
* hard-coding the layout runSmoke picks.
|
|
352
|
+
*/
|
|
353
|
+
function entrypointFixtureHome(fixtureDir, runtime) {
|
|
354
|
+
return path.join(fixtureDir, `entrypoints-${runtime}`);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Re-derive the configured entrypoints a completed install wrote into a
|
|
359
|
+
* runtime's own config files and report the ones that do not resolve to a
|
|
360
|
+
* file. Internal to Cycle 4; the smoke's verdict is the exported contract.
|
|
361
|
+
*
|
|
362
|
+
* This deliberately does NOT consult the installer's own entrypoint list (the
|
|
363
|
+
* assertConfiguredEntrypoints gate in bin/install.js). That gate can only
|
|
364
|
+
* validate paths a config writer remembered to register; reading the written
|
|
365
|
+
* config back is what catches a writer that emits a launch path without
|
|
366
|
+
* registering it, and a stale registration an install left behind.
|
|
367
|
+
*
|
|
368
|
+
* @param {string} configDir - Absolute path to the runtime config dir.
|
|
369
|
+
* @returns {{ checked: string[], unresolved: { configPath: string, scriptPath: string }[] }}
|
|
370
|
+
*/
|
|
371
|
+
function scanConfiguredEntrypoints(configDir) {
|
|
372
|
+
const checked = [];
|
|
373
|
+
const unresolved = [];
|
|
374
|
+
for (const name of RUNTIME_CONFIG_FILES) {
|
|
375
|
+
const configPath = path.join(configDir, name);
|
|
376
|
+
if (!fs.existsSync(configPath) || !fs.statSync(configPath).isFile()) continue;
|
|
377
|
+
const text = fs.readFileSync(configPath, 'utf-8');
|
|
378
|
+
for (const scriptPath of configuredEntrypointsIn(text, configDir)) {
|
|
379
|
+
checked.push(scriptPath);
|
|
380
|
+
if (fs.existsSync(scriptPath) && fs.statSync(scriptPath).isFile()) continue;
|
|
381
|
+
unresolved.push({ configPath, scriptPath });
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return { checked, unresolved };
|
|
385
|
+
}
|
|
386
|
+
|
|
277
387
|
// ---------------------------------------------------------------------------
|
|
278
388
|
// Pure function: runSmoke
|
|
279
389
|
// ---------------------------------------------------------------------------
|
|
@@ -285,6 +395,8 @@ function scanWorkflowColonLeak(filePath, cmdNames) {
|
|
|
285
395
|
* @param {string} opts.expectedVersion - semver string to assert (e.g. "1.50.0")
|
|
286
396
|
* @param {string} [opts.fixtureDir] - Temp dir to run `init` into (must NOT be HOME)
|
|
287
397
|
* @param {string[]} [opts.lifecycleCommands] - Commands to file-check (default: see below)
|
|
398
|
+
* @param {string[]} [opts.entrypointRuntimes] - Runtime profiles whose configured entrypoints are
|
|
399
|
+
* re-checked after a real install (default: see below). Requires fixtureDir; pass [] to skip.
|
|
288
400
|
* @param {boolean} [opts.dryRun=false] - If true, skip actual npm install; validate input only
|
|
289
401
|
* @param {object} [opts.npmEnv] - Optional env dict for the internal npm install
|
|
290
402
|
* spawnSync call. Pass an isolated HOME env (e.g. from isolatedNpmEnv() in tests/helpers.cjs)
|
|
@@ -298,6 +410,11 @@ function runSmoke({
|
|
|
298
410
|
expectedVersion,
|
|
299
411
|
fixtureDir,
|
|
300
412
|
lifecycleCommands = ['init', 'discuss-phase', 'plan-phase', 'execute-phase'],
|
|
413
|
+
// claude and codex cover the two top-level config surfaces this scan knows
|
|
414
|
+
// how to read (settings.json, and hooks.json + config.toml). Most other
|
|
415
|
+
// runtimes reuse one of those two shapes; Cline and Kimi do not (see
|
|
416
|
+
// RUNTIME_CONFIG_FILES), so they are out of scope here rather than covered.
|
|
417
|
+
entrypointRuntimes = ['claude', 'codex'],
|
|
301
418
|
dryRun = false,
|
|
302
419
|
npmEnv = undefined,
|
|
303
420
|
}) {
|
|
@@ -551,6 +668,75 @@ function runSmoke({
|
|
|
551
668
|
// NOTE: colonLeakCount is informational here. Once the backlog is fixed,
|
|
552
669
|
// a future enforcement mode can fail on non-zero counts.
|
|
553
670
|
|
|
671
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
672
|
+
// Cycle 4: configured-entrypoint resolution (#4154)
|
|
673
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
674
|
+
|
|
675
|
+
// The installer's own gate (assertConfiguredEntrypoints) runs in-process and
|
|
676
|
+
// only sees the paths a config writer registered with it. Installing the
|
|
677
|
+
// packed tarball for real and reading each runtime's written config back is
|
|
678
|
+
// what proves the launch paths a user's runtime will actually invoke exist
|
|
679
|
+
// in the shipped layout.
|
|
680
|
+
const entrypointProfiles = [];
|
|
681
|
+
if (fixtureDir && entrypointRuntimes.length > 0) {
|
|
682
|
+
for (const runtime of entrypointRuntimes) {
|
|
683
|
+
// Own HOME per runtime so a --global install cannot reach the real one.
|
|
684
|
+
const runtimeHome = entrypointFixtureHome(fixtureDir, runtime);
|
|
685
|
+
const configDir = path.join(runtimeHome, `.${runtime}`);
|
|
686
|
+
fs.mkdirSync(runtimeHome, { recursive: true });
|
|
687
|
+
|
|
688
|
+
const installResult = spawnSync(
|
|
689
|
+
process.execPath,
|
|
690
|
+
[path.join(pkg, 'bin', 'install.js'), `--${runtime}`, '--global', '--config-dir', configDir],
|
|
691
|
+
{
|
|
692
|
+
encoding: 'utf-8',
|
|
693
|
+
cwd: runtimeHome,
|
|
694
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
695
|
+
env: {
|
|
696
|
+
...effectiveNpmEnv,
|
|
697
|
+
HOME: runtimeHome,
|
|
698
|
+
USERPROFILE: runtimeHome,
|
|
699
|
+
// Same reason as the init check above: install.js skips its main()
|
|
700
|
+
// block when GSD_TEST_MODE is set and would exit 0 writing nothing.
|
|
701
|
+
GSD_TEST_MODE: '',
|
|
702
|
+
NO_UPDATE_NOTIFIER: '1',
|
|
703
|
+
},
|
|
704
|
+
timeout: CHILD_TIMEOUT_MS,
|
|
705
|
+
},
|
|
706
|
+
);
|
|
707
|
+
|
|
708
|
+
if (installResult.status !== 0) {
|
|
709
|
+
// #4249 (antigravity review): this is the Cycle 4 per-runtime install,
|
|
710
|
+
// not Cycle 1's `gsd init` — SMOKE.INSTALL_FAILED is the code Cycle 2's
|
|
711
|
+
// identical spawnSync-failure check already uses for the same failure
|
|
712
|
+
// class; reusing SMOKE.INIT_FAILED here conflated the two lifecycle
|
|
713
|
+
// stages in the reported code.
|
|
714
|
+
return {
|
|
715
|
+
code: SMOKE.INSTALL_FAILED,
|
|
716
|
+
details: {
|
|
717
|
+
...details,
|
|
718
|
+
runtime,
|
|
719
|
+
configDir,
|
|
720
|
+
stderr: installResult.stderr,
|
|
721
|
+
stdout: installResult.stdout,
|
|
722
|
+
},
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
const scan = scanConfiguredEntrypoints(configDir);
|
|
727
|
+
if (scan.unresolved.length > 0) {
|
|
728
|
+
return {
|
|
729
|
+
code: SMOKE.ENTRYPOINT_UNRESOLVED,
|
|
730
|
+
details: { ...details, runtime, configDir, unresolved: scan.unresolved },
|
|
731
|
+
};
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
entrypointProfiles.push({ runtime, configDir, entrypointsChecked: scan.checked.length });
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
details.entrypointProfiles = entrypointProfiles;
|
|
739
|
+
|
|
554
740
|
return { code: SMOKE.OK, details };
|
|
555
741
|
}
|
|
556
742
|
|
|
@@ -635,7 +821,14 @@ function cleanup(...dirs) {
|
|
|
635
821
|
// Exports
|
|
636
822
|
// ---------------------------------------------------------------------------
|
|
637
823
|
|
|
638
|
-
module.exports = {
|
|
824
|
+
module.exports = {
|
|
825
|
+
SMOKE,
|
|
826
|
+
runSmoke,
|
|
827
|
+
binInvocation,
|
|
828
|
+
entrypointFixtureHome,
|
|
829
|
+
CHILD_TIMEOUT_MS,
|
|
830
|
+
configuredEntrypointsIn,
|
|
831
|
+
};
|
|
639
832
|
|
|
640
833
|
if (require.main === module) {
|
|
641
834
|
runMain(cliMain);
|
|
@@ -89,10 +89,149 @@ function measureWorkflows(dir = WORKFLOWS_DIR) {
|
|
|
89
89
|
return measureMdFiles(dir);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
/**
|
|
93
|
+
* #4261: the reserved margin, as a fraction of a tier's hard cap.
|
|
94
|
+
*
|
|
95
|
+
* The hard caps are red lines and stay exactly where they are. This is the
|
|
96
|
+
* second, softer level the caps never had: `execute-phase.md` already carries
|
|
97
|
+
* a hand-rolled version of this shape (a hard `< 93600` plus a `<= 93400`
|
|
98
|
+
* margin whose own message says it exists "so minor future edits don't
|
|
99
|
+
* re-trip the gate"), and it is the only capped file that does. Everywhere
|
|
100
|
+
* else a file is either fine or already over, with nothing in between — so
|
|
101
|
+
* the first signal a contributor gets is a failure, and by then the cheap
|
|
102
|
+
* moment to extract has passed.
|
|
103
|
+
*
|
|
104
|
+
* 95% is deliberately not derived from anything. It is the round number the
|
|
105
|
+
* issue proposed, and the census below is what makes it reviewable: if it
|
|
106
|
+
* turns out to name too many or too few files, that is visible in one table
|
|
107
|
+
* rather than argued from first principles.
|
|
108
|
+
*/
|
|
109
|
+
const MARGIN_RATIO = 0.95;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* The reserved-margin threshold for a hard cap, in bytes.
|
|
113
|
+
*
|
|
114
|
+
* Floor, not round: the margin must never land ON or above the cap it is
|
|
115
|
+
* meant to sit under, however small the cap.
|
|
116
|
+
*
|
|
117
|
+
* @param {number} cap - Tier hard cap in bytes.
|
|
118
|
+
* @returns {number} Margin threshold in bytes.
|
|
119
|
+
*/
|
|
120
|
+
function marginFor(cap) {
|
|
121
|
+
return Math.floor(cap * MARGIN_RATIO);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Build the headroom census for a set of measured files.
|
|
126
|
+
*
|
|
127
|
+
* Sorted by pressure (least headroom first) because that is the reading
|
|
128
|
+
* order that matters: the top row is the file that will break next.
|
|
129
|
+
*
|
|
130
|
+
* @param {Object<string, number>} sizes - Map of filename -> LF byte size.
|
|
131
|
+
* @param {function(string): {tier: string, cap: number}} capFor - Tier lookup, keyed by stem.
|
|
132
|
+
* @returns {Array<{name: string, tier: string, bytes: number, cap: number, margin: number, headroom: number, usedPct: number, overMargin: boolean}>}
|
|
133
|
+
*/
|
|
134
|
+
function buildHeadroomRows(sizes, capFor) {
|
|
135
|
+
return Object.entries(sizes)
|
|
136
|
+
.map(([file, bytes]) => {
|
|
137
|
+
const name = file.replace(/\.md$/, '');
|
|
138
|
+
const { tier, cap } = capFor(name);
|
|
139
|
+
const margin = marginFor(cap);
|
|
140
|
+
return {
|
|
141
|
+
name,
|
|
142
|
+
tier,
|
|
143
|
+
bytes,
|
|
144
|
+
cap,
|
|
145
|
+
margin,
|
|
146
|
+
headroom: cap - bytes,
|
|
147
|
+
usedPct: (bytes / cap) * 100,
|
|
148
|
+
overMargin: bytes > margin,
|
|
149
|
+
};
|
|
150
|
+
})
|
|
151
|
+
.sort((a, b) => a.headroom - b.headroom || a.name.localeCompare(b.name));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Render the census as a fixed-width text table for the test diagnostics.
|
|
156
|
+
*
|
|
157
|
+
* @param {ReturnType<typeof buildHeadroomRows>} rows
|
|
158
|
+
* @param {{limit?: number}} [opts] - How many rows to render (default: all).
|
|
159
|
+
* @returns {string[]} Lines, ready to hand to `t.diagnostic` one at a time.
|
|
160
|
+
*/
|
|
161
|
+
function formatHeadroomTable(rows, { limit = Infinity } = {}) {
|
|
162
|
+
const shown = rows.slice(0, limit);
|
|
163
|
+
const width = Math.max(4, ...shown.map((r) => r.name.length));
|
|
164
|
+
const head = `${'file'.padEnd(width)} ${'tier'.padEnd(7)} ${'bytes'.padStart(7)} ${'cap'.padStart(7)} ${'margin'.padStart(7)} ${'headroom'.padStart(8)} ${'used'.padStart(6)}`;
|
|
165
|
+
const body = shown.map(
|
|
166
|
+
(r) =>
|
|
167
|
+
`${r.name.padEnd(width)} ${r.tier.padEnd(7)} ${String(r.bytes).padStart(7)} ${String(r.cap).padStart(7)} ${String(r.margin).padStart(7)} ${String(r.headroom).padStart(8)} ${r.usedPct.toFixed(1).padStart(5)}%`,
|
|
168
|
+
);
|
|
169
|
+
return [head, ...body];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Render the census as a GitHub job-summary markdown table.
|
|
174
|
+
*
|
|
175
|
+
* Only the rows over the reserved margin: a job summary that lists all 124
|
|
176
|
+
* capped files is a log dump nobody reads, and every row below the margin is
|
|
177
|
+
* by definition not the problem. The count of the rest is still reported so
|
|
178
|
+
* an empty table cannot be mistaken for an unmeasured one.
|
|
179
|
+
*
|
|
180
|
+
* @param {string} title - Section heading (e.g. `'Agent size headroom'`).
|
|
181
|
+
* @param {ReturnType<typeof buildHeadroomRows>} rows
|
|
182
|
+
* @returns {string} Markdown block.
|
|
183
|
+
*/
|
|
184
|
+
function buildHeadroomSummaryMarkdown(title, rows) {
|
|
185
|
+
const pressured = rows.filter((r) => r.overMargin);
|
|
186
|
+
const lines = [`### ${title}`, ''];
|
|
187
|
+
if (pressured.length === 0) {
|
|
188
|
+
lines.push(`All ${rows.length} files are under the ${Math.round(MARGIN_RATIO * 100)}% reserved margin.`);
|
|
189
|
+
return `${lines.join('\n')}\n`;
|
|
190
|
+
}
|
|
191
|
+
lines.push(
|
|
192
|
+
`**${pressured.length} of ${rows.length}** files are over the ${Math.round(MARGIN_RATIO * 100)}% reserved margin.`,
|
|
193
|
+
'',
|
|
194
|
+
'| file | tier | bytes | cap | headroom | used |',
|
|
195
|
+
'| --- | --- | ---: | ---: | ---: | ---: |',
|
|
196
|
+
);
|
|
197
|
+
for (const r of pressured) {
|
|
198
|
+
lines.push(`| \`${r.name}\` | ${r.tier} | ${r.bytes} | ${r.cap} | ${r.headroom} | ${r.usedPct.toFixed(1)}% |`);
|
|
199
|
+
}
|
|
200
|
+
return `${lines.join('\n')}\n`;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Append a census block to `$GITHUB_STEP_SUMMARY` when running in CI.
|
|
205
|
+
*
|
|
206
|
+
* No-op off CI, and never throws: this is reporting, and a test suite must
|
|
207
|
+
* not go red because a summary file was not writable.
|
|
208
|
+
*
|
|
209
|
+
* @param {string} title - Section heading.
|
|
210
|
+
* @param {ReturnType<typeof buildHeadroomRows>} rows
|
|
211
|
+
* @param {NodeJS.ProcessEnv} [env]
|
|
212
|
+
* @returns {boolean} Whether anything was written.
|
|
213
|
+
*/
|
|
214
|
+
function appendHeadroomStepSummary(title, rows, env = process.env) {
|
|
215
|
+
if (!env.GITHUB_STEP_SUMMARY) return false;
|
|
216
|
+
try {
|
|
217
|
+
fs.appendFileSync(env.GITHUB_STEP_SUMMARY, `${buildHeadroomSummaryMarkdown(title, rows)}\n`);
|
|
218
|
+
return true;
|
|
219
|
+
} catch (err) {
|
|
220
|
+
process.stderr.write(`workflow-size: could not write GITHUB_STEP_SUMMARY: ${err.message}\n`);
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
92
225
|
module.exports = {
|
|
93
226
|
WORKFLOWS_DIR,
|
|
227
|
+
MARGIN_RATIO,
|
|
94
228
|
lfByteCount,
|
|
95
229
|
listWorkflowStems,
|
|
96
230
|
measureMdFiles,
|
|
97
231
|
measureWorkflows,
|
|
232
|
+
marginFor,
|
|
233
|
+
buildHeadroomRows,
|
|
234
|
+
formatHeadroomTable,
|
|
235
|
+
buildHeadroomSummaryMarkdown,
|
|
236
|
+
appendHeadroomStepSummary,
|
|
98
237
|
};
|
|
@@ -36,10 +36,10 @@ Optional flags:
|
|
|
36
36
|
- `--to N` — stop after phase N completes (halt instead of advancing to next phase).
|
|
37
37
|
- `--only N` — execute only phase N (single-phase mode).
|
|
38
38
|
- `--interactive` — run discuss inline with questions (not auto-answered), then dispatch plan→execute as background agents. Keeps the main context lean while preserving user input on decisions.
|
|
39
|
-
- `--converge` — run each phase's planning step through `gsd-plan-review-convergence` instead of plain `gsd-plan-phase`.
|
|
39
|
+
- `--converge` — run each phase's planning step through `gsd-plan-review-convergence` instead of plain `gsd-plan-phase`. Works even when `workflow.plan_review_convergence` is `false` — the explicit flag overrides the gate; the gate (`workflow.plan_review_convergence=true` enables it) governs the standalone `gsd-plan-review-convergence` command. Without the flag, planning runs `gsd-plan-phase`.
|
|
40
40
|
- `--cross-ai` — compatibility alias for `--converge`.
|
|
41
41
|
|
|
42
|
-
When `--converge` or `--cross-ai` is set, reviewer selector flags supported by `gsd-plan-review-convergence` may be passed through: `--codex`, `--
|
|
42
|
+
When `--converge` or `--cross-ai` is set, reviewer selector flags supported by `gsd-plan-review-convergence` may be passed through: `--codex`, `--claude`, `--opencode`, `--ollama`, `--lm-studio`, `--llama-cpp`, `--all`, and `--max-cycles N`.
|
|
43
43
|
|
|
44
44
|
Project context, phase list, and state are resolved inside the workflow using init commands (`gsd-tools query init.milestone-op`, `gsd-tools query roadmap.analyze`). No upfront context loading needed.
|
|
45
45
|
</context>
|
|
@@ -32,7 +32,7 @@ Mode routing:
|
|
|
32
32
|
| (none) | Structured todo in .planning/todos/ | add-todo |
|
|
33
33
|
| --note | Timestamped note file, list, or promote | note |
|
|
34
34
|
| --backlog | ROADMAP.md backlog section (999.x) | add-backlog |
|
|
35
|
-
| --seed | .planning/seeds/SEED-
|
|
35
|
+
| --seed | .planning/seeds/SEED-YYMMDD-xxx-slug.md | plant-seed |
|
|
36
36
|
| --list | Interactive todo browser + action router | check-todos |
|
|
37
37
|
| --list-seeds | Read-only seed list/audit (optional status filter) | list-seeds |
|
|
38
38
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsd-code-review
|
|
3
3
|
description: "Review source files changed during a phase for bugs, security issues, and code quality problems"
|
|
4
|
-
argument-hint: "<phase-number> [--depth=quick|standard|deep] [--files file1,file2,...] [--fix [--all] [--auto]]"
|
|
4
|
+
argument-hint: "<phase-number> [--depth=quick|standard|deep] [--files file1,file2,...] [--fix [--all] [--auto]] [reviewer-lane flags]"
|
|
5
5
|
allowed-tools:
|
|
6
6
|
- Read
|
|
7
7
|
- Bash
|
|
@@ -26,6 +26,7 @@ Arguments:
|
|
|
26
26
|
- `--fix` (optional) — after review completes (or if REVIEW.md already exists), auto-apply fixes found. Spawns gsd-code-fixer agent. Accepts sub-flags:
|
|
27
27
|
- `--all` — include Info findings in fix scope (default: Critical + Warning only)
|
|
28
28
|
- `--auto` — enable fix + re-review iteration loop, capped at 3 iterations
|
|
29
|
+
- Optional reviewer-lane flags (#4209) — any flag returned by `gsd_run review-lane flags` (the canonical reviewer-lane roster; e.g. `--codex`, `--agy`) requests that lane independently review the same already-resolved scope alongside the internal `gsd-code-reviewer` agent. Its findings are corroborating evidence only — `gsd-code-reviewer` alone verifies each claim against the actual source and writes REVIEW.md; there is exactly one REVIEW.md schema. No reviewer-lane flag (the default) reviews with only the internal agent, byte-for-byte unchanged from before #4209.
|
|
29
30
|
|
|
30
31
|
Output: {padded_phase}-REVIEW.md in phase directory + inline summary of findings
|
|
31
32
|
</objective>
|
|
@@ -5,6 +5,7 @@ argument-hint: "[CONTEXT.md|PLAN.md|SUMMARY.md]"
|
|
|
5
5
|
allowed-tools:
|
|
6
6
|
- Read
|
|
7
7
|
- Bash
|
|
8
|
+
- Grep
|
|
8
9
|
---
|
|
9
10
|
|
|
10
11
|
|
|
@@ -83,15 +84,19 @@ On any error or timeout, stop and let the phase continue -- capture is best-effo
|
|
|
83
84
|
ROOM_DIR="$STAGE/<room>/<phase-id>"
|
|
84
85
|
mkdir -p "$ROOM_DIR"
|
|
85
86
|
cp "<artifact-path>" "$ROOM_DIR/<basename>"
|
|
86
|
-
# Mine with --wing only — no --room flag; detect_room() assigns from the folder path
|
|
87
|
-
|
|
87
|
+
# Mine with --wing only — no --room flag; detect_room() assigns from the folder path.
|
|
88
|
+
# --daemon --background (#4700): MemPalace wraps every mine in a per-palace
|
|
89
|
+
# lock; a concurrent writer would make a foreground mine exit 1
|
|
90
|
+
# (MineAlreadyRunning) and this onError: skip step would silently drop the
|
|
91
|
+
# capture. The background queue defers the job until the lock frees.
|
|
92
|
+
mempalace mine "$STAGE" --wing <wing> --daemon --background
|
|
88
93
|
```
|
|
89
94
|
3. **Mirror KG facts** unless `config.mempalace.mirror_kg === false` (registry default is true — an absent key means enabled): extract decision/delivery facts and `mempalace_kg_add` them with `valid_from` = the phase date (e.g. `(<project>, decided, <decision>)` from CONTEXT; `(<phase>, delivered, <capability>)` from SUMMARY). Under `augment` these are an *additive* mirror of GSD's native `.planning/graphs/`. Under `kg_backend`/`replace` the palace KG is the *authoritative* fact store — GSD still produces `.planning/graphs/` through its normal graphify, so an unreachable palace never loses a fact.
|
|
90
95
|
4. Re-running a phase MUST NOT create duplicate drawers (deterministic ids + `check_duplicate`).
|
|
91
96
|
|
|
92
97
|
## Step 4 -- Report
|
|
93
98
|
|
|
94
|
-
Print a one-line summary: `Filed <artifact> → <wing>/<room> (<n> KG facts)` or `MemPalace
|
|
99
|
+
Print a one-line summary: `Filed <artifact> → <wing>/<room> (<n> KG facts)`, `Capture queued — palace busy; MemPalace will file it when the lock frees` (the background mine was deferred behind another writer), or `MemPalace capture skipped — <reason>` (#4700: a skipped capture is never silent).
|
|
95
100
|
|
|
96
101
|
## Anti-Patterns
|
|
97
102
|
|
package/skills/gsd-next/SKILL.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsd-plan-review-convergence
|
|
3
3
|
description: "Cross-AI plan convergence - replan until review concerns are resolved."
|
|
4
|
-
argument-hint: "<phase> [--
|
|
4
|
+
argument-hint: "<phase> [--claude] [--codex] [--coderabbit] [--opencode] [--qwen] [--cursor] [--antigravity] [--agy] [--ollama] [--lm-studio] [--llama-cpp] [--kimi-code] [--text] [--ws <name>] [--all] [--max-cycles N]"
|
|
5
5
|
allowed-tools:
|
|
6
6
|
- Read
|
|
7
7
|
- Write
|
|
@@ -20,7 +20,7 @@ Repeatedly: review plans with external AI CLIs → if HIGH or actionable non-HIG
|
|
|
20
20
|
|
|
21
21
|
**Flow:** Skill("gsd-plan-phase") → Agent→Skill("gsd-review") → check unresolved HIGH + actionable non-HIGH → Skill("gsd-plan-phase --reviews") → Agent→Skill("gsd-review") → ... → Converge or escalate
|
|
22
22
|
|
|
23
|
-
Replaces gsd-plan-phase's internal gsd-plan-checker with external AI reviewers (codex,
|
|
23
|
+
Replaces gsd-plan-phase's internal gsd-plan-checker with external AI reviewers (codex, claude, etc.). Plan-phase runs **inline** (bare Skill at depth 0) so it can spawn gsd-planner/gsd-plan-checker at depth 1. Review runs inside an isolated Agent (gsd-review is a Bash leaf — no sub-agents needed). Orchestrator only does loop control.
|
|
24
24
|
|
|
25
25
|
**Orchestrator role:** Parse arguments, validate phase, run plan-phase inline (Skill at depth 0), spawn an Agent for gsd-review, check unresolved HIGH and actionable non-HIGH counts, stall detection, escalation gate.
|
|
26
26
|
</objective>
|
|
@@ -41,8 +41,7 @@ Phase number: extracted from $ARGUMENTS (required)
|
|
|
41
41
|
|
|
42
42
|
**Flags:**
|
|
43
43
|
- `--codex` — Use Codex CLI as reviewer (default if no reviewer flag given AND `review.default_reviewers` is unset; otherwise `review.default_reviewers` wins per ADR-0011 — #2315)
|
|
44
|
-
- `--
|
|
45
|
-
- `--agy` / `--antigravity` — Use Antigravity CLI as reviewer (successor to the discontinued Gemini CLI)
|
|
44
|
+
- `--agy` / `--antigravity` — Use Antigravity CLI as reviewer
|
|
46
45
|
- `--claude` — Use Claude CLI as reviewer (separate session)
|
|
47
46
|
- `--coderabbit` — Use CodeRabbit as reviewer (reviews the working-tree diff, not the source tree)
|
|
48
47
|
- `--opencode` — Use OpenCode as reviewer
|
|
@@ -56,7 +55,8 @@ Phase number: extracted from $ARGUMENTS (required)
|
|
|
56
55
|
- `--max-cycles N` — Maximum replan→review cycles (default: 3)
|
|
57
56
|
|
|
58
57
|
**Feature gate:** This command requires `workflow.plan_review_convergence=true`. Enable with:
|
|
59
|
-
`gsd config-set workflow.plan_review_convergence true`
|
|
58
|
+
`gsd config-set workflow.plan_review_convergence true`. A dispatch carrying `--override-gate` —
|
|
59
|
+
how `/gsd-autonomous --converge` invokes this workflow (#4600) — bypasses the gate for that run.
|
|
60
60
|
</context>
|
|
61
61
|
|
|
62
62
|
<process>
|
|
@@ -24,7 +24,7 @@ Three modes:
|
|
|
24
24
|
<flags>
|
|
25
25
|
- **--next**: Detect current project state and automatically invoke the next logical GSD workflow step. Scans all prior phases for incomplete work before routing. `--next --force` bypasses safety gates.
|
|
26
26
|
- **--next --auto**: Like `--next`, but after the determined step completes, automatically re-invokes `/gsd-progress --next --auto` to continue chaining steps until completion or a blocking decision. Enables hands-free plan→execute→verify→complete progression.
|
|
27
|
-
- **--next --converge**: When the next action is planning (Route 3), route it through the plan-review **convergence** loop instead of the standard planner. Requires `workflow.plan_review_convergence=true` (enable with `gsd config-set workflow.plan_review_convergence true`). `--cross-ai` is an alias. Reviewer flags (`--codex`, `--
|
|
27
|
+
- **--next --converge**: When the next action is planning (Route 3), route it through the plan-review **convergence** loop instead of the standard planner. Requires `workflow.plan_review_convergence=true` (enable with `gsd config-set workflow.plan_review_convergence true`). `--cross-ai` is an alias. Reviewer flags (`--codex`, `--claude`, `--opencode`, `--ollama`, `--lm-studio`, `--llama-cpp`, `--all`) and `--max-cycles N` are forwarded to the convergence loop.
|
|
28
28
|
- **--do "..."**: Smart dispatcher — match freeform intent to the best GSD command using routing rules, confirm the match, then hand off.
|
|
29
29
|
- **--forensic**: Run 6-check integrity audit after the standard progress report.
|
|
30
30
|
- **(no flag)**: Standard progress check + intelligent routing (Routes A through F).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsd-quick-batch
|
|
3
|
-
description: "Batch several
|
|
3
|
+
description: "Batch several `/gsd-quick`-shaped tasks together — planned, dispatched, and merged as one run"
|
|
4
4
|
argument-hint: "[--file <path>] [--jobs auto|N] [--validate] [--research] [--resume <batch-id>] [task list]"
|
|
5
5
|
allowed-tools:
|
|
6
6
|
- Read
|