@opengsd/gsd-core 1.11.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.opencode/plugins/gsd-core.js +12 -0
- package/agents/gsd-code-fixer.md +1 -1
- package/agents/gsd-debug-session-manager.md +1 -1
- package/agents/gsd-debugger.md +1 -1
- package/agents/gsd-dom-verifier.md +169 -0
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-executor.md +78 -42
- package/agents/gsd-framework-selector.md +1 -3
- package/agents/gsd-intel-updater.md +1 -1
- package/agents/gsd-mempalace-curator.md +0 -1
- package/agents/gsd-pattern-mapper.md +11 -0
- package/agents/gsd-phase-researcher.md +3 -1
- package/agents/gsd-plan-checker.md +91 -112
- package/agents/gsd-planner.md +20 -4
- package/agents/gsd-project-researcher.md +1 -1
- package/agents/gsd-research-synthesizer.md +2 -2
- package/agents/gsd-roadmapper.md +15 -11
- package/agents/gsd-ui-checker.md +82 -7
- package/agents/gsd-ui-researcher.md +70 -3
- package/agents/gsd-verifier.md +24 -2
- package/bin/install.js +847 -200
- package/commands/gsd/discuss-phase.md +1 -1
- package/commands/gsd/execute-phase.md +1 -1
- package/commands/gsd/import.md +1 -1
- package/commands/gsd/ns-workflow.md +2 -1
- package/commands/gsd/phase.md +1 -1
- package/commands/gsd/quick-batch.md +105 -0
- package/commands/gsd/quick.md +8 -4
- package/commands/gsd/surface.md +18 -8
- package/gsd-core/bin/gsd-tools.cjs +761 -100
- package/gsd-core/bin/lib/active-workstream-store.cjs +8 -0
- package/gsd-core/bin/lib/adr-parser.cjs +13 -7
- package/gsd-core/bin/lib/agent-install-check.cjs +162 -0
- package/gsd-core/bin/lib/api-coverage.cjs +30 -9
- package/gsd-core/bin/lib/artifacts.cjs +2 -0
- package/gsd-core/bin/lib/assumption-delta.cjs +30 -11
- package/gsd-core/bin/lib/audit.cjs +163 -41
- package/gsd-core/bin/lib/broken-windows.cjs +306 -28
- package/gsd-core/bin/lib/capability-activation.cjs +27 -0
- package/gsd-core/bin/lib/capability-lock.cjs +10 -4
- package/gsd-core/bin/lib/capability-registry.cjs +785 -144
- package/gsd-core/bin/lib/capability-state.cjs +25 -4
- package/gsd-core/bin/lib/capability-validator.cjs +321 -18
- package/gsd-core/bin/lib/capability-writer.cjs +14 -4
- package/gsd-core/bin/lib/check-command-router.cjs +229 -6
- package/gsd-core/bin/lib/claude-orchestration.cjs +10 -25
- package/gsd-core/bin/lib/cli-exit.cjs +496 -10
- package/gsd-core/bin/lib/clusters.cjs +1 -0
- package/gsd-core/bin/lib/code-review-depth.cjs +288 -0
- package/gsd-core/bin/lib/codex-agent-toml.cjs +410 -4
- package/gsd-core/bin/lib/command-aliases.cjs +16 -0
- package/gsd-core/bin/lib/command-arg-projection.cjs +144 -14
- package/gsd-core/bin/lib/command-routing-hub.cjs +31 -2
- package/gsd-core/bin/lib/commands.cjs +877 -54
- package/gsd-core/bin/lib/complexity-trigger.cjs +26 -6
- package/gsd-core/bin/lib/config-loader.cjs +121 -29
- package/gsd-core/bin/lib/config.cjs +92 -2
- package/gsd-core/bin/lib/configuration.cjs +129 -37
- package/gsd-core/bin/lib/core-utils.cjs +118 -14
- package/gsd-core/bin/lib/decisions.cjs +213 -1
- package/gsd-core/bin/lib/edge-probe.cjs +23 -2
- package/gsd-core/bin/lib/estimate-cli.cjs +55 -11
- package/gsd-core/bin/lib/exit-code-registry.cjs +98 -0
- package/gsd-core/bin/lib/file-overlap-partitioner.cjs +74 -0
- package/gsd-core/bin/lib/frontmatter.cjs +975 -326
- package/gsd-core/bin/lib/gap-checker.cjs +41 -8
- package/gsd-core/bin/lib/git-base-branch.cjs +182 -39
- package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +7 -3
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +8 -2
- package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +60 -14
- package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +75 -22
- package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +22 -8
- package/gsd-core/bin/lib/health-diagnostic.cjs +23 -3
- package/gsd-core/bin/lib/host-integration.cjs +96 -11
- package/gsd-core/bin/lib/init-command-router.cjs +132 -21
- package/gsd-core/bin/lib/init.cjs +252 -56
- package/gsd-core/bin/lib/install-engine.cjs +252 -15
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +78 -1
- package/gsd-core/bin/lib/install-profiles.cjs +100 -18
- package/gsd-core/bin/lib/installer-migration-report.cjs +4 -0
- package/gsd-core/bin/lib/installer-migrations/010-antigravity-retire-confighome-artifacts.cjs +169 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +10 -7
- package/gsd-core/bin/lib/intel.cjs +101 -26
- package/gsd-core/bin/lib/io.cjs +195 -15
- package/gsd-core/bin/lib/learnings.cjs +85 -14
- package/gsd-core/bin/lib/legacy-cleanup.cjs +8 -2
- package/gsd-core/bin/lib/loop-resolver.cjs +14 -8
- package/gsd-core/bin/lib/markdown-table.cjs +175 -4
- package/gsd-core/bin/lib/milestone.cjs +112 -7
- package/gsd-core/bin/lib/model-catalog.cjs +177 -19
- package/gsd-core/bin/lib/model-resolver.cjs +10 -28
- package/gsd-core/bin/lib/onboard-projection.cjs +5 -1
- package/gsd-core/bin/lib/phase-command-router.cjs +13 -6
- package/gsd-core/bin/lib/phase-estimation.cjs +17 -8
- package/gsd-core/bin/lib/phase-id.cjs +321 -13
- package/gsd-core/bin/lib/phase-lifecycle.cjs +24 -16
- package/gsd-core/bin/lib/phase-locator.cjs +138 -17
- package/gsd-core/bin/lib/phase.cjs +1175 -115
- package/gsd-core/bin/lib/plan-document.cjs +273 -0
- package/gsd-core/bin/lib/plan-scan.cjs +13 -2
- package/gsd-core/bin/lib/planning-command-router.cjs +61 -0
- package/gsd-core/bin/lib/planning-inspect.cjs +1168 -0
- package/gsd-core/bin/lib/planning-snapshot.cjs +165 -34
- package/gsd-core/bin/lib/planning-workspace.cjs +159 -28
- package/gsd-core/bin/lib/probe-core.cjs +4 -1
- package/gsd-core/bin/lib/profile-pipeline-command-router.cjs +50 -7
- package/gsd-core/bin/lib/profile-pipeline.cjs +6 -3
- package/gsd-core/bin/lib/quick-batch-command-router.cjs +285 -0
- package/gsd-core/bin/lib/quick-batch-dispatch.cjs +250 -0
- package/gsd-core/bin/lib/quick-batch.cjs +840 -0
- package/gsd-core/bin/lib/real-home-guard.cjs +419 -0
- package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +71 -45
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +62 -14
- package/gsd-core/bin/lib/review-lane-invocation.cjs +73 -1
- package/gsd-core/bin/lib/review-lane-runner.cjs +136 -10
- package/gsd-core/bin/lib/roadmap-command-router.cjs +45 -31
- package/gsd-core/bin/lib/roadmap-parser.cjs +577 -41
- package/gsd-core/bin/lib/roadmap.cjs +248 -64
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +329 -41
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +16 -17
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +320 -109
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +487 -83
- package/gsd-core/bin/lib/runtime-identity.cjs +234 -0
- package/gsd-core/bin/lib/runtime-slash.cjs +72 -2
- package/gsd-core/bin/lib/shell-command-projection.cjs +75 -8
- package/gsd-core/bin/lib/smart-entry.cjs +19 -31
- package/gsd-core/bin/lib/spec-section.cjs +12 -7
- package/gsd-core/bin/lib/state-command-router.cjs +47 -18
- package/gsd-core/bin/lib/state-contract.cjs +359 -0
- package/gsd-core/bin/lib/state-document.cjs +216 -5
- package/gsd-core/bin/lib/state-md-schema.cjs +231 -0
- package/gsd-core/bin/lib/state-transition.cjs +850 -145
- package/gsd-core/bin/lib/state.cjs +1629 -287
- package/gsd-core/bin/lib/surface.cjs +33 -10
- package/gsd-core/bin/lib/task-command-router.cjs +111 -1
- package/gsd-core/bin/lib/task-content-resolution.cjs +368 -0
- package/gsd-core/bin/lib/tdd-red-evidence.cjs +133 -0
- package/gsd-core/bin/lib/teams-status.cjs +4 -1
- package/gsd-core/bin/lib/uat-predicate.cjs +58 -20
- package/gsd-core/bin/lib/uat.cjs +2542 -387
- package/gsd-core/bin/lib/ui-consideration-probe.cjs +9 -1
- package/gsd-core/bin/lib/ui-safety-gate.cjs +37 -7
- package/gsd-core/bin/lib/unusable-input.cjs +13 -0
- package/gsd-core/bin/lib/update-context.cjs +6 -2
- package/gsd-core/bin/lib/validate-command-router.cjs +2 -2
- package/gsd-core/bin/lib/validate.cjs +230 -12
- package/gsd-core/bin/lib/vendor/README.md +43 -5
- package/gsd-core/bin/lib/vendor/js-yaml.cjs +3014 -0
- package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +287 -13
- package/gsd-core/bin/lib/verify-command-grounding.cjs +846 -0
- package/gsd-core/bin/lib/verify-command-router.cjs +1 -0
- package/gsd-core/bin/lib/verify.cjs +441 -56
- package/gsd-core/bin/lib/workstream-inventory.cjs +20 -2
- package/gsd-core/bin/lib/workstream-name-policy.cjs +25 -4
- package/gsd-core/bin/lib/worktree-base-ref.cjs +66 -12
- package/gsd-core/bin/lib/worktree-safety.cjs +185 -21
- package/gsd-core/bin/shared/config-defaults.manifest.json +7 -1
- package/gsd-core/bin/shared/config-schema.manifest.json +13 -0
- package/gsd-core/bin/shared/exit-codes.json +8 -0
- package/gsd-core/bin/shared/exit-codes.sh +20 -0
- package/gsd-core/bin/shared/model-catalog.json +8 -1
- package/gsd-core/bin/verify-reapply-patches.cjs +70 -3
- package/gsd-core/references/agent-contracts.md +6 -5
- package/gsd-core/references/api-coverage.md +24 -2
- package/gsd-core/references/autonomous-smart-discuss.md +3 -3
- package/gsd-core/references/checkpoints.md +37 -19
- package/gsd-core/references/decimal-phase-calculation.md +5 -5
- package/gsd-core/references/edge-probe.md +17 -5
- package/gsd-core/references/execute-mvp-tdd.md +18 -18
- package/gsd-core/references/execute-phase-between-wave-reset.md +9 -12
- package/gsd-core/references/execute-phase-response-language.md +6 -0
- package/gsd-core/references/execute-phase-wave-guard.md +11 -9
- package/gsd-core/references/executor-examples.md +42 -0
- package/gsd-core/references/failing-direction.md +78 -0
- package/gsd-core/references/few-shot-examples/plan-checker.md +15 -15
- package/gsd-core/references/gate-prompts.md +1 -1
- package/gsd-core/references/git-integration.md +5 -5
- package/gsd-core/references/git-planning-commit.md +3 -3
- package/gsd-core/references/gsd-run-resolver.md +1 -1
- package/gsd-core/references/loop-hook-dispatch.md +22 -0
- package/gsd-core/references/model-profiles.md +1 -1
- package/gsd-core/references/mvp-concepts.md +2 -2
- package/gsd-core/references/nyquist-compliance.md +74 -0
- package/gsd-core/references/offer-next.md +3 -5
- package/gsd-core/references/phase-argument-parsing.md +3 -3
- package/gsd-core/references/plan-checker-examples.md +41 -0
- package/gsd-core/references/planner-antipatterns.md +25 -0
- package/gsd-core/references/planner-chunked.md +5 -1
- package/gsd-core/references/planner-coupling.md +42 -0
- package/gsd-core/references/planner-failing-direction.md +53 -0
- package/gsd-core/references/planner-human-verify-mode.md +15 -1
- package/gsd-core/references/planner-quick-batch.md +71 -0
- package/gsd-core/references/planner-reviews.md +47 -0
- package/gsd-core/references/planner-revision.md +76 -3
- package/gsd-core/references/planner-verify-command-grounding.md +17 -0
- package/gsd-core/references/planning-config.md +39 -9
- package/gsd-core/references/response-language-directive.md +9 -0
- package/gsd-core/references/reviewer-instances.md +31 -0
- package/gsd-core/references/revision-loop.md +118 -11
- package/gsd-core/references/runtime-aware-dispatch.md +1 -1
- package/gsd-core/references/tdd.md +15 -12
- package/gsd-core/references/ui-brand.md +65 -21
- package/gsd-core/references/ui-consideration-probe.md +1 -1
- package/gsd-core/references/universal-anti-patterns.md +2 -2
- package/gsd-core/references/verifier-evidence-gate.md +160 -0
- package/gsd-core/references/verify-command-path-resolvability.md +42 -0
- package/gsd-core/references/verify-mvp-mode.md +1 -1
- package/gsd-core/references/workstream-flag.md +11 -11
- package/gsd-core/templates/README.md +1 -1
- package/gsd-core/templates/SECURITY.md +3 -3
- package/gsd-core/templates/UI-SPEC.md +25 -3
- package/gsd-core/templates/VALIDATION.md +3 -3
- package/gsd-core/templates/phase-prompt.md +7 -0
- package/gsd-core/templates/state.md +7 -0
- package/gsd-core/templates/verification-report.md +5 -0
- package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
- package/gsd-core/workflows/add-backlog.md +3 -1
- package/gsd-core/workflows/add-phase.md +5 -3
- package/gsd-core/workflows/add-tests.md +4 -9
- package/gsd-core/workflows/add-todo.md +2 -2
- package/gsd-core/workflows/ai-integration-phase.md +5 -10
- package/gsd-core/workflows/analyze-dependencies.md +2 -0
- package/gsd-core/workflows/audit-fix.md +14 -3
- package/gsd-core/workflows/audit-milestone.md +11 -9
- package/gsd-core/workflows/audit-uat.md +19 -2
- package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +2 -2
- package/gsd-core/workflows/autonomous.md +12 -26
- package/gsd-core/workflows/check-todos.md +2 -2
- package/gsd-core/workflows/cleanup.md +3 -3
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +16 -14
- package/gsd-core/workflows/code-review-fix.md +3 -1
- package/gsd-core/workflows/code-review.md +192 -69
- package/gsd-core/workflows/complete-milestone.md +28 -14
- package/gsd-core/workflows/debug.md +6 -4
- package/gsd-core/workflows/diagnose-issues.md +17 -7
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +3 -1
- package/gsd-core/workflows/discuss-phase/modes/all.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/analyze.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/auto.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/batch.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/chain.md +5 -7
- package/gsd-core/workflows/discuss-phase/modes/default.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/power.md +2 -0
- package/gsd-core/workflows/discuss-phase/modes/text.md +3 -1
- package/gsd-core/workflows/discuss-phase/templates/context.md +2 -0
- package/gsd-core/workflows/discuss-phase/templates/discussion-log.md +2 -0
- package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +1 -3
- package/gsd-core/workflows/discuss-phase-assumptions.md +3 -3
- package/gsd-core/workflows/discuss-phase-power.md +2 -0
- package/gsd-core/workflows/discuss-phase.md +2 -2
- package/gsd-core/workflows/do.md +46 -19
- package/gsd-core/workflows/docs-update.md +6 -5
- package/gsd-core/workflows/edit-phase.md +3 -1
- package/gsd-core/workflows/eval-review.md +5 -10
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +3 -1
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +129 -11
- 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 +29 -5
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/protected-branch.md +21 -0
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +4 -2
- package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +25 -0
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +39 -0
- package/gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md +2 -0
- package/gsd-core/workflows/execute-phase.md +68 -66
- package/gsd-core/workflows/execute-plan.md +25 -20
- package/gsd-core/workflows/explore.md +3 -1
- package/gsd-core/workflows/extract-learnings.md +3 -1
- package/gsd-core/workflows/fast.md +8 -2
- package/gsd-core/workflows/forensics.md +3 -1
- package/gsd-core/workflows/graduation.md +6 -6
- package/gsd-core/workflows/health.md +4 -7
- package/gsd-core/workflows/help/modes/brief.md +2 -0
- package/gsd-core/workflows/help/modes/default.md +2 -0
- package/gsd-core/workflows/help/modes/full.md +12 -0
- package/gsd-core/workflows/help/modes/topic.md +2 -0
- package/gsd-core/workflows/help.md +2 -0
- package/gsd-core/workflows/import.md +17 -14
- package/gsd-core/workflows/inbox.md +5 -6
- package/gsd-core/workflows/ingest-docs.md +45 -12
- package/gsd-core/workflows/insert-phase.md +7 -5
- package/gsd-core/workflows/list-phase-assumptions.md +2 -0
- package/gsd-core/workflows/list-seeds.md +7 -3
- package/gsd-core/workflows/list-workspaces.md +3 -1
- package/gsd-core/workflows/manager.md +15 -26
- package/gsd-core/workflows/map-codebase.md +3 -1
- package/gsd-core/workflows/milestone-summary.md +3 -1
- package/gsd-core/workflows/mvp-phase.md +3 -3
- package/gsd-core/workflows/new-milestone.md +10 -22
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
- package/gsd-core/workflows/new-project.md +17 -29
- package/gsd-core/workflows/new-workspace.md +2 -2
- package/gsd-core/workflows/next.md +4 -2
- package/gsd-core/workflows/node-repair.md +2 -0
- package/gsd-core/workflows/note.md +2 -0
- package/gsd-core/workflows/onboard.md +1 -1
- package/gsd-core/workflows/pause-work.md +20 -5
- package/gsd-core/workflows/plan-phase/steps/adr-ingest-express-path.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +100 -18
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +4 -4
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +12 -3
- package/gsd-core/workflows/plan-phase.md +251 -54
- package/gsd-core/workflows/plan-review-convergence.md +148 -19
- package/gsd-core/workflows/plant-seed.md +3 -3
- package/gsd-core/workflows/pr-branch.md +195 -51
- package/gsd-core/workflows/profile-user.md +17 -15
- package/gsd-core/workflows/progress/steps/forensic-audit.md +1 -1
- package/gsd-core/workflows/progress.md +52 -15
- package/gsd-core/workflows/quick/steps/discussion-phase.md +1 -3
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +38 -5
- package/gsd-core/workflows/quick/steps/quick-verification.md +2 -4
- package/gsd-core/workflows/quick/steps/research-phase.md +5 -7
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +3 -3
- package/gsd-core/workflows/quick-batch/steps/batch-init.md +55 -0
- package/gsd-core/workflows/quick-batch/steps/completion.md +65 -0
- package/gsd-core/workflows/quick-batch/steps/merge-wave.md +100 -0
- package/gsd-core/workflows/quick-batch/steps/plan-checker-loop.md +147 -0
- package/gsd-core/workflows/quick-batch/steps/planner-wave.md +158 -0
- package/gsd-core/workflows/quick-batch/steps/research-phase.md +95 -0
- package/gsd-core/workflows/quick-batch/steps/resume-mode.md +49 -0
- package/gsd-core/workflows/quick-batch/steps/verification-wave.md +73 -0
- package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +169 -0
- package/gsd-core/workflows/quick-batch.md +203 -0
- package/gsd-core/workflows/quick.md +33 -32
- package/gsd-core/workflows/reapply-patches.md +2 -0
- package/gsd-core/workflows/remove-phase.md +6 -4
- package/gsd-core/workflows/remove-workspace.md +3 -3
- package/gsd-core/workflows/resume-project.md +14 -14
- package/gsd-core/workflows/review.md +404 -21
- package/gsd-core/workflows/scan.md +3 -1
- package/gsd-core/workflows/section-manifest.json +12 -0
- package/gsd-core/workflows/secure-phase.md +3 -3
- package/gsd-core/workflows/session-report.md +2 -0
- package/gsd-core/workflows/settings-advanced.md +9 -9
- package/gsd-core/workflows/settings-integrations.md +66 -32
- package/gsd-core/workflows/settings.md +4 -6
- package/gsd-core/workflows/ship.md +22 -16
- package/gsd-core/workflows/sketch-wrap-up.md +13 -17
- package/gsd-core/workflows/sketch.md +13 -19
- package/gsd-core/workflows/smart-entry.md +4 -6
- package/gsd-core/workflows/spec-phase.md +31 -4
- package/gsd-core/workflows/spike-wrap-up.md +9 -11
- package/gsd-core/workflows/spike.md +21 -32
- package/gsd-core/workflows/stats.md +4 -2
- package/gsd-core/workflows/sync-skills.md +13 -5
- package/gsd-core/workflows/thread.md +13 -7
- package/gsd-core/workflows/transition.md +7 -5
- package/gsd-core/workflows/ui-phase.md +36 -21
- package/gsd-core/workflows/ui-review.md +7 -11
- package/gsd-core/workflows/ultraplan-phase.md +7 -13
- package/gsd-core/workflows/undo.md +9 -17
- package/gsd-core/workflows/update.md +47 -48
- package/gsd-core/workflows/validate-phase.md +3 -3
- package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +25 -1
- package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +1 -1
- package/gsd-core/workflows/verify-work.md +106 -21
- package/hooks/dist/gsd-agent-isolation-guard.js +77 -38
- package/hooks/dist/gsd-check-update-worker.js +19 -2
- package/hooks/dist/gsd-config-reload.js +18 -12
- package/hooks/dist/gsd-context-monitor.js +302 -22
- package/hooks/dist/gsd-cursor-post-tool.js +3 -1
- package/hooks/dist/gsd-cursor-pre-tool.js +3 -1
- package/hooks/dist/gsd-cursor-session-start.js +2 -1
- package/hooks/dist/gsd-cursor-stop.js +2 -1
- package/hooks/dist/gsd-cursor-subagent-start.js +28 -23
- package/hooks/dist/gsd-cursor-subagent-stop.js +3 -1
- package/hooks/dist/gsd-ensure-canonical-path.js +2 -1
- package/hooks/dist/gsd-graphify-update.sh +22 -18
- package/hooks/dist/gsd-node-runner.sh +77 -0
- package/hooks/dist/gsd-phase-boundary.sh +1 -0
- package/hooks/dist/gsd-prompt-guard.js +46 -12
- package/hooks/dist/gsd-read-guard.js +18 -7
- package/hooks/dist/gsd-read-injection-scanner.js +22 -13
- package/hooks/dist/gsd-secret-read-guard.js +1079 -0
- package/hooks/dist/gsd-session-state.sh +1 -0
- package/hooks/dist/gsd-statusline.js +222 -29
- package/hooks/dist/gsd-validate-commit.sh +523 -12
- package/hooks/dist/gsd-windsurf-pre-command.js +16 -11
- package/hooks/dist/gsd-windsurf-pre-write.js +22 -13
- package/hooks/dist/gsd-workflow-guard.js +36 -17
- package/hooks/dist/gsd-worktree-path-guard.js +36 -21
- package/hooks/dist/gsd-write-guard.js +35 -25
- package/hooks/dist/lib/cli-exit.js +560 -0
- package/hooks/dist/lib/exit-code-registry.js +98 -0
- package/hooks/dist/lib/git-cmd.js +210 -1
- package/hooks/dist/lib/git-probe.js +84 -0
- package/hooks/dist/lib/hook-exit.js +81 -0
- package/hooks/dist/lib/injection-patterns.js +36 -6
- package/hooks/dist/managed-hooks-registry.cjs +4 -0
- package/hooks/gsd-agent-isolation-guard.js +77 -38
- package/hooks/gsd-check-update-worker.js +19 -2
- package/hooks/gsd-config-reload.js +18 -12
- package/hooks/gsd-context-monitor.js +302 -22
- package/hooks/gsd-cursor-post-tool.js +3 -1
- package/hooks/gsd-cursor-pre-tool.js +3 -1
- package/hooks/gsd-cursor-session-start.js +2 -1
- package/hooks/gsd-cursor-stop.js +2 -1
- package/hooks/gsd-cursor-subagent-start.js +28 -23
- package/hooks/gsd-cursor-subagent-stop.js +3 -1
- package/hooks/gsd-ensure-canonical-path.js +2 -1
- package/hooks/gsd-graphify-update.sh +22 -18
- package/hooks/gsd-node-runner.sh +77 -0
- package/hooks/gsd-phase-boundary.sh +1 -0
- package/hooks/gsd-prompt-guard.js +46 -12
- package/hooks/gsd-read-guard.js +18 -7
- package/hooks/gsd-read-injection-scanner.js +22 -13
- package/hooks/gsd-secret-read-guard.js +1079 -0
- package/hooks/gsd-session-state.sh +1 -0
- package/hooks/gsd-statusline.js +222 -29
- package/hooks/gsd-validate-commit.sh +523 -12
- package/hooks/gsd-windsurf-pre-command.js +16 -11
- package/hooks/gsd-windsurf-pre-write.js +22 -13
- package/hooks/gsd-workflow-guard.js +36 -17
- package/hooks/gsd-worktree-path-guard.js +36 -21
- package/hooks/gsd-write-guard.js +35 -25
- package/hooks/hooks.json +6 -0
- package/hooks/lib/cli-exit.js +560 -0
- package/hooks/lib/exit-code-registry.js +98 -0
- package/hooks/lib/git-cmd.js +210 -1
- package/hooks/lib/git-probe.js +84 -0
- package/hooks/lib/hook-exit.js +81 -0
- package/hooks/lib/injection-patterns.js +36 -6
- package/hooks/managed-hooks-registry.cjs +4 -0
- package/package.json +14 -9
- package/scripts/base64-scan.sh +74 -12
- package/scripts/build-hooks.js +12 -0
- package/scripts/check-glossary-refs.cjs +77 -15
- package/scripts/check-mutation-score-ratchet.cjs +156 -0
- package/scripts/ci-check-job-near-cap.cjs +49 -0
- package/scripts/ci-pr-mergeability.cjs +262 -0
- package/scripts/ci-test-scope.cjs +52 -12
- package/scripts/ci-timeout-report.cjs +230 -0
- package/scripts/docs-guard-registry.cjs +406 -0
- package/scripts/gen-capability-registry.cjs +8 -6
- package/scripts/gen-exit-code-docs.cjs +318 -0
- package/scripts/gen-exit-code-registry.cjs +891 -0
- package/scripts/gen-features.cjs +836 -0
- package/scripts/gen-hooks-cli-exit.cjs +239 -0
- package/scripts/gen-install-tree-fixtures.cjs +2 -2
- package/scripts/gen-loop-host-contract.cjs +189 -4
- package/scripts/gen-scripts-cli-exit.cjs +185 -0
- package/scripts/gen-state-md-docs.cjs +727 -0
- package/scripts/{test-failure-reasons.cjs → gsd-test-gate-reasons.cjs} +6 -0
- package/scripts/lib/ci-job-timing.cjs +72 -0
- package/scripts/lib/cli-exit.cjs +546 -44
- package/scripts/lib/drift-scan.cjs +32 -2
- package/scripts/lib/exit-code-registry.cjs +98 -0
- package/scripts/lib/ndjson-reporter.cjs +119 -0
- package/scripts/lib/shellcheck-fetch.cjs +247 -0
- package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -6
- package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
- package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
- package/scripts/lint-docs-guard-registration.cjs +495 -0
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +198 -0
- package/scripts/lint-eslint-glob-coverage.allowlist.json +4 -0
- package/scripts/{lint-fix-has-regression-test.cjs → lint-fix-has-regression-tests.cjs} +12 -6
- package/scripts/lint-health-diagnostic-rule-table.cjs +65 -8
- package/scripts/lint-mutation-test-derivation-drift.cjs +86 -0
- package/scripts/lint-phase-enumeration-drift.cjs +45 -14
- package/scripts/lint-phase-id-drift.cjs +133 -8
- package/scripts/lint-planning-prompt-drift.cjs +38 -1
- package/scripts/lint-portable-grep.cjs +176 -0
- package/scripts/lint-removed-but-needed.cjs +184 -16
- package/scripts/lint-response-language-coverage.cjs +524 -0
- package/scripts/lint-seam-enforcement.cjs +182 -0
- package/scripts/lint-slug-derivation-drift.cjs +921 -0
- package/scripts/lint-source-test-name-collision.cjs +241 -0
- package/scripts/lint-state-write-path-drift.cjs +337 -432
- package/scripts/lint-test-file-count.allowlist.json +124 -4
- package/scripts/lint-test-file-count.cjs +25 -3
- package/scripts/lint-unreachable-guard-drift.cjs +51 -64
- package/scripts/lint-vendored-deps.cjs +208 -35
- package/scripts/lint-workflow-shellcheck-baseline.json +1027 -0
- package/scripts/lint-workflow-shellcheck.cjs +614 -0
- package/scripts/mutation-matrix.cjs +599 -50
- package/scripts/npm-audit-baseline.cjs +376 -0
- package/scripts/prompt-injection-scan.sh +83 -14
- package/scripts/require-issue-link-policy.cjs +16 -1
- package/scripts/secret-scan.sh +75 -13
- package/scripts/select-docs-guards.cjs +56 -0
- package/scripts/sync-runtime-launcher.cjs +22 -3
- package/skills/gsd-discuss-phase/SKILL.md +1 -1
- package/skills/gsd-execute-phase/SKILL.md +1 -1
- package/skills/gsd-import/SKILL.md +1 -1
- package/skills/gsd-ns-workflow/SKILL.md +1 -0
- package/skills/gsd-phase/SKILL.md +1 -1
- package/skills/gsd-quick/SKILL.md +8 -4
- package/skills/gsd-quick-batch/SKILL.md +105 -0
- package/skills/gsd-surface/SKILL.md +18 -8
- package/vscode/package.json +1 -1
- package/bin/lib/ui-safety-gate.cjs +0 -109
- package/scripts/lint-emitted-drift-ack.cjs +0 -344
- package/scripts/state-write-path-drift-baseline.json +0 -19
|
@@ -1,17 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_doc": "Baseline of modules currently exceeding the 2-test-file limit. Each entry locks in TODAY's exact test filenames as the allowlisted set (identity ratchet). Adding a NEW test file to a capped module fails (novel). Removing one requires pruning this list (stale, ratchet-down). When a cluster drops to \u2264 2, remove its entry entirely. New entries require justification in PR description.",
|
|
3
3
|
"modules": {
|
|
4
|
+
"adr-parser": {
|
|
5
|
+
"files": [
|
|
6
|
+
"adr-parser.property.test.cjs",
|
|
7
|
+
"adr-parser.test.cjs",
|
|
8
|
+
"adr-parser.unit.test.cjs"
|
|
9
|
+
],
|
|
10
|
+
"issue": "3227",
|
|
11
|
+
"justification": "Grandfathered by #3227 when the testEffectivePrefix() dot/hyphen bucketing fix first made this pre-existing over-cap cluster visible to the gate; not new test sprawl."
|
|
12
|
+
},
|
|
4
13
|
"config": {
|
|
5
14
|
"files": [
|
|
6
15
|
"config-defaults-runtime-exclusion.test.cjs",
|
|
7
16
|
"config-field-docs.test.cjs",
|
|
8
17
|
"config-get-default.test.cjs",
|
|
9
|
-
"config-
|
|
18
|
+
"config-get-raw-guard.test.cjs",
|
|
10
19
|
"config-validation.test.cjs",
|
|
11
20
|
"config.test.cjs"
|
|
12
21
|
],
|
|
13
22
|
"issue": "TBD"
|
|
14
23
|
},
|
|
24
|
+
"context-predicates": {
|
|
25
|
+
"files": [
|
|
26
|
+
"context-predicates-query.test.cjs",
|
|
27
|
+
"context-predicates.property.test.cjs",
|
|
28
|
+
"context-predicates.test.cjs"
|
|
29
|
+
],
|
|
30
|
+
"issue": "3227",
|
|
31
|
+
"justification": "Grandfathered by #3227 when the testEffectivePrefix() dot/hyphen bucketing fix first made this pre-existing over-cap cluster visible to the gate; not new test sprawl."
|
|
32
|
+
},
|
|
33
|
+
"frontmatter": {
|
|
34
|
+
"files": [
|
|
35
|
+
"frontmatter-cli.test.cjs",
|
|
36
|
+
"frontmatter-golden-parity.test.cjs",
|
|
37
|
+
"frontmatter-roundtrip.property.test.cjs",
|
|
38
|
+
"frontmatter.property.test.cjs",
|
|
39
|
+
"frontmatter.test.cjs",
|
|
40
|
+
"frontmatter.unit.test.cjs"
|
|
41
|
+
],
|
|
42
|
+
"issue": "3881",
|
|
43
|
+
"justification": "Grandfathered by #3227 for the original 4-file cluster (pre-existing over-cap, not new sprawl). #3881 (ADR-3473 \u00a78.1, the js-yaml parser migration) adds two more: frontmatter-golden-parity.test.cjs (D-series golden-corpus diff against the legacy parser, ~900 real documents \u2014 cannot be folded into an existing file without losing its independent-of-current-parser provenance) and frontmatter-roundtrip.property.test.cjs (fast-check property coverage the migration's bijective-contract rule requires). Both are migration-specific, not incidental sprawl."
|
|
44
|
+
},
|
|
15
45
|
"graphify": {
|
|
16
46
|
"files": [
|
|
17
47
|
"graphify-auto-update.slow.test.cjs",
|
|
@@ -51,6 +81,7 @@
|
|
|
51
81
|
"phase-dependency-levels.test.cjs",
|
|
52
82
|
"phase-resolution-parity.test.cjs",
|
|
53
83
|
"phase-structure.test.cjs",
|
|
84
|
+
"phase-tdd-applicable.test.cjs",
|
|
54
85
|
"phase.test.cjs"
|
|
55
86
|
],
|
|
56
87
|
"issue": "3186"
|
|
@@ -99,6 +130,7 @@
|
|
|
99
130
|
},
|
|
100
131
|
"verify": {
|
|
101
132
|
"files": [
|
|
133
|
+
"verify-archive-dirs-live-path.test.cjs",
|
|
102
134
|
"verify-health.test.cjs",
|
|
103
135
|
"verify-mvp-uat.test.cjs",
|
|
104
136
|
"verify-npm-publish.test.cjs",
|
|
@@ -106,20 +138,22 @@
|
|
|
106
138
|
"verify-work-auto-transition.test.cjs",
|
|
107
139
|
"verify.test.cjs"
|
|
108
140
|
],
|
|
109
|
-
"issue": "
|
|
141
|
+
"issue": "#3813 \u2014 the live-path #1883 suite drives buildPlanningSnapshot in-process with an fs fault; the verify module suites are CLI-driving and cannot host an fs monkeypatch",
|
|
142
|
+
"justification": "verify-command-grounding added by #2401/#3678; allowlist follow-up landed with #3606 (base was red on this lane)."
|
|
110
143
|
},
|
|
111
144
|
"install": {
|
|
112
145
|
"files": [
|
|
113
146
|
"install-minimal-hooks.test.cjs",
|
|
114
147
|
"install-nested-layout.test.cjs",
|
|
115
148
|
"install-path-detection.test.cjs",
|
|
149
|
+
"install-profile-workflow-spawns.test.cjs",
|
|
116
150
|
"install-regressions.test.cjs",
|
|
117
151
|
"install-runtime-artifacts.test.cjs",
|
|
118
152
|
"install-update-marker.test.cjs",
|
|
119
153
|
"install-write-confinement.test.cjs",
|
|
120
154
|
"install.test.cjs"
|
|
121
155
|
],
|
|
122
|
-
"issue": "
|
|
156
|
+
"issue": "#3798 \u2014 the profile-closure spawn test reads the real repo surface (commands+workflows+agents); consolidating it into install.test.cjs would put a whole-repo scan behind the suite's heaviest file"
|
|
123
157
|
},
|
|
124
158
|
"edge-probe": {
|
|
125
159
|
"files": [
|
|
@@ -150,9 +184,95 @@
|
|
|
150
184
|
"files": [
|
|
151
185
|
"prompt-budget-cli.test.cjs",
|
|
152
186
|
"prompt-budget-parity.test.cjs",
|
|
153
|
-
"prompt-budget.test.cjs"
|
|
187
|
+
"prompt-budget.property.test.cjs",
|
|
188
|
+
"prompt-budget.test.cjs",
|
|
189
|
+
"prompt-budget.unit.test.cjs"
|
|
154
190
|
],
|
|
155
191
|
"issue": "2929"
|
|
192
|
+
},
|
|
193
|
+
"mcp-catalog": {
|
|
194
|
+
"files": [
|
|
195
|
+
"mcp-catalog-parity.install.test.cjs",
|
|
196
|
+
"mcp-catalog.property.test.cjs",
|
|
197
|
+
"mcp-catalog.test.cjs"
|
|
198
|
+
],
|
|
199
|
+
"issue": "3227",
|
|
200
|
+
"justification": "Grandfathered by #3227 when the testEffectivePrefix() dot/hyphen bucketing fix first made this pre-existing over-cap cluster visible to the gate; not new test sprawl."
|
|
201
|
+
},
|
|
202
|
+
"model-catalog": {
|
|
203
|
+
"files": [
|
|
204
|
+
"model-catalog-runtime-defaults.test.cjs",
|
|
205
|
+
"model-catalog-valid-tiers.test.cjs",
|
|
206
|
+
"model-catalog.unit.test.cjs"
|
|
207
|
+
],
|
|
208
|
+
"issue": "3227",
|
|
209
|
+
"justification": "Grandfathered by #3227 when the testEffectivePrefix() dot/hyphen bucketing fix first made this pre-existing over-cap cluster visible to the gate; not new test sprawl."
|
|
210
|
+
},
|
|
211
|
+
"package-legitimacy": {
|
|
212
|
+
"files": [
|
|
213
|
+
"package-legitimacy-gate.test.cjs",
|
|
214
|
+
"package-legitimacy.property.test.cjs",
|
|
215
|
+
"package-legitimacy.test.cjs"
|
|
216
|
+
],
|
|
217
|
+
"issue": "3227",
|
|
218
|
+
"justification": "Grandfathered by #3227 when the testEffectivePrefix() dot/hyphen bucketing fix first made this pre-existing over-cap cluster visible to the gate; not new test sprawl."
|
|
219
|
+
},
|
|
220
|
+
"runtime-homes": {
|
|
221
|
+
"files": [
|
|
222
|
+
"runtime-homes-descriptor-drive.test.cjs",
|
|
223
|
+
"runtime-homes-legacy-ids-drift-guard.test.cjs",
|
|
224
|
+
"runtime-homes.property.test.cjs"
|
|
225
|
+
],
|
|
226
|
+
"issue": "3227",
|
|
227
|
+
"justification": "Grandfathered by #3227 when the testEffectivePrefix() dot/hyphen bucketing fix first made this pre-existing over-cap cluster visible to the gate; not new test sprawl."
|
|
228
|
+
},
|
|
229
|
+
"section-manifest": {
|
|
230
|
+
"files": [
|
|
231
|
+
"section-manifest-init-facts.test.cjs",
|
|
232
|
+
"section-manifest.property.test.cjs",
|
|
233
|
+
"section-manifest.test.cjs"
|
|
234
|
+
],
|
|
235
|
+
"issue": "3227",
|
|
236
|
+
"justification": "Grandfathered by #3227 when the testEffectivePrefix() dot/hyphen bucketing fix first made this pre-existing over-cap cluster visible to the gate; not new test sprawl."
|
|
237
|
+
},
|
|
238
|
+
"workflow-fragments": {
|
|
239
|
+
"files": [
|
|
240
|
+
"workflow-fragments-emission.install.test.cjs",
|
|
241
|
+
"workflow-fragments.property.test.cjs",
|
|
242
|
+
"workflow-fragments.test.cjs"
|
|
243
|
+
],
|
|
244
|
+
"issue": "3227",
|
|
245
|
+
"justification": "Grandfathered by #3227 when the testEffectivePrefix() dot/hyphen bucketing fix first made this pre-existing over-cap cluster visible to the gate; not new test sprawl."
|
|
246
|
+
},
|
|
247
|
+
"docs": {
|
|
248
|
+
"files": [
|
|
249
|
+
"docs-hooks-table-parity.test.cjs",
|
|
250
|
+
"docs-parity-live-registry.test.cjs",
|
|
251
|
+
"docs-state-md-locale-parity.test.cjs",
|
|
252
|
+
"docs-update.test.cjs"
|
|
253
|
+
],
|
|
254
|
+
"issue": "3873 | #3839 \u2014 the hook-event parity suite cross-checks the four docs hook tables against src/runtime-hooks-surface.cts registrations; a generated-docs concern distinct from content freshness and registry parity",
|
|
255
|
+
"justification": "ADR-3473 \u00a78.8 makes docs/reference/state-md.md and its four locale siblings generated-and-committed and adds the repo's first locale-parity check (verified: no locale-parity lint precedent exists here). That check is a distinct concern from docs-update (content freshness) and docs-parity-live-registry (registry parity); folding it into either would place an unrelated subject inside them purely to satisfy a count. The section it guards is absent from all four translations today and documents the status enum behind #3853."
|
|
256
|
+
},
|
|
257
|
+
"audit": {
|
|
258
|
+
"files": [
|
|
259
|
+
"audit-command-cutover.test.cjs",
|
|
260
|
+
"audit-fix-command.test.cjs",
|
|
261
|
+
"audit-milestone-filename-guard.test.cjs",
|
|
262
|
+
"audit-open-remainder-count.test.cjs",
|
|
263
|
+
"audit-uat-acknowledged.test.cjs",
|
|
264
|
+
"audit-uat-summary-segmentation.test.cjs",
|
|
265
|
+
"audit-workstream-layouts.test.cjs"
|
|
266
|
+
],
|
|
267
|
+
"issue": "#3804/#3805 \u2014 audit-layout and acknowledged-marker suites drive the real audit-uat CLI against on-disk fixtures | #3817 \u2014 regression suite proving countReal counts the truncation remainder marker instead of treating it as one phantom item | #3783 \u2014 dedicated suite for the summary.current_milestone/archived segmentation, matching this module's one-file-per-feature-slice precedent (e.g. audit-uat-acknowledged.test.cjs) rather than growing the unrelated 6900+ line tests/uat.test.cjs (a different module, keyed off uat.cjs)"
|
|
268
|
+
},
|
|
269
|
+
"shell-command-projection": {
|
|
270
|
+
"files": [
|
|
271
|
+
"shell-command-projection-dispatch.test.cjs",
|
|
272
|
+
"shell-command-projection-md-normalize.test.cjs",
|
|
273
|
+
"shell-command-projection-path-sep.test.cjs"
|
|
274
|
+
],
|
|
275
|
+
"issue": "#3854 \u2014 the tight-list suite pins the markdown write-normalizer's blank-line policy through the exported normalizeContent/platformWriteSync seam; a distinct concern from dispatch routing and path separation"
|
|
156
276
|
}
|
|
157
277
|
}
|
|
158
278
|
}
|
|
@@ -74,7 +74,16 @@ function prodPrefix(filename) {
|
|
|
74
74
|
function testEffectivePrefix(testName) {
|
|
75
75
|
const bare = testName
|
|
76
76
|
.replace(/\.integration\.test\.(ts|cjs)$/, '')
|
|
77
|
-
.replace(/\.test\.(ts|cjs)$/, '')
|
|
77
|
+
.replace(/\.test\.(ts|cjs)$/, '')
|
|
78
|
+
// #3227: strip a trailing suite/kind qualifier (`.unit`, `.property`,
|
|
79
|
+
// `.security`, `.slow`, `.install`, `.rule`, `.regression`, `.qa`, ...).
|
|
80
|
+
// A production prefix comes from `prodPrefix`, which strips only the file
|
|
81
|
+
// extension, so it never contains a dot — any surviving trailing `.<word>`
|
|
82
|
+
// is a qualifier. Without this, `frontmatter.property` matched no module at
|
|
83
|
+
// all (65 files counted against nothing repo-wide) and `state-contract.unit`
|
|
84
|
+
// matched the SHORTER `state` module through the `prefix + '-'` rule
|
|
85
|
+
// (9 files mis-bucketed).
|
|
86
|
+
.replace(/\.[a-z0-9]+$/i, '');
|
|
78
87
|
const m = bare.match(/^(?:feat|bug|enh|fix)-\d+(?:-\d+)*-(.+)$/);
|
|
79
88
|
return m ? m[1] : bare;
|
|
80
89
|
}
|
|
@@ -109,12 +118,25 @@ function buildTestMap(prodPrefixes, allTestFiles) {
|
|
|
109
118
|
const map = new Map([...prodPrefixes.keys()].map(p => [p, []]));
|
|
110
119
|
for (const tf of allTestFiles) {
|
|
111
120
|
const ep = testEffectivePrefix(path.basename(tf));
|
|
121
|
+
// fs.readdirSync order (and therefore prodPrefixes' Map insertion order,
|
|
122
|
+
// which is built from it in collectProdPrefixes) is NOT stable across
|
|
123
|
+
// platforms/filesystems — e.g. ext4 hash order on Linux CI differs from
|
|
124
|
+
// HFS+/APFS on macOS. When one module's name is a hyphen-extension of
|
|
125
|
+
// another's (e.g. `verify` and `verify-command-grounding`), first-match-
|
|
126
|
+
// wins bucketing is therefore platform-dependent. Scan every candidate
|
|
127
|
+
// and keep the longest (most specific) matching prefix, so the bucket a
|
|
128
|
+
// test file lands in is decided by specificity, never iteration order.
|
|
129
|
+
let bestPrefix = null;
|
|
112
130
|
for (const prefix of prodPrefixes.keys()) {
|
|
113
131
|
if (ep === prefix || ep.startsWith(prefix + '-')) {
|
|
114
|
-
|
|
115
|
-
|
|
132
|
+
if (bestPrefix === null || prefix.length > bestPrefix.length) {
|
|
133
|
+
bestPrefix = prefix;
|
|
134
|
+
}
|
|
116
135
|
}
|
|
117
136
|
}
|
|
137
|
+
if (bestPrefix !== null) {
|
|
138
|
+
map.get(bestPrefix).push(tf);
|
|
139
|
+
}
|
|
118
140
|
}
|
|
119
141
|
return map;
|
|
120
142
|
}
|
|
@@ -8,37 +8,43 @@
|
|
|
8
8
|
* Design: .gsd/phase/feat-3409-unreachable-shell-guard-lint/40-design.md
|
|
9
9
|
* Test matrix: .gsd/phase/feat-3409-unreachable-shell-guard-lint/50-test-matrix.md
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
11
|
+
* RETIRED — Detector A (`--pick` + `|| echo` on one line), #3884.
|
|
12
|
+
* `gsd-tools.cjs`'s `--pick <field>` extractor used to coerce a missing/
|
|
13
|
+
* absent field to the empty string and exit **0**, which made the `|| echo D`
|
|
14
|
+
* arm in `$(gsd_run query V --pick F 2>/dev/null || echo D)` unreachable on
|
|
15
|
+
* field absence — the exact defect Detector A existed to flag (this file's
|
|
16
|
+
* own prior header quoted the premise verbatim: "the `|| echo D` arm can
|
|
17
|
+
* fire only on a typo in the verb name, never on the field absence it was
|
|
18
|
+
* written to handle"). ADR-3473 §8.4 ("Failure is a value") makes `--pick`
|
|
19
|
+
* exit **non-zero** on an absent field (see
|
|
20
|
+
* `.gsd/phase/feat-3884-failure-is-a-value/40-design.md` rows B6-B14), so
|
|
21
|
+
* that premise is now FALSE: the `|| echo D` arm is reachable, and the shape
|
|
22
|
+
* Detector A forbade is the CORRECT idiom going forward. Keeping Detector A
|
|
23
|
+
* would forbid the fix, so it is removed rather than updated — see this
|
|
24
|
+
* file's Guard ledger entry in 40-design.md ("net: −1 detector, 0 added").
|
|
25
|
+
* `docs/how-to/resolve-unreachable-guard-findings.md` Shape A was updated in
|
|
26
|
+
* the same change (#3884) to say the same thing. The three shell guards this
|
|
27
|
+
* file's Detector A shipped alongside (#3365's Walking Skeleton gate,
|
|
28
|
+
* `PHASE_REQ_IDS`, `complete-milestone.md`'s bare `cat <glob>`) were fixed
|
|
29
|
+
* under #3409 with remedies that never took the now-retired shape (a bare
|
|
30
|
+
* `--pick` with no fallback, a two-line `X=…`/`X="${X:-D}"` split, and an
|
|
31
|
+
* array expansion, respectively) — see
|
|
32
|
+
* `tests/unreachable-shell-guard.test.cjs`, which this file does not touch
|
|
33
|
+
* and which #3884 confirmed still passes unchanged.
|
|
20
34
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* Detector A — a line carrying BOTH a `--pick` token AND a `|| echo`
|
|
25
|
-
* fallback. `--pick` is the discriminator: a `|| echo` default WITHOUT
|
|
26
|
-
* `--pick` (e.g. `config-get k 2>/dev/null || echo "default"`, ~132 of the
|
|
27
|
-
* 141 `$(… || echo …)` lines in the prompt layer) genuinely observes a
|
|
28
|
-
* nonzero exit code and is left alone — see 40-design.md's Rejected #2
|
|
29
|
-
* ("detect on `gsd_run` + `|| echo`" was tried and reverted for exactly
|
|
30
|
-
* this false-positive volume).
|
|
35
|
+
* ONE detector remains, unaffected by the above — its mechanism (nullglob
|
|
36
|
+
* success-on-empty) has nothing to do with `--pick`'s exit code:
|
|
31
37
|
*
|
|
32
38
|
* Detector B — `cat` or `ls` invoked in COMMAND POSITION with an operand
|
|
33
|
-
* containing an unquoted glob metacharacter (`*` or `?`).
|
|
34
|
-
*
|
|
35
|
-
* success-on-empty case silently defeats.
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
39
|
+
* containing an unquoted glob metacharacter (`*` or `?`). At bottom the
|
|
40
|
+
* same class of bug Detector A used to catch one level up the stack: a
|
|
41
|
+
* fallback/guard arm that a success-on-empty case silently defeats.
|
|
42
|
+
* Detector B-ii below is `ls <glob> … || echo` — with `ls`'s own
|
|
43
|
+
* nullglob-driven success-on-empty standing in for what used to be
|
|
44
|
+
* `--pick`'s absence-coerced-to-''. SCOPED to exactly three fired shapes,
|
|
45
|
+
* per a full measurement across the four SCAN_DIRS (measured counts
|
|
46
|
+
* recorded in the PR description; 0 sites for B-iii today, by design — see
|
|
47
|
+
* KNOWN LIMITS):
|
|
42
48
|
*
|
|
43
49
|
* B-i. `cat <glob>` fires UNCONDITIONALLY. This is the stdin-hang
|
|
44
50
|
* shape (measured rc=137 at 3s under an unmatched glob +
|
|
@@ -96,9 +102,6 @@
|
|
|
96
102
|
* `npm run lint:ci` runs CodeQL js/redos over this repo, the same
|
|
97
103
|
* discipline `lint-planning-prompt-drift.cjs` documents in its own header:
|
|
98
104
|
*
|
|
99
|
-
* - PICK_RE / ECHO_FALLBACK_RE carry only a single bounded `\s*`
|
|
100
|
-
* quantifier each, over a fixed literal — no nesting, nothing to
|
|
101
|
-
* backtrack.
|
|
102
105
|
* - CAT_LS_COMMAND_RE's alternation is a FIXED, non-overlapping set (a
|
|
103
106
|
* handful of literal command-position anchors, then a fixed
|
|
104
107
|
* `(cat|ls)`), with one `[ \t]*` quantifier between the anchor and the
|
|
@@ -171,11 +174,6 @@
|
|
|
171
174
|
* SCAN_EXT: `.md` only.
|
|
172
175
|
*
|
|
173
176
|
* KNOWN, ACCEPTED limits (same tradeoffs the sibling guards document):
|
|
174
|
-
* - A cross-line split defeats Detector A (`--pick` on one line, `|| echo`
|
|
175
|
-
* on the next) — left to code review, per-line textual scan only.
|
|
176
|
-
* - `|| printf` and other non-`echo` fallbacks are not detected by
|
|
177
|
-
* Detector A — narrow by design; widening is a one-line change if a
|
|
178
|
-
* site ever appears.
|
|
179
177
|
* - Detector B's command-position anchor set (line start; `;`, `&`, `|`,
|
|
180
178
|
* `(`; the keywords `if`/`then`/`elif`/`while`/`do`) is what lets
|
|
181
179
|
* `$(cat …)` / `$(ls …)` — the dominant real invocation idiom in this
|
|
@@ -214,16 +212,6 @@ const path = require('node:path');
|
|
|
214
212
|
const driftScan = require('./lib/drift-scan.cjs');
|
|
215
213
|
const { sanitizeForReport, scanTree } = driftScan;
|
|
216
214
|
|
|
217
|
-
// ─── Detector A — `--pick` + `|| echo` ────────────────────────────────────
|
|
218
|
-
//
|
|
219
|
-
// `--pick` is the discriminator (see module header); `|| echo` is the
|
|
220
|
-
// unreachable fallback arm it silently defeats. Both must be present on the
|
|
221
|
-
// SAME line for the shape to be the exact unreachable-arm defect #3409
|
|
222
|
-
// fixes — see the module header for why a bare "`gsd_run` + `|| echo`" rule
|
|
223
|
-
// was tried and reverted (Rejected #2).
|
|
224
|
-
const PICK_RE = /--pick\b/;
|
|
225
|
-
const ECHO_FALLBACK_RE = /\|\|\s*echo\b/;
|
|
226
|
-
|
|
227
215
|
// ─── Detector B — cat <glob> (B-i), ls <glob> … || <real fallback> (B-ii),
|
|
228
216
|
// or ls <glob> at the head of if/elif/while (B-iii) ────────────────────────
|
|
229
217
|
//
|
|
@@ -378,22 +366,28 @@ const BASELINE_REL_PATH = path.join('scripts', 'baselines', 'unreachable-guard-d
|
|
|
378
366
|
|
|
379
367
|
// The tracking issue this guard's own baseline entries are owned by, absent
|
|
380
368
|
// a more specific site owner named at `--update` time. #3409 is this
|
|
381
|
-
// guard's own issue: any site it finds that this PR does not
|
|
382
|
-
// "one careless line from the same class" per 40-design.md's
|
|
383
|
-
// section, tracked here until
|
|
384
|
-
//
|
|
369
|
+
// guard's own issue: any Detector B site it finds that this PR does not
|
|
370
|
+
// convert is a "one careless line from the same class" per 40-design.md's
|
|
371
|
+
// Postel's Law section, tracked here until a per-site conversion lands.
|
|
372
|
+
// (Detector A's own entries, if any had ever existed, would have been
|
|
373
|
+
// tracked the same way until the upstream `--pick` contract fix landed —
|
|
374
|
+
// #3884 — but the baseline shipped with zero Detector A entries; see the
|
|
375
|
+
// retirement note at the top of this file.)
|
|
385
376
|
const RATCHET_OWNER_ISSUE = '#3409';
|
|
386
377
|
|
|
387
378
|
/**
|
|
388
|
-
* Pure: scan `text` (one file's content) for Detector
|
|
389
|
-
*
|
|
390
|
-
*
|
|
391
|
-
*
|
|
379
|
+
* Pure: scan `text` (one file's content) for Detector B violations and
|
|
380
|
+
* malformed escape-marker declarations. `relPath` is the repo-relative path
|
|
381
|
+
* (native separators or POSIX, either accepted) — normalized via
|
|
382
|
+
* `toPosixRel` and attached as `file` on every result.
|
|
392
383
|
*
|
|
393
384
|
* Returns `{ violations, malformed }`:
|
|
394
|
-
* - `violations`: `[{ file, line, kind: '
|
|
395
|
-
*
|
|
396
|
-
* discriminating
|
|
385
|
+
* - `violations`: `[{ file, line, kind: 'B', found, text }]` — `text` is
|
|
386
|
+
* the TRIMMED source line (the baseline key), `found` names the
|
|
387
|
+
* discriminating command (`cat`/`ls`). `kind` is retained as a field
|
|
388
|
+
* (rather than dropped now that only one detector remains) so the
|
|
389
|
+
* baseline JSON shape and the `--json` report shape are unchanged by
|
|
390
|
+
* Detector A's retirement.
|
|
397
391
|
* - `malformed`: `[{ file, line, text, reason }]` — an ATTEMPTED
|
|
398
392
|
* `# gsd-scan-ignore:` declaration whose reason names no issue and no
|
|
399
393
|
* URL. Checked on EVERY line independent of whether that line also
|
|
@@ -428,9 +422,6 @@ function findUnreachableGuardDrift(text, relPath) {
|
|
|
428
422
|
}
|
|
429
423
|
if (exempt) continue;
|
|
430
424
|
|
|
431
|
-
if (PICK_RE.test(line) && ECHO_FALLBACK_RE.test(line)) {
|
|
432
|
-
violations.push({ file, line: lineNo, kind: 'A', found: '--pick', text: line.trim() });
|
|
433
|
-
}
|
|
434
425
|
const globInfo = detectGlobOperand(line);
|
|
435
426
|
if (globInfo) {
|
|
436
427
|
violations.push({ file, line: lineNo, kind: 'B', found: globInfo.command, text: line.trim() });
|
|
@@ -774,8 +765,6 @@ function main() {
|
|
|
774
765
|
if (!json) {
|
|
775
766
|
if (fresh.length > 0) {
|
|
776
767
|
process.stderr.write('unreachable-guard-drift: NEW unreachable shell-guard shape(s) found in the prompt layer.\n');
|
|
777
|
-
process.stderr.write('Detector A (--pick + || echo): the fallback can never fire on field absence — replace with an\n');
|
|
778
|
-
process.stderr.write('explicit -z/empty-string test on the resolved value.\n');
|
|
779
768
|
process.stderr.write('Detector B (cat/ls over a glob operand): under a nullglob set elsewhere in the same shell\n');
|
|
780
769
|
process.stderr.write('session, an unmatched glob reads from stdin (cat) or lists the cwd (ls) — use an array\n');
|
|
781
770
|
process.stderr.write('expansion or an existence test instead.\n');
|
|
@@ -825,8 +814,6 @@ module.exports = {
|
|
|
825
814
|
dedupeViolationsForBaseline,
|
|
826
815
|
sortEntries,
|
|
827
816
|
writeBaseline,
|
|
828
|
-
PICK_RE,
|
|
829
|
-
ECHO_FALLBACK_RE,
|
|
830
817
|
CAT_LS_COMMAND_RE,
|
|
831
818
|
HEREDOC_AFTER_COMMAND_RE,
|
|
832
819
|
EXIT_TESTING_KEYWORDS,
|