@opengsd/gsd-core 1.17.0 → 1.18.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/agents/gsd-advisor-researcher.compact.md +1 -1
- package/agents/gsd-advisor-researcher.md +1 -1
- package/agents/gsd-assumptions-analyzer.compact.md +1 -1
- package/agents/gsd-assumptions-analyzer.md +1 -1
- package/agents/gsd-code-fixer.compact.md +1 -1
- package/agents/gsd-code-fixer.md +1 -1
- package/agents/gsd-code-reviewer.compact.md +1 -1
- package/agents/gsd-code-reviewer.md +1 -1
- package/agents/gsd-codebase-mapper.compact.md +1 -1
- package/agents/gsd-codebase-mapper.md +1 -1
- package/agents/gsd-debugger.md +1 -1
- package/agents/gsd-doc-verifier.compact.md +4 -4
- package/agents/gsd-doc-verifier.md +4 -3
- package/agents/gsd-doc-writer.compact.md +23 -5
- package/agents/gsd-doc-writer.md +19 -6
- package/agents/gsd-eval-auditor.compact.md +1 -1
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-executor.md +7 -3
- package/agents/gsd-integration-checker.compact.md +1 -1
- package/agents/gsd-integration-checker.md +1 -1
- package/agents/gsd-nyquist-auditor.compact.md +1 -1
- package/agents/gsd-nyquist-auditor.md +1 -1
- package/agents/gsd-phase-researcher.md +1 -1
- package/agents/gsd-plan-checker.md +2 -1
- package/agents/gsd-planner.md +5 -4
- package/agents/gsd-project-researcher.compact.md +1 -1
- package/agents/gsd-project-researcher.md +1 -1
- package/agents/gsd-research-synthesizer.compact.md +5 -5
- package/agents/gsd-research-synthesizer.md +5 -5
- package/agents/gsd-roadmapper.compact.md +1 -1
- package/agents/gsd-roadmapper.md +1 -1
- package/agents/gsd-security-auditor.compact.md +1 -1
- package/agents/gsd-security-auditor.md +1 -1
- package/agents/gsd-ui-auditor.compact.md +1 -1
- package/agents/gsd-ui-auditor.md +1 -1
- package/agents/gsd-ui-checker.compact.md +1 -1
- package/agents/gsd-ui-checker.md +1 -1
- package/agents/gsd-ui-researcher.compact.md +13 -1
- package/agents/gsd-ui-researcher.md +28 -1
- package/agents/gsd-verifier.md +1 -1
- package/bin/install.js +38 -2
- package/commands/gsd/code-review.md +8 -0
- package/commands/gsd/pause-work.md +1 -1
- package/gsd-core/bin/gsd-tools.cjs +18 -11
- package/gsd-core/bin/lib/capability-ledger.cjs +25 -0
- package/gsd-core/bin/lib/capability-lock.cjs +29 -7
- package/gsd-core/bin/lib/capability-registry.cjs +70 -64
- package/gsd-core/bin/lib/capability-source.cjs +3 -1
- package/gsd-core/bin/lib/capability-state.cjs +6 -3
- package/gsd-core/bin/lib/capability-validator.cjs +6 -4
- package/gsd-core/bin/lib/commands.cjs +5 -1
- package/gsd-core/bin/lib/config-loader.cjs +3 -3
- package/gsd-core/bin/lib/decision-coverage-support.cjs +19 -0
- package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +15 -0
- package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +13 -0
- package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +23 -3
- package/gsd-core/bin/lib/gate-predicate.cjs +8 -12
- package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +60 -5
- package/gsd-core/bin/lib/init.cjs +11 -4
- package/gsd-core/bin/lib/install-effort-resolver.cjs +2 -2
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +4 -3
- package/gsd-core/bin/lib/install-profiles.cjs +5 -3
- package/gsd-core/bin/lib/phase.cjs +120 -11
- package/gsd-core/bin/lib/report-parser.cjs +57 -1
- package/gsd-core/bin/lib/review-lane-invocation.cjs +40 -0
- package/gsd-core/bin/lib/review-reviewer-selection.cjs +20 -1
- package/gsd-core/bin/lib/roadmap.cjs +56 -5
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +47 -2
- package/gsd-core/bin/lib/runtime-homes.cjs +18 -0
- package/gsd-core/bin/lib/shell-command-projection.cjs +2 -0
- package/gsd-core/bin/lib/smart-entry.cjs +24 -16
- package/gsd-core/bin/lib/state-document.cjs +37 -3
- package/gsd-core/bin/lib/state-transition.cjs +31 -10
- package/gsd-core/bin/lib/state.cjs +90 -60
- package/gsd-core/bin/lib/task-command-router.cjs +2 -3
- package/gsd-core/bin/lib/tdd-red-evidence.cjs +5 -0
- package/gsd-core/bin/lib/tdd-test-files.cjs +42 -0
- package/gsd-core/bin/lib/verify.cjs +36 -1
- package/gsd-core/references/agent-contracts.md +1 -1
- package/gsd-core/references/agent-skills-bootstrap.md +26 -7
- package/gsd-core/references/git-integration.md +3 -3
- package/gsd-core/references/planner-reversibility.md +18 -4
- package/gsd-core/references/planner-verify-command-grounding.md +18 -0
- package/gsd-core/references/tdd.md +4 -3
- package/gsd-core/references/verifier-phase-gates.md +8 -1
- package/gsd-core/workflows/add-backlog.md +10 -2
- package/gsd-core/workflows/add-phase.md +5 -1
- package/gsd-core/workflows/add-tests.md +5 -1
- package/gsd-core/workflows/add-todo.md +5 -1
- package/gsd-core/workflows/ai-integration-phase.md +5 -1
- package/gsd-core/workflows/audit-milestone.md +21 -9
- package/gsd-core/workflows/autonomous/templates/minimal-context.md +41 -0
- package/gsd-core/workflows/autonomous.md +52 -64
- package/gsd-core/workflows/check-todos.md +5 -1
- package/gsd-core/workflows/code-review-fix.md +5 -1
- package/gsd-core/workflows/code-review.md +5 -1
- package/gsd-core/workflows/complete-milestone/detail/elaboration.md +5 -1
- package/gsd-core/workflows/complete-milestone.md +25 -5
- package/gsd-core/workflows/debug.md +5 -1
- package/gsd-core/workflows/diagnose-issues.md +5 -1
- package/gsd-core/workflows/discuss-phase/modes/chain.md +5 -1
- package/gsd-core/workflows/discuss-phase-assumptions.md +11 -3
- package/gsd-core/workflows/discuss-phase.md +5 -1
- package/gsd-core/workflows/docs-update/detail/elaboration.md +7 -6
- package/gsd-core/workflows/docs-update.md +27 -5
- package/gsd-core/workflows/edit-phase.md +5 -1
- package/gsd-core/workflows/eval-review.md +11 -3
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +5 -1
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +12 -6
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +19 -2
- package/gsd-core/workflows/execute-phase/steps/regression-gate.md +18 -1
- package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +5 -1
- package/gsd-core/workflows/execute-phase.md +37 -6
- package/gsd-core/workflows/execute-plan.md +8 -4
- package/gsd-core/workflows/extract-learnings.md +6 -2
- package/gsd-core/workflows/forensics.md +5 -1
- package/gsd-core/workflows/import.md +5 -1
- package/gsd-core/workflows/insert-phase.md +5 -1
- package/gsd-core/workflows/manager.md +10 -2
- package/gsd-core/workflows/map-codebase.md +5 -1
- package/gsd-core/workflows/milestone-summary.md +10 -2
- package/gsd-core/workflows/new-milestone.md +13 -5
- package/gsd-core/workflows/new-project.md +9 -5
- package/gsd-core/workflows/next.md +8 -4
- package/gsd-core/workflows/pause-work.md +3 -3
- package/gsd-core/workflows/plan-phase/steps/auto-advance-check.md +70 -0
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +5 -1
- package/gsd-core/workflows/plan-phase/steps/closed-phase-gate.md +6 -2
- package/gsd-core/workflows/plan-phase.md +41 -73
- package/gsd-core/workflows/plan-review-convergence.md +17 -5
- package/gsd-core/workflows/plant-seed.md +8 -4
- package/gsd-core/workflows/progress.md +6 -2
- package/gsd-core/workflows/quick-batch.md +5 -1
- package/gsd-core/workflows/quick.md +22 -7
- package/gsd-core/workflows/remove-phase.md +5 -1
- package/gsd-core/workflows/resume-project.md +5 -1
- package/gsd-core/workflows/review.md +6 -2
- package/gsd-core/workflows/scan.md +5 -1
- package/gsd-core/workflows/secure-phase.md +6 -2
- package/gsd-core/workflows/settings.md +3 -3
- package/gsd-core/workflows/ship.md +13 -10
- package/gsd-core/workflows/thread.md +10 -2
- package/gsd-core/workflows/transition.md +5 -1
- package/gsd-core/workflows/ui-phase.md +5 -1
- package/gsd-core/workflows/ui-review.md +6 -2
- package/gsd-core/workflows/ultraplan-phase.md +5 -1
- package/gsd-core/workflows/update.md +5 -1
- package/gsd-core/workflows/validate-phase.md +6 -2
- package/gsd-core/workflows/verify-work/detail/elaboration.md +1 -1
- package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +5 -1
- package/gsd-core/workflows/verify-work.md +11 -3
- package/hooks/dist/gsd-agent-isolation-guard.js +3 -1
- package/hooks/dist/gsd-cursor-subagent-start.js +2 -1
- package/hooks/dist/gsd-secret-read-guard.js +72 -14
- package/hooks/dist/gsd-validate-commit.sh +27 -5
- package/hooks/gsd-agent-isolation-guard.js +3 -1
- package/hooks/gsd-cursor-subagent-start.js +2 -1
- package/hooks/gsd-secret-read-guard.js +72 -14
- package/hooks/gsd-validate-commit.sh +27 -5
- package/package.json +1 -1
- package/scripts/audit-workflow-script-paths.cjs +1 -1
- package/scripts/diagnose-validate-commit-in-tier.cjs +270 -0
- package/scripts/diagnose-validate-commit-phases.cjs +348 -0
- package/scripts/diagnose-windows-spawn-watcher.cjs +317 -0
- package/scripts/docs-guard-registry.cjs +2 -0
- package/scripts/lib/macos-conformance-tier.generated.cjs +9 -0
- package/scripts/lib/platform-conformance-tier.generated.cjs +16 -0
- package/scripts/lint-phase-arg-assignment.cjs +2 -2
- package/scripts/lint-workflow-shellcheck-baseline.json +16 -16
- package/scripts/release-tarball-smoke.cjs +1 -0
- package/scripts/xtrace-phase-timing.cjs +205 -0
- package/skills/gsd-code-review/SKILL.md +8 -0
- package/skills/gsd-pause-work/SKILL.md +1 -1
- package/vscode/package.json +1 -1
|
@@ -46,6 +46,7 @@ module.exports = {
|
|
|
46
46
|
"tests/codex-config-hooks.test.cjs",
|
|
47
47
|
"tests/codex-config-install.test.cjs",
|
|
48
48
|
"tests/codex-config.test.cjs",
|
|
49
|
+
"tests/command-arguments-block.test.cjs",
|
|
49
50
|
"tests/commands.platform.test.cjs",
|
|
50
51
|
"tests/commit-docs-bypass.test.cjs",
|
|
51
52
|
"tests/commit-files-deletion.test.cjs",
|
|
@@ -71,6 +72,7 @@ module.exports = {
|
|
|
71
72
|
"tests/execute-phase-decimal-arithmetic.test.cjs",
|
|
72
73
|
"tests/executed-plan.test.cjs",
|
|
73
74
|
"tests/executor-mvp-tdd-section.test.cjs",
|
|
75
|
+
"tests/executor-sequential-linked-worktree.test.cjs",
|
|
74
76
|
"tests/external-job.test.cjs",
|
|
75
77
|
"tests/failing-direction.test.cjs",
|
|
76
78
|
"tests/fallow-runner.test.cjs",
|
|
@@ -80,6 +82,7 @@ module.exports = {
|
|
|
80
82
|
"tests/gap-checker.property.test.cjs",
|
|
81
83
|
"tests/gate-api-coverage-verify-pre-escape.test.cjs",
|
|
82
84
|
"tests/gate-codebase-drift.unit.test.cjs",
|
|
85
|
+
"tests/gate-predicate.unit.test.cjs",
|
|
83
86
|
"tests/gate-tdd-red-evidence-containment.test.cjs",
|
|
84
87
|
"tests/gate-ui-plan.unit.test.cjs",
|
|
85
88
|
"tests/gate-verify-command-paths.unit.test.cjs",
|
|
@@ -104,6 +107,7 @@ module.exports = {
|
|
|
104
107
|
"tests/hooks-crash-policy.test.cjs",
|
|
105
108
|
"tests/hooks-opt-in.test.cjs",
|
|
106
109
|
"tests/host-integration.test.cjs",
|
|
110
|
+
"tests/in-tier-commit-hook-timing.test.cjs",
|
|
107
111
|
"tests/init-manager.test.cjs",
|
|
108
112
|
"tests/install-minimal-hooks.test.cjs",
|
|
109
113
|
"tests/install-path-detection.test.cjs",
|
|
@@ -159,6 +163,7 @@ module.exports = {
|
|
|
159
163
|
"tests/phase-status.test.cjs",
|
|
160
164
|
"tests/phase.platform.test.cjs",
|
|
161
165
|
"tests/phase.test.cjs",
|
|
166
|
+
"tests/plan-authoring-verification-gaps.test.cjs",
|
|
162
167
|
"tests/plan-count-single-owner.test.cjs",
|
|
163
168
|
"tests/plan-document.test.cjs",
|
|
164
169
|
"tests/plan-phase-stall-detection.test.cjs",
|
|
@@ -181,6 +186,7 @@ module.exports = {
|
|
|
181
186
|
"tests/quick-batch-command-router.stdin.test.cjs",
|
|
182
187
|
"tests/quick-batch.test.cjs",
|
|
183
188
|
"tests/quick-branching.test.cjs",
|
|
189
|
+
"tests/quick-commit-boundary.test.cjs",
|
|
184
190
|
"tests/quick-research.test.cjs",
|
|
185
191
|
"tests/reapply-verify-hunks.test.cjs",
|
|
186
192
|
"tests/refactor-1390-t3-characterization.test.cjs",
|
|
@@ -188,6 +194,7 @@ module.exports = {
|
|
|
188
194
|
"tests/response-language-coverage.test.cjs",
|
|
189
195
|
"tests/retired-artifact-cleanup.test.cjs",
|
|
190
196
|
"tests/review-build-prompt-optional-sections.test.cjs",
|
|
197
|
+
"tests/review-lane-invocation.test.cjs",
|
|
191
198
|
"tests/review-lane-runner.test.cjs",
|
|
192
199
|
"tests/review-lane-windows-spawn-resolution.test.cjs",
|
|
193
200
|
"tests/review-parallel-lanes.test.cjs",
|
|
@@ -211,11 +218,13 @@ module.exports = {
|
|
|
211
218
|
"tests/shared-hooks-dir-resolution.test.cjs",
|
|
212
219
|
"tests/shell-command-projection-dispatch.test.cjs",
|
|
213
220
|
"tests/shipped-reference-cites.test.cjs",
|
|
221
|
+
"tests/skill-manifest.test.cjs",
|
|
214
222
|
"tests/spawn-liveness-banner.test.cjs",
|
|
215
223
|
"tests/state-document.test.cjs",
|
|
216
224
|
"tests/state-transition.test.cjs",
|
|
217
225
|
"tests/state.platform.test.cjs",
|
|
218
226
|
"tests/state.test.cjs",
|
|
227
|
+
"tests/tdd-mode.platform.test.cjs",
|
|
219
228
|
"tests/todos-workstream-scope.test.cjs",
|
|
220
229
|
"tests/tracer-bullet.test.cjs",
|
|
221
230
|
"tests/uat-complete-session.test.cjs",
|
|
@@ -24,6 +24,7 @@ module.exports = {
|
|
|
24
24
|
"tests/capability-ledger.test.cjs",
|
|
25
25
|
"tests/capability-lifecycle.test.cjs",
|
|
26
26
|
"tests/capability-loader.test.cjs",
|
|
27
|
+
"tests/capability-lock-lazy-self-probe-5327.test.cjs",
|
|
27
28
|
"tests/capability-lock-mkdir-failure-3987.test.cjs",
|
|
28
29
|
"tests/capability-probe-fallback.test.cjs",
|
|
29
30
|
"tests/capability-source.test.cjs",
|
|
@@ -59,6 +60,7 @@ module.exports = {
|
|
|
59
60
|
"tests/codex-config.test.cjs",
|
|
60
61
|
"tests/codex-inherit-smoke.test.cjs",
|
|
61
62
|
"tests/codex-windows-shim-node-resolution.test.cjs",
|
|
63
|
+
"tests/command-arguments-block.test.cjs",
|
|
62
64
|
"tests/command-routing-hub.test.cjs",
|
|
63
65
|
"tests/commands.platform.test.cjs",
|
|
64
66
|
"tests/commit-files-deletion.test.cjs",
|
|
@@ -81,6 +83,8 @@ module.exports = {
|
|
|
81
83
|
"tests/cursor-hooks.test.cjs",
|
|
82
84
|
"tests/cursor-subagent-isolation.test.cjs",
|
|
83
85
|
"tests/debug-session-management.test.cjs",
|
|
86
|
+
"tests/defaults-json-fallback.test.cjs",
|
|
87
|
+
"tests/diagnose-windows-spawn-watcher.test.cjs",
|
|
84
88
|
"tests/dispatch-identity.test.cjs",
|
|
85
89
|
"tests/dispatcher.test.cjs",
|
|
86
90
|
"tests/drift-detection.test.cjs",
|
|
@@ -93,12 +97,14 @@ module.exports = {
|
|
|
93
97
|
"tests/emitted-provenance.test.cjs",
|
|
94
98
|
"tests/ensure-runtime-build.test.cjs",
|
|
95
99
|
"tests/eslint-rules.test.cjs",
|
|
100
|
+
"tests/execute-phase-cross-block-state.test.cjs",
|
|
96
101
|
"tests/execute-phase-decimal-arithmetic.test.cjs",
|
|
97
102
|
"tests/execute-phase-worktree-guard.test.cjs",
|
|
98
103
|
"tests/execute-plan-update-codebase-map-diff-base.test.cjs",
|
|
99
104
|
"tests/execute-wave-post-gate-pipeline-e2e.test.cjs",
|
|
100
105
|
"tests/executed-plan.test.cjs",
|
|
101
106
|
"tests/executor-mvp-tdd-section.test.cjs",
|
|
107
|
+
"tests/executor-sequential-linked-worktree.test.cjs",
|
|
102
108
|
"tests/external-descriptor-confinement.test.cjs",
|
|
103
109
|
"tests/failing-direction.test.cjs",
|
|
104
110
|
"tests/fallow-runner.test.cjs",
|
|
@@ -111,6 +117,7 @@ module.exports = {
|
|
|
111
117
|
"tests/gate-consumer-exit-awareness.test.cjs",
|
|
112
118
|
"tests/gate-decision-coverage-verify-stderr.test.cjs",
|
|
113
119
|
"tests/gate-exit.test.cjs",
|
|
120
|
+
"tests/gate-predicate.unit.test.cjs",
|
|
114
121
|
"tests/gate-tdd-red-evidence-containment.test.cjs",
|
|
115
122
|
"tests/gate-tdd-review-checkpoint-hardening.test.cjs",
|
|
116
123
|
"tests/gate-tdd-review-checkpoint.unit.test.cjs",
|
|
@@ -145,6 +152,8 @@ module.exports = {
|
|
|
145
152
|
"tests/hooks-crash-policy.test.cjs",
|
|
146
153
|
"tests/hooks-opt-in.test.cjs",
|
|
147
154
|
"tests/host-integration.test.cjs",
|
|
155
|
+
"tests/in-tier-msys-fork-stress.test.cjs",
|
|
156
|
+
"tests/in-tier-sh-pipeline-timing.test.cjs",
|
|
148
157
|
"tests/init-manager.test.cjs",
|
|
149
158
|
"tests/install-minimal-hooks.test.cjs",
|
|
150
159
|
"tests/install-nested-layout.test.cjs",
|
|
@@ -180,6 +189,7 @@ module.exports = {
|
|
|
180
189
|
"tests/mcp-catalog.test.cjs",
|
|
181
190
|
"tests/milestone-archive.test.cjs",
|
|
182
191
|
"tests/milestone-window-single-owner.test.cjs",
|
|
192
|
+
"tests/milestone.test.cjs",
|
|
183
193
|
"tests/model-resolver.test.cjs",
|
|
184
194
|
"tests/mutation-workflow-base-ref.test.cjs",
|
|
185
195
|
"tests/new-milestone-clear-phases.test.cjs",
|
|
@@ -245,6 +255,7 @@ module.exports = {
|
|
|
245
255
|
"tests/quick-batch-command-router.stdin.test.cjs",
|
|
246
256
|
"tests/quick-batch.test.cjs",
|
|
247
257
|
"tests/quick-branching.test.cjs",
|
|
258
|
+
"tests/quick-commit-boundary.test.cjs",
|
|
248
259
|
"tests/quick-research.test.cjs",
|
|
249
260
|
"tests/quick-review-scope-tip-bound.test.cjs",
|
|
250
261
|
"tests/read-guard.test.cjs",
|
|
@@ -258,6 +269,7 @@ module.exports = {
|
|
|
258
269
|
"tests/retired-artifact-cleanup.test.cjs",
|
|
259
270
|
"tests/review-build-prompt-optional-sections.test.cjs",
|
|
260
271
|
"tests/review-default-reviewers-config.test.cjs",
|
|
272
|
+
"tests/review-lane-invocation.test.cjs",
|
|
261
273
|
"tests/review-lane-runner.test.cjs",
|
|
262
274
|
"tests/review-lane-windows-spawn-resolution.test.cjs",
|
|
263
275
|
"tests/review-model-config.test.cjs",
|
|
@@ -293,6 +305,9 @@ module.exports = {
|
|
|
293
305
|
"tests/slug-derivation-drift-guard.test.cjs",
|
|
294
306
|
"tests/state-todos-render.test.cjs",
|
|
295
307
|
"tests/state.platform.test.cjs",
|
|
308
|
+
"tests/subject-first-line.platform.test.cjs",
|
|
309
|
+
"tests/tdd-mode.platform.test.cjs",
|
|
310
|
+
"tests/tdd-review-checkpoint-cross-plan.test.cjs",
|
|
296
311
|
"tests/teams-status.test.cjs",
|
|
297
312
|
"tests/test-gate-watch-mode.test.cjs",
|
|
298
313
|
"tests/todos-workstream-scope.test.cjs",
|
|
@@ -322,5 +337,6 @@ module.exports = {
|
|
|
322
337
|
"tests/worktree-cleanup.test.cjs",
|
|
323
338
|
"tests/worktree-safety.test.cjs",
|
|
324
339
|
"tests/worktree.test.cjs",
|
|
340
|
+
"tests/xtrace-phase-timing.platform.test.cjs",
|
|
325
341
|
],
|
|
326
342
|
};
|
|
@@ -93,10 +93,10 @@ const SHELL_INFO_STRINGS = new Set(['bash', 'sh', 'shell']);
|
|
|
93
93
|
const CANONICAL_FORMS = Object.freeze({
|
|
94
94
|
/** `/gsd:secure-phase 4` — the phase is the whole argument string, minus a `--ws <name>` pair. */
|
|
95
95
|
positional:
|
|
96
|
-
'PHASE_ARG=$(echo "$
|
|
96
|
+
'PHASE_ARG=$(echo "$GSD_ARGS" | sed -E \'s/--ws[[:space:]]+[A-Za-z0-9._-]+//g\' | xargs)',
|
|
97
97
|
/** `/gsd:review --phase 4 --codex` — the phase is the value of a named flag. */
|
|
98
98
|
phaseFlag:
|
|
99
|
-
'PHASE_ARG=$(echo "$
|
|
99
|
+
'PHASE_ARG=$(echo "$GSD_ARGS" | sed -nE \'s/.*--phase[[:space:]]+([A-Za-z0-9._-]+).*/\\1/p\')',
|
|
100
100
|
/** Skill dispatch passes the phase as `$1` (`Skill(skill="gsd-code-review", args="4")`). */
|
|
101
101
|
firstPositional: 'PHASE_ARG="${1}"',
|
|
102
102
|
});
|
|
@@ -384,6 +384,21 @@
|
|
|
384
384
|
"code": "2086",
|
|
385
385
|
"message": "Double quote to prevent globbing and word splitting."
|
|
386
386
|
},
|
|
387
|
+
{
|
|
388
|
+
"file": "gsd-core/workflows/execute-phase/steps/code-review-disposition.md",
|
|
389
|
+
"code": "2317",
|
|
390
|
+
"message": "Command appears to be unreachable. Check usage (or ignore if invoked indirectly)."
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
"file": "gsd-core/workflows/execute-phase/steps/code-review-disposition.md",
|
|
394
|
+
"code": "2317",
|
|
395
|
+
"message": "Command appears to be unreachable. Check usage (or ignore if invoked indirectly)."
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
"file": "gsd-core/workflows/execute-phase/steps/code-review-disposition.md",
|
|
399
|
+
"code": "2317",
|
|
400
|
+
"message": "Command appears to be unreachable. Check usage (or ignore if invoked indirectly)."
|
|
401
|
+
},
|
|
387
402
|
{
|
|
388
403
|
"file": "gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md",
|
|
389
404
|
"code": "2016",
|
|
@@ -690,7 +705,7 @@
|
|
|
690
705
|
"message": "Double quote to prevent globbing and word splitting."
|
|
691
706
|
},
|
|
692
707
|
{
|
|
693
|
-
"file": "gsd-core/workflows/plan-phase.md",
|
|
708
|
+
"file": "gsd-core/workflows/plan-phase/steps/auto-advance-check.md",
|
|
694
709
|
"code": "2235",
|
|
695
710
|
"message": "Use { ..; } instead of (..) to avoid subshell overhead."
|
|
696
711
|
},
|
|
@@ -1108,20 +1123,5 @@
|
|
|
1108
1123
|
"file": "gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",
|
|
1109
1124
|
"code": "2086",
|
|
1110
1125
|
"message": "Double quote to prevent globbing and word splitting."
|
|
1111
|
-
},
|
|
1112
|
-
{
|
|
1113
|
-
"file": "gsd-core/workflows/execute-phase/steps/code-review-disposition.md",
|
|
1114
|
-
"code": "2317",
|
|
1115
|
-
"message": "Command appears to be unreachable. Check usage (or ignore if invoked indirectly)."
|
|
1116
|
-
},
|
|
1117
|
-
{
|
|
1118
|
-
"file": "gsd-core/workflows/execute-phase/steps/code-review-disposition.md",
|
|
1119
|
-
"code": "2317",
|
|
1120
|
-
"message": "Command appears to be unreachable. Check usage (or ignore if invoked indirectly)."
|
|
1121
|
-
},
|
|
1122
|
-
{
|
|
1123
|
-
"file": "gsd-core/workflows/execute-phase/steps/code-review-disposition.md",
|
|
1124
|
-
"code": "2317",
|
|
1125
|
-
"message": "Command appears to be unreachable. Check usage (or ignore if invoked indirectly)."
|
|
1126
1126
|
}
|
|
1127
1127
|
]
|
|
@@ -703,6 +703,7 @@ function runSmoke({
|
|
|
703
703
|
...effectiveNpmEnv,
|
|
704
704
|
HOME: runtimeHome,
|
|
705
705
|
USERPROFILE: runtimeHome,
|
|
706
|
+
GSD_HOME: runtimeHome, // #5017: the defaults store root follows HOME
|
|
706
707
|
// Same reason as the init check above: install.js skips its main()
|
|
707
708
|
// block when GSD_TEST_MODE is set and would exit 0 writing nothing.
|
|
708
709
|
GSD_TEST_MODE: '',
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Per-line cost attribution for a `bash -x` trace whose PS4 stamps every
|
|
5
|
+
* traced command with a millisecond timestamp, its line number and enclosing
|
|
6
|
+
* function (#5473).
|
|
7
|
+
*
|
|
8
|
+
* The stamp is `<depth marks>@@<nonce>@@<epoch-ms>@@<lineno>@@<function>@@ `, so
|
|
9
|
+
* one trace line looks like `++@@k3f9@@1760615775123@@271@@@@ MSG_SUFFIX=...`.
|
|
10
|
+
* The nonce is a per-run random token: a traced value that merely LOOKS like a
|
|
11
|
+
* stamp (hostile or accidental) cannot forge one without knowing it.
|
|
12
|
+
*
|
|
13
|
+
* WHAT A GAP MEANS. bash prints a trace line (and so evaluates PS4) AFTER it
|
|
14
|
+
* has expanded the command's words and BEFORE it runs the command. The gap
|
|
15
|
+
* between stamp i and stamp i+1 is therefore
|
|
16
|
+
*
|
|
17
|
+
* execution of command i + expansion of command i+1
|
|
18
|
+
*
|
|
19
|
+
* which cannot be split from the trace alone. Both attributions are reported:
|
|
20
|
+
* `afterMs` (the gap that FOLLOWS the line) is large for a line that EXECUTES
|
|
21
|
+
* slowly (an external command, a `$(...)` already expanded); `beforeMs` (the
|
|
22
|
+
* gap that PRECEDES it) is large for a line whose EXPANSION is slow (a
|
|
23
|
+
* `${var//pat/x}` or `${var:off}` over a 112KB value, whose result is only
|
|
24
|
+
* printed once it is computed). Neither alone is "the cost of the line".
|
|
25
|
+
*
|
|
26
|
+
* Every traced command also pays one stamp (a subshell and a perl); measure it
|
|
27
|
+
* with a run of no-ops (see the CLI) and read gaps below it as zero.
|
|
28
|
+
*
|
|
29
|
+
* No I/O and no clock: every function returns a value computed from its
|
|
30
|
+
* arguments. The CLI that runs bash is scripts/diagnose-validate-commit-phases.cjs.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/** PS4 to hand to `bash -x`; `timestampCommand` prints the epoch milliseconds. */
|
|
34
|
+
function stampPs4(timestampCommand, nonce) {
|
|
35
|
+
return `+@@${nonce}@@$(${timestampCommand})@@\${LINENO}@@\${FUNCNAME:-}@@ `;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* How the stamp reaches bash. Every other route failed somewhere:
|
|
40
|
+
* - an exported PS4: bash 5.x does not run the command substitution in a PS4
|
|
41
|
+
* it imported from the environment, so it silently degrades to `+ `;
|
|
42
|
+
* - BASH_ENV: bash reads the system bashrc INSTEAD of it in some
|
|
43
|
+
* environments (it did in the gsd-test tester container);
|
|
44
|
+
* - `bash -c '... . "$0"'`: puts an uncontrolled path inside a shell command.
|
|
45
|
+
* So the script under test is run as an ordinary script that has ONE line
|
|
46
|
+
* inserted after its shebang, which assigns PS4 (read from a sibling file, so
|
|
47
|
+
* the stamp text is never quoted into shell code) and turns on xtrace. `$0`,
|
|
48
|
+
* `exit` and sibling files then behave exactly as in a direct run (the CLI's
|
|
49
|
+
* tests pin this against the real hook).
|
|
50
|
+
*/
|
|
51
|
+
const TRACE_PS4_FILE = 'xtrace-ps4.txt';
|
|
52
|
+
const INJECTED_LINES = 1;
|
|
53
|
+
const INJECTED_LINE = `PS4="$(cat "\${0%/*}/${TRACE_PS4_FILE}")"; set -x`;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* `scriptText` with the tracing line inserted after its shebang (or at the top
|
|
57
|
+
* when it has none). The script must be run by a path containing a `/`, with
|
|
58
|
+
* the PS4 text in TRACE_PS4_FILE beside it. Adds exactly INJECTED_LINES lines.
|
|
59
|
+
*/
|
|
60
|
+
function injectTracing(scriptText) {
|
|
61
|
+
const text = String(scriptText);
|
|
62
|
+
if (!text.startsWith('#!')) return `${INJECTED_LINE}\n${text}`;
|
|
63
|
+
const eol = text.indexOf('\n');
|
|
64
|
+
if (eol === -1) return `${text}\n${INJECTED_LINE}\n`;
|
|
65
|
+
return `${text.slice(0, eol + 1)}${INJECTED_LINE}\n${text.slice(eol + 1)}`;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// What follows the depth marks and the nonce: `<epoch-ms>@@<lineno>@@<function>@@ `.
|
|
69
|
+
const STAMP_TAIL = /^(\d+)@@(\d+)@@([^@]*)@@ ?/;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Parse a stamped trace. Lines with no stamp are continuations of the
|
|
73
|
+
* previous command (a traced value that itself contains newlines) and are
|
|
74
|
+
* folded into it; text before the first stamp is ignored.
|
|
75
|
+
*
|
|
76
|
+
* @param {string} text
|
|
77
|
+
* @param {string} nonce the nonce given to stampPs4
|
|
78
|
+
* @returns {{ t: number, line: number, depth: number, fn: string, cmd: string }[]}
|
|
79
|
+
*/
|
|
80
|
+
function parseTimedXtrace(text, nonce) {
|
|
81
|
+
// The nonce is matched as a literal prefix, never compiled into a pattern.
|
|
82
|
+
const head = `@@${nonce}@@`;
|
|
83
|
+
const entries = [];
|
|
84
|
+
const lines = String(text).split('\n');
|
|
85
|
+
// A stream ends with the newline of its last line; that is a terminator, not
|
|
86
|
+
// an empty continuation of the last command.
|
|
87
|
+
if (lines.length > 0 && lines[lines.length - 1] === '') lines.pop();
|
|
88
|
+
for (const raw of lines) {
|
|
89
|
+
let depth = 0;
|
|
90
|
+
while (raw[depth] === '+') depth++;
|
|
91
|
+
const tail = depth > 0 && raw.startsWith(head, depth)
|
|
92
|
+
? STAMP_TAIL.exec(raw.slice(depth + head.length))
|
|
93
|
+
: null;
|
|
94
|
+
if (tail) {
|
|
95
|
+
entries.push({
|
|
96
|
+
t: Number(tail[1]),
|
|
97
|
+
line: Number(tail[2]),
|
|
98
|
+
depth,
|
|
99
|
+
fn: tail[3],
|
|
100
|
+
cmd: raw.slice(depth + head.length + tail[0].length),
|
|
101
|
+
});
|
|
102
|
+
} else if (entries.length > 0) {
|
|
103
|
+
entries[entries.length - 1].cmd += `\n${raw}`;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return entries;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Entries with their line numbers moved back by `injected` lines, so a stamp
|
|
111
|
+
* reports the line of the ORIGINAL script, not of the instrumented copy.
|
|
112
|
+
*/
|
|
113
|
+
function shiftLines(entries, injected) {
|
|
114
|
+
return entries.map((e) => ({ ...e, line: e.line - injected }));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Attribute the gaps around each entry to its (function, line): `afterMs` is
|
|
119
|
+
* the gap to the NEXT stamp, `beforeMs` the gap from the PREVIOUS one (see the
|
|
120
|
+
* header for what each means). A clock that steps backwards counts as zero.
|
|
121
|
+
*
|
|
122
|
+
* @param {{ t: number, line: number, fn?: string, cmd: string }[]} entries
|
|
123
|
+
* @returns {{ costs: { fn: string, line: number, afterMs: number, beforeMs: number, maxMs: number, count: number, sample: string }[], totalMs: number }}
|
|
124
|
+
*/
|
|
125
|
+
function phaseCosts(entries) {
|
|
126
|
+
const byKey = new Map();
|
|
127
|
+
const last = entries.length - 1;
|
|
128
|
+
for (let i = 0; i <= last; i++) {
|
|
129
|
+
const after = i < last ? Math.max(0, entries[i + 1].t - entries[i].t) : 0;
|
|
130
|
+
const before = i > 0 ? Math.max(0, entries[i].t - entries[i - 1].t) : 0;
|
|
131
|
+
const e = entries[i];
|
|
132
|
+
const fn = e.fn || '';
|
|
133
|
+
const key = `${fn}\u0000${e.line}`;
|
|
134
|
+
const acc = byKey.get(key) || { fn, line: e.line, afterMs: 0, beforeMs: 0, maxMs: 0, count: 0, sample: '' };
|
|
135
|
+
acc.afterMs += after;
|
|
136
|
+
acc.beforeMs += before;
|
|
137
|
+
acc.count += 1;
|
|
138
|
+
const peak = Math.max(after, before);
|
|
139
|
+
if (peak >= acc.maxMs) {
|
|
140
|
+
acc.maxMs = peak;
|
|
141
|
+
acc.sample = e.cmd;
|
|
142
|
+
}
|
|
143
|
+
byKey.set(key, acc);
|
|
144
|
+
}
|
|
145
|
+
const totalMs = entries.length > 1 ? Math.max(0, entries[last].t - entries[0].t) : 0;
|
|
146
|
+
return { costs: [...byKey.values()], totalMs };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** A line's weight when ranking: the larger of its two attributions. */
|
|
150
|
+
const peakMs = (c) => Math.max(c.afterMs, c.beforeMs);
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* The `n` most expensive lines, costliest first; ties broken by function then
|
|
154
|
+
* line number so the order is deterministic.
|
|
155
|
+
*/
|
|
156
|
+
function slowestLines(costs, n) {
|
|
157
|
+
return [...costs]
|
|
158
|
+
.sort((a, b) => peakMs(b) - peakMs(a) || (a.fn < b.fn ? -1 : a.fn > b.fn ? 1 : 0) || a.line - b.line)
|
|
159
|
+
.slice(0, n);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Elapsed time per run of `size` source lines of the script's top level, in
|
|
164
|
+
* line order, plus one entry per function. `afterMs` summed over a region is
|
|
165
|
+
* the time from its first stamp to the next region's, so regions roughly
|
|
166
|
+
* partition the run: a coarse "which phase" view that needs no knowledge of
|
|
167
|
+
* the script.
|
|
168
|
+
*
|
|
169
|
+
* @returns {{ label: string, afterMs: number }[]}
|
|
170
|
+
*/
|
|
171
|
+
function rollupByRegion(costs, size) {
|
|
172
|
+
if (!Number.isInteger(size) || size < 1) throw new RangeError('region size must be a positive integer');
|
|
173
|
+
const regions = new Map();
|
|
174
|
+
for (const c of costs) {
|
|
175
|
+
const start = Math.floor((c.line - 1) / size) * size + 1;
|
|
176
|
+
const label = c.fn ? `in ${c.fn}()` : `lines ${start}-${start + size - 1}`;
|
|
177
|
+
const from = c.fn ? Number.MAX_SAFE_INTEGER : start; // functions sort after the top level
|
|
178
|
+
const acc = regions.get(label) || { label, from, afterMs: 0 };
|
|
179
|
+
acc.afterMs += c.afterMs;
|
|
180
|
+
regions.set(label, acc);
|
|
181
|
+
}
|
|
182
|
+
return [...regions.values()]
|
|
183
|
+
.sort((a, b) => a.from - b.from || (a.label < b.label ? -1 : a.label > b.label ? 1 : 0))
|
|
184
|
+
.map(({ label, afterMs }) => ({ label, afterMs }));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** One-line, length-bounded rendering of a traced command for a report. */
|
|
188
|
+
function abbreviate(cmd, max = 100) {
|
|
189
|
+
const flat = String(cmd).replace(/\s+/g, ' ').trim();
|
|
190
|
+
return flat.length <= max ? flat : `${flat.slice(0, max)}… (${flat.length} chars)`;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
module.exports = {
|
|
194
|
+
stampPs4,
|
|
195
|
+
TRACE_PS4_FILE,
|
|
196
|
+
INJECTED_LINES,
|
|
197
|
+
injectTracing,
|
|
198
|
+
parseTimedXtrace,
|
|
199
|
+
shiftLines,
|
|
200
|
+
phaseCosts,
|
|
201
|
+
peakMs,
|
|
202
|
+
slowestLines,
|
|
203
|
+
rollupByRegion,
|
|
204
|
+
abbreviate,
|
|
205
|
+
};
|
|
@@ -48,6 +48,14 @@ Optional flags parsed from the `<arguments>` block:
|
|
|
48
48
|
- `--files=file1,file2,...` — Explicit file list override. Has highest precedence for file scoping per D-08. When provided, workflow skips SUMMARY.md extraction and git diff fallback entirely.
|
|
49
49
|
|
|
50
50
|
Context files (CLAUDE.md, SUMMARY.md, phase state) are resolved inside the workflow via `gsd-tools query init.phase-op` and delegated to agent via `<required_reading>` blocks.
|
|
51
|
+
|
|
52
|
+
## Outside a phase
|
|
53
|
+
|
|
54
|
+
Reviewer lanes run without a phase (`gsd_run` is defined by the runtime-launcher preamble inside workflow fences; in a plain shell call `node <install>/gsd-core/bin/gsd-tools.cjs` instead): pipe canonical repo-relative file paths (one per line) to stdin of
|
|
55
|
+
`gsd_run review-lane dispatch-step --repo-root <root> --depth <quick|standard|deep> --base-sha <sha> --run-dir "$(mktemp -d)" --cap-id code-review --point execute:post --explicit <slugs> --raw`.
|
|
56
|
+
`review-lane` flags are space-separated (`--depth quick`), never `--flag=value`. `--explicit` (omitted, nothing dispatches yet the call exits ok), `--depth`, `--base-sha` (lane reviews changes relative to it; commit them first) and stdin paths are required; `--run-dir` should be a fresh temp dir (default `.` writes the prompt file into the current directory); read each lane's output path (`results[].reviewPath`) from the JSON before removing it. `--cap-id`/`--point` select the `code-review` capability, which must be enabled (`workflow.code_review`) and active at `--point` — `execute:post`, or `execute:wave:post` when `workflow.code_review_point` selects it; otherwise nothing dispatches.
|
|
57
|
+
`--explicit` takes comma-separated canonical slugs, no spaces (`codex,antigravity`), not flag aliases (`antigravity`, not `agy`); slugs: first column of `gsd_run review-lane sections` (`review-lane flags` lists flags/aliases).
|
|
58
|
+
Each lane declares its own model key, which is not always its slug (antigravity's is `review.models.agy`); see the `review.models.*` table in `docs/CONFIGURATION.md`. Unset = lane default model.
|
|
51
59
|
</context>
|
|
52
60
|
|
|
53
61
|
<process>
|
|
@@ -21,7 +21,7 @@ Routes to the pause-work workflow which handles:
|
|
|
21
21
|
- Current phase detection from recent files
|
|
22
22
|
- Complete state gathering (position, completed work, remaining work, decisions, blockers)
|
|
23
23
|
- Handoff file creation with all context sections
|
|
24
|
-
- Git commit
|
|
24
|
+
- Git commit handoff
|
|
25
25
|
- Resume instructions
|
|
26
26
|
</objective>
|
|
27
27
|
|
package/vscode/package.json
CHANGED