@opengsd/gsd-core 1.9.1 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +2 -3
- package/.opencode/plugins/gsd-core.js +8 -1
- package/agents/gsd-code-fixer.md +27 -3
- package/agents/gsd-debug-session-manager.md +11 -0
- package/agents/gsd-debugger.md +12 -246
- package/agents/gsd-doc-synthesizer.md +2 -4
- package/agents/gsd-executor.md +12 -10
- package/agents/gsd-integration-checker.md +3 -0
- package/agents/gsd-mempalace-curator.md +5 -2
- package/agents/gsd-phase-researcher.md +20 -1
- package/agents/gsd-plan-checker.md +46 -0
- package/agents/gsd-planner.md +49 -54
- package/agents/gsd-roadmapper.md +21 -3
- package/agents/gsd-user-profiler.md +3 -0
- package/agents/gsd-verifier.md +26 -73
- package/bin/install.js +1272 -1238
- package/bin/lib/ui-safety-gate.cjs +2 -0
- package/commands/gsd/code-review.md +1 -1
- package/commands/gsd/execute-phase.md +1 -1
- package/commands/gsd/map-codebase.md +1 -1
- package/commands/gsd/mempalace-capture.md +2 -2
- package/commands/gsd/mempalace-recall.md +1 -1
- package/commands/gsd/new-milestone.md +2 -2
- package/commands/gsd/plan-phase.md +1 -1
- package/commands/gsd/quick.md +1 -1
- package/commands/gsd/review-backlog.md +2 -1
- package/commands/gsd/verify-work.md +1 -1
- package/gsd-core/bin/gsd-tools.cjs +1009 -115
- package/gsd-core/bin/lib/active-workstream-store.cjs +153 -12
- package/gsd-core/bin/lib/agent-install-check.cjs +268 -38
- package/gsd-core/bin/lib/api-coverage.cjs +123 -5
- package/gsd-core/bin/lib/artifacts.cjs +3 -0
- package/gsd-core/bin/lib/assumption-delta.cjs +2 -4
- package/gsd-core/bin/lib/audit-command-router.cjs +9 -2
- package/gsd-core/bin/lib/audit.cjs +926 -202
- package/gsd-core/bin/lib/broken-windows.cjs +36 -6
- package/gsd-core/bin/lib/capability-consent.cjs +149 -15
- package/gsd-core/bin/lib/capability-lifecycle.cjs +45 -0
- package/gsd-core/bin/lib/capability-registry.cjs +608 -148
- package/gsd-core/bin/lib/capability-source.cjs +92 -0
- package/gsd-core/bin/lib/capability-trust.cjs +444 -25
- package/gsd-core/bin/lib/capability-validator.cjs +507 -24
- package/gsd-core/bin/lib/capability-writer.cjs +3 -2
- package/gsd-core/bin/lib/check-command-router.cjs +114 -38
- package/gsd-core/bin/lib/claude-orchestration.cjs +56 -3
- package/gsd-core/bin/lib/codex-agent-toml.cjs +329 -0
- package/gsd-core/bin/lib/command-aliases.cjs +94 -0
- package/gsd-core/bin/lib/command-roster.cjs +44 -1
- package/gsd-core/bin/lib/commands.cjs +665 -99
- package/gsd-core/bin/lib/commonjs-marker.cjs +142 -0
- package/gsd-core/bin/lib/complexity-trigger.cjs +1172 -0
- package/gsd-core/bin/lib/config-loader.cjs +76 -0
- package/gsd-core/bin/lib/config.cjs +22 -2
- package/gsd-core/bin/lib/context-composer.cjs +278 -0
- package/gsd-core/bin/lib/context-predicates.cjs +506 -0
- package/gsd-core/bin/lib/core-utils.cjs +217 -40
- package/gsd-core/bin/lib/decisions.cjs +23 -0
- package/gsd-core/bin/lib/docs.cjs +3 -2
- package/gsd-core/bin/lib/external-job.cjs +19 -4
- package/gsd-core/bin/lib/fallow-runner.cjs +20 -44
- package/gsd-core/bin/lib/frontmatter.cjs +239 -32
- package/gsd-core/bin/lib/gap-checker.cjs +68 -7
- package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +57 -6
- package/gsd-core/bin/lib/git-base-branch.cjs +160 -15
- package/gsd-core/bin/lib/graphify.cjs +142 -27
- package/gsd-core/bin/lib/gsd2-import.cjs +37 -5
- package/gsd-core/bin/lib/health-diagnostic-rules/agent-install.cjs +101 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/config-validation.cjs +348 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +145 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/install-surface-shadowing.cjs +98 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/milestone-archive-hygiene.cjs +100 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +222 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +265 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/root-existence.cjs +161 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +303 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +173 -0
- package/gsd-core/bin/lib/health-diagnostic-types.cjs +68 -0
- package/gsd-core/bin/lib/health-diagnostic.cjs +431 -0
- package/gsd-core/bin/lib/host-integration.cjs +13 -1
- package/gsd-core/bin/lib/host-runtime-detection.cjs +134 -0
- package/gsd-core/bin/lib/init-command-router.cjs +83 -8
- package/gsd-core/bin/lib/init.cjs +1325 -169
- package/gsd-core/bin/lib/install-effort-resolver.cjs +73 -30
- package/gsd-core/bin/lib/install-engine.cjs +805 -264
- package/gsd-core/bin/lib/install-fs-adapter.cjs +262 -0
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +203 -0
- package/gsd-core/bin/lib/install-profiles.cjs +160 -57
- package/gsd-core/bin/lib/install-scope.cjs +270 -0
- package/gsd-core/bin/lib/install-shadow-report.cjs +385 -0
- package/gsd-core/bin/lib/installed-surface-resolver.cjs +381 -0
- package/gsd-core/bin/lib/installer-migration-authoring.cjs +3 -1
- package/gsd-core/bin/lib/installer-migration-report.cjs +4 -0
- package/gsd-core/bin/lib/installer-migrations/007-retire-config-root-commonjs-marker.cjs +149 -0
- package/gsd-core/bin/lib/installer-migrations/008-cursor-retire-commands-surface.cjs +55 -0
- package/gsd-core/bin/lib/installer-migrations/009-pi-retire-reserved-hooks-dir.cjs +199 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +206 -13
- package/gsd-core/bin/lib/io.cjs +38 -3
- package/gsd-core/bin/lib/markdown-sectionizer.cjs +8 -1
- package/gsd-core/bin/lib/markdown-table.cjs +133 -20
- package/gsd-core/bin/lib/mcp-catalog.cjs +518 -0
- package/gsd-core/bin/lib/mcp-server.cjs +135 -3
- package/gsd-core/bin/lib/milestone-lock.cjs +248 -0
- package/gsd-core/bin/lib/milestone.cjs +821 -109
- package/gsd-core/bin/lib/model-catalog.cjs +59 -1
- package/gsd-core/bin/lib/model-resolver.cjs +183 -40
- package/gsd-core/bin/lib/normalize-test-command.cjs +1 -1
- package/gsd-core/bin/lib/pattern.cjs +122 -0
- package/gsd-core/bin/lib/phase-estimation.cjs +1 -1
- package/gsd-core/bin/lib/phase-id.cjs +507 -36
- package/gsd-core/bin/lib/phase-lifecycle.cjs +28 -3
- package/gsd-core/bin/lib/phase-locator.cjs +258 -58
- package/gsd-core/bin/lib/phase.cjs +891 -156
- package/gsd-core/bin/lib/plan-dependency-graph.cjs +303 -0
- package/gsd-core/bin/lib/plan-drift-guard.cjs +120 -0
- package/gsd-core/bin/lib/plan-scan.cjs +86 -2
- package/gsd-core/bin/lib/planning-scope.cjs +31 -0
- package/gsd-core/bin/lib/planning-snapshot.cjs +890 -0
- package/gsd-core/bin/lib/planning-workspace.cjs +60 -6
- package/gsd-core/bin/lib/probe-core.cjs +1 -1
- package/gsd-core/bin/lib/profile-output.cjs +1 -1
- package/gsd-core/bin/lib/prompt-budget.cjs +128 -165
- package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +740 -0
- package/gsd-core/bin/lib/retired-artifact-cleanup.cjs +85 -0
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +108 -0
- package/gsd-core/bin/lib/review-lane-invocation.cjs +30 -0
- package/gsd-core/bin/lib/review-lane-runner.cjs +447 -68
- package/gsd-core/bin/lib/review-reviewer-selection.cjs +13 -18
- package/gsd-core/bin/lib/roadmap-command-router.cjs +76 -9
- package/gsd-core/bin/lib/roadmap-parser.cjs +1035 -194
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +37 -10
- package/gsd-core/bin/lib/roadmap.cjs +405 -84
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +795 -100
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +14 -2
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +440 -57
- package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +3 -2
- package/gsd-core/bin/lib/runtime-homes.cjs +220 -41
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +220 -44
- package/gsd-core/bin/lib/runtime-name-policy.cjs +3 -1
- package/gsd-core/bin/lib/runtime-slash.cjs +27 -9
- package/gsd-core/bin/lib/section-manifest.cjs +209 -0
- package/gsd-core/bin/lib/security.cjs +104 -5
- package/gsd-core/bin/lib/shell-command-projection.cjs +388 -30
- package/gsd-core/bin/lib/smart-entry.cjs +154 -22
- package/gsd-core/bin/lib/state-command-router.cjs +5 -1
- package/gsd-core/bin/lib/state-document.cjs +152 -8
- package/gsd-core/bin/lib/state-transition.cjs +424 -105
- package/gsd-core/bin/lib/state.cjs +1927 -401
- package/gsd-core/bin/lib/surface.cjs +35 -10
- package/gsd-core/bin/lib/text-lines.cjs +80 -0
- package/gsd-core/bin/lib/token-scanner.cjs +76 -0
- package/gsd-core/bin/lib/uat-predicate.cjs +20 -4
- package/gsd-core/bin/lib/uat.cjs +706 -64
- package/gsd-core/bin/lib/ui-frontend-evidence.cjs +157 -0
- package/gsd-core/bin/lib/ui-safety-gate.cjs +14 -5
- package/gsd-core/bin/lib/unusable-input.cjs +33 -0
- package/gsd-core/bin/lib/update-context.cjs +8 -2
- package/gsd-core/bin/lib/user-artifact-staging.cjs +705 -0
- package/gsd-core/bin/lib/validate.cjs +20 -6
- package/gsd-core/bin/lib/vendor/README.md +37 -0
- package/gsd-core/bin/lib/vendor/re2js.cjs +6480 -0
- package/gsd-core/bin/lib/vendor/re2js.d.cts +938 -0
- package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +287 -20
- package/gsd-core/bin/lib/verify.cjs +368 -880
- package/gsd-core/bin/lib/workflow-fragments.cjs +557 -0
- package/gsd-core/bin/lib/workstream-inventory-builder.cjs +203 -19
- package/gsd-core/bin/lib/workstream-inventory.cjs +576 -31
- package/gsd-core/bin/lib/workstream.cjs +8 -2
- package/gsd-core/bin/lib/worktree-base-ref.cjs +50 -6
- package/gsd-core/bin/lib/worktree-safety.cjs +450 -125
- package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +9 -1
- package/gsd-core/references/agent-contracts.md +43 -26
- package/gsd-core/references/artifact-types.md +10 -3
- package/gsd-core/references/autonomous-ui-design-contract.md +42 -0
- package/gsd-core/references/checkpoints.md +2 -2
- package/gsd-core/references/context-budget.md +1 -1
- package/gsd-core/references/debugger-techniques.md +255 -0
- package/gsd-core/references/dispatch-isolation-gate.md +138 -0
- package/gsd-core/references/doc-conflict-engine.md +1 -1
- package/gsd-core/references/execute-mvp-tdd.md +3 -3
- package/gsd-core/references/execute-phase-between-wave-reset.md +6 -2
- package/gsd-core/references/execute-phase-context-guard.md +1 -1
- package/gsd-core/references/execute-phase-response-language.md +1 -1
- package/gsd-core/references/execute-phase-wave-guard.md +6 -2
- package/gsd-core/references/gate-prompts.md +1 -1
- package/gsd-core/references/git-planning-commit.md +2 -1
- package/gsd-core/references/loop-hook-dispatch.md +39 -2
- package/gsd-core/references/model-profiles.md +12 -4
- package/gsd-core/references/mvp-concepts.md +9 -9
- package/gsd-core/references/planner-guidance.md +3 -9
- package/gsd-core/references/planner-preconditions.md +1 -1
- package/gsd-core/references/planner-reviews.md +1 -1
- package/gsd-core/references/planning-config.md +8 -6
- package/gsd-core/references/research-documentation-lookup.md +5 -3
- package/gsd-core/references/revision-loop.md +1 -1
- package/gsd-core/references/specless-probe-fallback.md +8 -7
- package/gsd-core/references/universal-anti-patterns.md +3 -3
- package/gsd-core/references/verifier-phase-gates.md +192 -0
- package/gsd-core/references/verifier-wiring-patterns.md +100 -0
- package/gsd-core/references/verify-mvp-mode.md +1 -1
- package/gsd-core/references/workstream-flag.md +22 -6
- package/gsd-core/references/worktree-branch-check.md +2 -2
- package/gsd-core/templates/discussion-log.md +1 -1
- package/gsd-core/templates/phase-prompt.md +2 -4
- package/gsd-core/templates/state.md +4 -4
- package/gsd-core/templates/summary-complex.md +2 -0
- package/gsd-core/templates/summary-minimal.md +2 -0
- package/gsd-core/templates/summary-standard.md +2 -0
- package/gsd-core/templates/summary.md +2 -0
- package/gsd-core/templates/verification-report.md +9 -1
- package/gsd-core/workflows/ai-integration-phase.md +9 -11
- package/gsd-core/workflows/audit-milestone.md +3 -0
- package/gsd-core/workflows/autonomous/steps/converge-banner.md +1 -0
- package/gsd-core/workflows/autonomous/steps/converge-dispatch-bg.md +11 -0
- package/gsd-core/workflows/autonomous/steps/converge-dispatch-inline.md +7 -0
- package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +21 -0
- package/gsd-core/workflows/autonomous/steps/converge-loop.md +7 -0
- package/gsd-core/workflows/autonomous.md +33 -70
- package/gsd-core/workflows/cleanup.md +62 -3
- package/gsd-core/workflows/code-review/steps/dispatch-fix.md +39 -0
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +93 -0
- package/gsd-core/workflows/code-review-fix.md +37 -10
- package/gsd-core/workflows/code-review.md +74 -166
- package/gsd-core/workflows/complete-milestone/steps/git-tag.md +29 -0
- package/gsd-core/workflows/complete-milestone.md +160 -95
- package/gsd-core/workflows/debug.md +16 -17
- package/gsd-core/workflows/diagnose-issues.md +56 -8
- package/gsd-core/workflows/discuss-phase/modes/chain.md +2 -1
- package/gsd-core/workflows/discuss-phase/modes/default.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +15 -0
- package/gsd-core/workflows/discuss-phase-assumptions.md +7 -17
- package/gsd-core/workflows/docs-update/steps/dispatch-monorepo-packages.md +51 -0
- package/gsd-core/workflows/docs-update.md +8 -51
- package/gsd-core/workflows/edit-phase.md +26 -1
- package/gsd-core/workflows/eval-review.md +3 -5
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +64 -7
- package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +50 -0
- package/gsd-core/workflows/execute-phase/steps/partial-wave.md +31 -0
- package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +77 -0
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +21 -0
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +42 -0
- package/gsd-core/workflows/execute-phase/steps/regression-gate.md +43 -37
- package/gsd-core/workflows/execute-phase.md +103 -187
- package/gsd-core/workflows/execute-plan.md +36 -4
- package/gsd-core/workflows/explore.md +131 -4
- package/gsd-core/workflows/fast.md +10 -2
- package/gsd-core/workflows/health.md +73 -4
- package/gsd-core/workflows/help/modes/full.md +6 -1
- package/gsd-core/workflows/import.md +4 -4
- package/gsd-core/workflows/ingest-docs.md +7 -6
- package/gsd-core/workflows/mvp-phase.md +6 -3
- package/gsd-core/workflows/new-milestone/steps/project-md-milestone-write.md +16 -0
- package/gsd-core/workflows/new-milestone/steps/reset-phase-safety.md +19 -0
- package/gsd-core/workflows/new-milestone.md +35 -47
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +176 -0
- package/gsd-core/workflows/new-project/steps/auto-mode-detection.md +32 -0
- package/gsd-core/workflows/new-project/steps/codebase-map-offer.md +18 -0
- package/gsd-core/workflows/new-project.md +27 -240
- package/gsd-core/workflows/next.md +12 -0
- package/gsd-core/workflows/plan-phase/steps/adr-ingest-express-path.md +15 -0
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +110 -0
- package/gsd-core/workflows/plan-phase/steps/prd-express-gate.md +8 -0
- package/gsd-core/workflows/plan-phase/steps/research-only-early-exit.md +17 -0
- package/gsd-core/workflows/plan-phase/steps/research-only-modifiers.md +16 -0
- package/gsd-core/workflows/plan-phase/steps/reviews-prerequisite.md +17 -0
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +149 -0
- package/gsd-core/workflows/plan-phase.md +89 -209
- package/gsd-core/workflows/plan-review-convergence.md +50 -2
- package/gsd-core/workflows/progress/steps/forensic-audit.md +125 -0
- package/gsd-core/workflows/progress/steps/mvp-display.md +18 -0
- package/gsd-core/workflows/progress.md +45 -159
- package/gsd-core/workflows/quick/steps/discussion-phase.md +124 -0
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +111 -0
- package/gsd-core/workflows/quick/steps/quick-verification.md +67 -0
- package/gsd-core/workflows/quick/steps/research-phase.md +72 -0
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +37 -0
- package/gsd-core/workflows/quick.md +55 -405
- package/gsd-core/workflows/resume-project.md +3 -0
- package/gsd-core/workflows/review/steps/reviewer-instances-note-1.md +4 -0
- package/gsd-core/workflows/review/steps/reviewer-instances-note-2.md +3 -0
- package/gsd-core/workflows/review.md +41 -13
- package/gsd-core/workflows/section-manifest.json +219 -0
- package/gsd-core/workflows/secure-phase.md +1 -1
- package/gsd-core/workflows/session-report.md +2 -1
- package/gsd-core/workflows/settings.md +66 -2
- package/gsd-core/workflows/ship.md +104 -44
- package/gsd-core/workflows/sketch.md +1 -1
- package/gsd-core/workflows/spec-phase.md +41 -20
- package/gsd-core/workflows/spike-wrap-up.md +20 -5
- package/gsd-core/workflows/spike.md +50 -16
- package/gsd-core/workflows/sync-skills.md +106 -13
- package/gsd-core/workflows/transition/steps/workstream-collision-check.md +17 -0
- package/gsd-core/workflows/transition.md +53 -31
- package/gsd-core/workflows/ui-phase.md +13 -12
- package/gsd-core/workflows/ui-review.md +2 -2
- package/gsd-core/workflows/update/steps/channel-banner.md +7 -0
- package/gsd-core/workflows/update.md +19 -8
- package/gsd-core/workflows/validate-phase.md +1 -1
- package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +36 -0
- package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +21 -0
- package/gsd-core/workflows/verify-work.md +17 -65
- package/hooks/dist/gsd-agent-isolation-guard.js +517 -0
- package/hooks/dist/gsd-check-update-worker.js +64 -12
- package/hooks/dist/gsd-check-update.js +19 -1
- package/hooks/dist/gsd-cursor-pre-tool.js +0 -3
- package/hooks/dist/gsd-cursor-subagent-start.js +607 -26
- package/hooks/dist/gsd-cursor-subagent-stop.js +3 -2
- package/hooks/dist/gsd-prompt-guard.js +21 -20
- package/hooks/dist/gsd-read-injection-scanner.js +45 -24
- package/hooks/dist/gsd-statusline.js +90 -6
- package/hooks/dist/gsd-update-banner.js +22 -1
- package/hooks/dist/gsd-workflow-guard.js +134 -36
- package/hooks/dist/gsd-worktree-path-guard.js +2 -1
- package/hooks/dist/gsd-write-guard.js +359 -0
- package/hooks/dist/lib/git-cmd.js +92 -59
- package/hooks/dist/lib/injection-patterns.js +45 -0
- package/hooks/dist/lib/isolation-deny-reason.js +39 -0
- package/hooks/dist/lib/isolation-sentinel.js +277 -0
- package/hooks/dist/managed-hooks-registry.cjs +2 -0
- package/hooks/gsd-agent-isolation-guard.js +517 -0
- package/hooks/gsd-check-update-worker.js +64 -12
- package/hooks/gsd-check-update.js +19 -1
- package/hooks/gsd-cursor-pre-tool.js +0 -3
- package/hooks/gsd-cursor-subagent-start.js +607 -26
- package/hooks/gsd-cursor-subagent-stop.js +3 -2
- package/hooks/gsd-prompt-guard.js +21 -20
- package/hooks/gsd-read-injection-scanner.js +45 -24
- package/hooks/gsd-statusline.js +90 -6
- package/hooks/gsd-update-banner.js +22 -1
- package/hooks/gsd-workflow-guard.js +134 -36
- package/hooks/gsd-worktree-path-guard.js +2 -1
- package/hooks/gsd-write-guard.js +359 -0
- package/hooks/hooks.json +12 -0
- package/hooks/lib/git-cmd.js +92 -59
- package/hooks/lib/injection-patterns.js +45 -0
- package/hooks/lib/isolation-deny-reason.js +39 -0
- package/hooks/lib/isolation-sentinel.js +277 -0
- package/hooks/managed-hooks-registry.cjs +2 -0
- package/package.json +31 -10
- package/pi/gsd.cjs +71 -12
- package/scripts/baselines/planning-prompt-drift-baseline.json +4 -0
- package/scripts/baselines/planning-snapshot-bypass-baseline.json +12 -0
- package/scripts/baselines/unreachable-guard-drift-baseline.json +4 -0
- package/scripts/build-hooks.js +9 -0
- package/scripts/changeset/lint.cjs +68 -6
- package/scripts/changeset/serialize.cjs +5 -1
- package/scripts/check-alias-drift.cjs +7 -43
- package/scripts/check-contract-drift.cjs +297 -0
- package/scripts/ci-test-scope.cjs +19 -2
- package/scripts/command-contract-helpers.cjs +903 -1
- package/scripts/gen-adr-index.cjs +728 -38
- package/scripts/gen-capability-matrix.cjs +1 -1
- package/scripts/gen-capability-registry.cjs +3 -15
- package/scripts/gen-context-index.cjs +439 -0
- package/scripts/gen-health-docs.cjs +390 -0
- package/scripts/gen-inventory-manifest.cjs +150 -4
- package/scripts/gen-loop-host-contract.cjs +4 -24
- package/scripts/gen-prompt-budget-parity-corpus.cjs +645 -0
- package/scripts/gen-registry.cjs +3 -14
- package/scripts/gen-section-manifest.cjs +638 -0
- package/scripts/generate-package-identity.cjs +4 -2
- package/scripts/lib/alias-drift-families.cjs +46 -0
- package/scripts/lib/drift-scan.cjs +278 -0
- package/scripts/lint-allow-test-rule-refs.allowlist.json +15 -54
- package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +4 -0
- package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +3 -0
- package/scripts/lint-canary-version-leak.cjs +73 -0
- package/scripts/lint-command-contract.cjs +96 -13
- package/scripts/lint-compiled-artifact-sync.cjs +6 -1
- package/scripts/lint-completion-predicate-drift.cjs +933 -0
- package/scripts/lint-completion-ratio-drift.cjs +214 -0
- package/scripts/lint-default-flip-documentation.cjs +193 -0
- package/scripts/lint-docs-command-form.cjs +195 -0
- package/scripts/lint-docs-required.cjs +9 -1
- package/scripts/lint-emitted-drift-ack.cjs +215 -20
- package/scripts/lint-eslint-glob-coverage.allowlist.json +34 -0
- package/scripts/lint-eslint-glob-coverage.cjs +340 -0
- package/scripts/lint-example-parser-parity.cjs +395 -0
- package/scripts/lint-frontmatter-scalar-broad-grep.cjs +237 -0
- package/scripts/lint-health-diagnostic-rule-table.cjs +404 -0
- package/scripts/lint-hooks-runtime-build-seam.cjs +262 -0
- package/scripts/lint-milestone-window-drift.cjs +468 -0
- package/scripts/lint-phase-enumeration-drift.cjs +479 -0
- package/scripts/lint-plan-count-drift.cjs +318 -0
- package/scripts/lint-planning-artifact-writer-drift.cjs +398 -0
- package/scripts/lint-planning-prompt-drift.cjs +434 -0
- package/scripts/lint-planning-snapshot-bypass-drift.cjs +544 -0
- package/scripts/lint-regression-test-names.cjs +15 -13
- package/scripts/lint-removed-but-needed.cjs +320 -0
- package/scripts/lint-state-field-drift.cjs +805 -0
- package/scripts/lint-state-write-path-drift.cjs +1045 -0
- package/scripts/lint-test-file-count.allowlist.json +40 -3
- package/scripts/lint-unreachable-guard-drift.cjs +843 -0
- package/scripts/lint-vendored-deps.cjs +124 -0
- package/scripts/mutation-matrix.cjs +13 -0
- package/scripts/pr-changed-files.cjs +63 -0
- package/scripts/pr-template-policy.cjs +14 -4
- package/scripts/prompt-injection-scan.sh +52 -6
- package/scripts/require-issue-link-policy.cjs +192 -0
- package/scripts/state-write-path-drift-baseline.json +19 -0
- package/scripts/sync-runtime-launcher.cjs +2 -4
- package/skills/gsd-autonomous/SKILL.md +0 -1
- package/skills/gsd-code-review/SKILL.md +1 -1
- package/skills/gsd-execute-phase/SKILL.md +1 -2
- package/skills/gsd-map-codebase/SKILL.md +1 -1
- package/skills/gsd-mempalace-capture/SKILL.md +2 -2
- package/skills/gsd-mempalace-recall/SKILL.md +1 -1
- package/skills/gsd-new-milestone/SKILL.md +2 -2
- package/skills/gsd-next/SKILL.md +0 -1
- package/skills/gsd-plan-phase/SKILL.md +1 -2
- package/skills/gsd-progress/SKILL.md +0 -1
- package/skills/gsd-quick/SKILL.md +1 -1
- package/skills/gsd-review-backlog/SKILL.md +2 -1
- package/skills/gsd-stats/SKILL.md +0 -1
- package/skills/gsd-verify-work/SKILL.md +1 -1
- package/vscode/package.json +1 -1
- package/gsd-core/workflows/discovery-phase.md +0 -298
- package/gsd-core/workflows/plan-milestone-gaps.md +0 -281
- package/gsd-core/workflows/verify-phase.md +0 -577
- package/scripts/affected-tests-lib.cjs +0 -554
- package/scripts/gen-emitted-baseline.cjs +0 -145
- package/scripts/lint-allow-test-rule-refs.cjs +0 -162
- package/scripts/run-affected-tests.cjs +0 -7
- package/scripts/run-tests.cjs +0 -1050
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* lint-eslint-glob-coverage.cjs — ESLint `files:` glob coverage drift guard (#3059).
|
|
6
|
+
*
|
|
7
|
+
* ## What this enforces
|
|
8
|
+
*
|
|
9
|
+
* `eslint.config.mjs` is a flat config: a tracked source file is only linted
|
|
10
|
+
* if it matches at least one config object's `files:` glob (or a global,
|
|
11
|
+
* files-less block). A file matching NO glob resolves to zero reachable
|
|
12
|
+
* rules and `eslint .` silently exits 0 on it — the #3059 defect class (62
|
|
13
|
+
* tracked source files found with this shape). This guard walks every
|
|
14
|
+
* tracked `.cjs/.cts/.js/.mjs` source file, resolves its real ESLint config,
|
|
15
|
+
* and fails when a file resolves to zero rules and isn't a deliberately
|
|
16
|
+
* exempted, reasoned allowlist entry.
|
|
17
|
+
*
|
|
18
|
+
* This checks rule REACHABILITY (does at least one rule apply to this file
|
|
19
|
+
* at all, any severity), not rule SEVERITY (whether an applicable rule is
|
|
20
|
+
* `error` vs `warn` vs `off`) — severity coverage is a separate gate, #1885
|
|
21
|
+
* F17. A file with one `off` rule reachable still counts as "covered" here:
|
|
22
|
+
* it proves the file was deliberately targeted by a `files:` glob, which is
|
|
23
|
+
* the thing #3059 is about.
|
|
24
|
+
*
|
|
25
|
+
* ## Goodhart rationale
|
|
26
|
+
*
|
|
27
|
+
* A coverage metric is trivially gameable by padding the allowlist instead
|
|
28
|
+
* of fixing the glob, so every knob here is built to resist that:
|
|
29
|
+
* - Every allowlist entry MUST carry a non-empty `reason` — an unreasoned
|
|
30
|
+
* entry is indistinguishable from "quietly made the metric look better".
|
|
31
|
+
* - The allowlist only ratchets DOWN: an entry whose path now resolves to
|
|
32
|
+
* >=1 rule (`allowlist_stale`) is a failure, forcing prompt removal
|
|
33
|
+
* rather than letting stale exemptions accumulate as free cover for
|
|
34
|
+
* future accidental escapes at the same path.
|
|
35
|
+
* - A tracked-file-count floor (`tracked_count_below_floor`) exists so a
|
|
36
|
+
* broken or empty `git ls-files` (e.g. wrong cwd, detached worktree)
|
|
37
|
+
* can't report a vacuous "0 escapes out of 0 checked" clean run.
|
|
38
|
+
*
|
|
39
|
+
* ## Ignored vs. unmatched (the discrimination this script makes)
|
|
40
|
+
*
|
|
41
|
+
* ESLint's `ignores:` blocks are the one legitimate "this file is not meant
|
|
42
|
+
* to be linted" decision (e.g. the ADR-457 tsc-emitted `.cjs` artifacts
|
|
43
|
+
* under `gsd-core/bin/lib/`) and must NOT be reported as uncovered. But
|
|
44
|
+
* `ESLint#isPathIgnored` cannot be trusted uniformly across extensions:
|
|
45
|
+
* for ESLint's default-lintable extensions (`.js`/`.mjs`/`.cjs`), it
|
|
46
|
+
* reports `true` only when the path matches an explicit `ignores:` glob —
|
|
47
|
+
* verified empirically: an unmatched top-level `.cjs` probe file reports
|
|
48
|
+
* `isPathIgnored() === false` with an empty resolved rule set, not `true`.
|
|
49
|
+
* For `.cts` (and any other non-default extension), flat config requires an
|
|
50
|
+
* EXPLICIT `files:` glob match to be linted at all; a `.cts` file matching
|
|
51
|
+
* no `files:` glob ALSO reports `isPathIgnored() === true` — indistinguishable,
|
|
52
|
+
* via this API, from a genuine `ignores:` entry (verified with a scratch
|
|
53
|
+
* `.cts` fixture under `tests/fixtures/`). This repo's `ignores:` list never
|
|
54
|
+
* contains a `.cts` path (ADR-457 retires only the emitted `.cjs`; the
|
|
55
|
+
* `.cts` source is always meant to stay linted), so for `.cts` specifically
|
|
56
|
+
* an `isPathIgnored() === true` verdict can only mean "matches no `files:`
|
|
57
|
+
* glob" and is therefore treated as UNCOVERED, not ignored. See
|
|
58
|
+
* `resolveFileCoverage` below.
|
|
59
|
+
*
|
|
60
|
+
* ## Why `bin/install.js` is NOT in the allowlist
|
|
61
|
+
*
|
|
62
|
+
* The allowlist below is exclusively for files that resolve to ZERO rules —
|
|
63
|
+
* it is a registry of accepted escapes, not a general-purpose "reasons for
|
|
64
|
+
* how a file is configured" log. The `bin/install.js` / `bin/gsd-mcp-server.js`
|
|
65
|
+
* / `scripts/build-hooks.js` family is deliberately covered by a minimal,
|
|
66
|
+
* 2-rule block in `eslint.config.mjs` per ADR-1703 (targeting only the
|
|
67
|
+
* portability defect surface, not a full style sweep of ~12k lines of
|
|
68
|
+
* generated code) — see the comment at that block in `eslint.config.mjs`.
|
|
69
|
+
* Because 2 rules is non-empty, that family already passes this guard
|
|
70
|
+
* without needing an allowlist entry, and adding one anyway would itself be
|
|
71
|
+
* flagged `allowlist_stale` (see the ratchet above). The allowlist exemption
|
|
72
|
+
* surface deliberately cannot be used to re-state a decision that is already
|
|
73
|
+
* recorded in the config; #3059 is the guard, ADR-1703 is the decision.
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
const fs = require('fs');
|
|
77
|
+
const path = require('path');
|
|
78
|
+
|
|
79
|
+
const ROOT = path.join(__dirname, '..');
|
|
80
|
+
const ALLOWLIST_PATH = path.join(__dirname, 'lint-eslint-glob-coverage.allowlist.json');
|
|
81
|
+
|
|
82
|
+
const SOURCE_EXT_RE = /\.(cjs|cts|js|mjs)$/;
|
|
83
|
+
|
|
84
|
+
// ESLint's flat-config default-lintable extensions: a file with one of these
|
|
85
|
+
// extensions that matches no `files:` glob still reports `isPathIgnored()
|
|
86
|
+
// === false` (with an empty resolved rule set) — so for these extensions,
|
|
87
|
+
// `isPathIgnored() === true` reliably means an explicit `ignores:` match.
|
|
88
|
+
const DEFAULT_LINTABLE_EXT_RE = /\.(js|mjs|cjs)$/;
|
|
89
|
+
|
|
90
|
+
const MIN_TRACKED_SOURCE_FILES = 500;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Runs `git ls-files` and returns the tracked source files (repo-relative,
|
|
94
|
+
* POSIX-normalized, filtered to SOURCE_EXT_RE). Never throws: a git failure
|
|
95
|
+
* (non-zero exit or timeout) produces a degraded `{ ok: false }` result so
|
|
96
|
+
* callers can turn it into a `git_failed` violation instead of crashing.
|
|
97
|
+
*
|
|
98
|
+
* @param {object} [opts]
|
|
99
|
+
* @param {Function} [opts.execFile] - injectable sync exec function with the
|
|
100
|
+
* `execFileSync(cmd, args, options)` signature; defaults to
|
|
101
|
+
* `child_process.execFileSync`.
|
|
102
|
+
*/
|
|
103
|
+
function listTrackedSourceFiles({ execFile } = {}) {
|
|
104
|
+
const run = execFile || require('child_process').execFileSync;
|
|
105
|
+
let stdout;
|
|
106
|
+
try {
|
|
107
|
+
// The test runner and CI execute inside a container where this repo is
|
|
108
|
+
// owned by a different UID than the running user; bare `git ls-files`
|
|
109
|
+
// then refuses with "detected dubious ownership" unless the path is in
|
|
110
|
+
// `safe.directory`, and this guard degrades to a `git_failed` violation
|
|
111
|
+
// — exactly where it must run to be a useful gate (#3059). `-c
|
|
112
|
+
// safe.directory=*` scopes the override to THIS invocation only (it
|
|
113
|
+
// never writes to any config file, global or local), and the wildcard
|
|
114
|
+
// is fine here because this command only ever enumerates tracked paths
|
|
115
|
+
// in the repo the guard is already executing inside.
|
|
116
|
+
stdout = run('git', ['-c', 'safe.directory=*', 'ls-files'], {
|
|
117
|
+
cwd: ROOT,
|
|
118
|
+
encoding: 'utf8',
|
|
119
|
+
// 30s — `git ls-files` on this tree returns ~1175 paths in <1s; 30s is
|
|
120
|
+
// the CLAUDE.md git ceiling, generous for a cold index.
|
|
121
|
+
timeout: 30000,
|
|
122
|
+
});
|
|
123
|
+
} catch (err) {
|
|
124
|
+
return { ok: false, files: [], error: (err && err.message) || String(err) };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const files = String(stdout)
|
|
128
|
+
// CRLF-safe: `git ls-files` output may carry \r\n on a Windows checkout
|
|
129
|
+
// or a git config with core.autocrlf set (DEFECT.CRLF class).
|
|
130
|
+
.split(/\r?\n/)
|
|
131
|
+
.filter((line) => line.length > 0)
|
|
132
|
+
// Unconditional backslash normalization (never path.sep-gated): the
|
|
133
|
+
// guard's own process may run on any platform regardless of what
|
|
134
|
+
// produced the tracked-file listing.
|
|
135
|
+
.map((line) => line.replace(/\\/g, '/'))
|
|
136
|
+
.filter((line) => SOURCE_EXT_RE.test(line));
|
|
137
|
+
|
|
138
|
+
return { ok: true, files };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Loads and parses the allowlist JSON file. */
|
|
142
|
+
function loadAllowlist() {
|
|
143
|
+
const raw = fs.readFileSync(ALLOWLIST_PATH, 'utf8');
|
|
144
|
+
return JSON.parse(raw);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Resolves the ESLint coverage verdict for a single tracked file. See the
|
|
149
|
+
* "Ignored vs. unmatched" header section for the extension-dependent
|
|
150
|
+
* discrimination rationale.
|
|
151
|
+
*
|
|
152
|
+
* @param {import('eslint').ESLint} eslint
|
|
153
|
+
* @param {string} relPath - repo-relative POSIX path
|
|
154
|
+
* @returns {Promise<{ ignored: boolean, ruleCount: number }>}
|
|
155
|
+
*/
|
|
156
|
+
async function resolveFileCoverage(eslint, relPath) {
|
|
157
|
+
const absPath = path.join(ROOT, relPath);
|
|
158
|
+
const ignored = await eslint.isPathIgnored(absPath);
|
|
159
|
+
|
|
160
|
+
if (ignored) {
|
|
161
|
+
if (DEFAULT_LINTABLE_EXT_RE.test(relPath)) {
|
|
162
|
+
// .js/.mjs/.cjs: isPathIgnored() only reports true for an explicit
|
|
163
|
+
// `ignores:` glob match — a recorded decision.
|
|
164
|
+
return { ignored: true, ruleCount: 0 };
|
|
165
|
+
}
|
|
166
|
+
// .cts (or any non-default extension): isPathIgnored() can't
|
|
167
|
+
// distinguish "explicit ignores: match" from "no files: glob matched
|
|
168
|
+
// it at all" — and this repo's ignores: list never targets .cts, so
|
|
169
|
+
// treat it as the latter (uncovered), never as ignored.
|
|
170
|
+
return { ignored: false, ruleCount: 0 };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const config = await eslint.calculateConfigForFile(absPath);
|
|
174
|
+
const ruleCount = config && config.rules ? Object.keys(config.rules).length : 0;
|
|
175
|
+
return { ignored: false, ruleCount };
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Builds the default real-ESLint-backed resolveConfig function. */
|
|
179
|
+
function createDefaultResolveConfig() {
|
|
180
|
+
const { ESLint } = require('eslint');
|
|
181
|
+
const eslint = new ESLint({ cwd: ROOT });
|
|
182
|
+
return (relPath) => resolveFileCoverage(eslint, relPath);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* The pure coverage predicate. All I/O is injectable via `deps` so tests
|
|
187
|
+
* never need a temp repo, a real subprocess, or a real ESLint instance:
|
|
188
|
+
*
|
|
189
|
+
* @param {object} [deps]
|
|
190
|
+
* @param {string[] | { ok: boolean, files?: string[], error?: string }} [deps.trackedFiles]
|
|
191
|
+
* Either a plain array of tracked source paths (success shorthand), or a
|
|
192
|
+
* `listTrackedSourceFiles()`-shaped result object (so a git failure can be
|
|
193
|
+
* injected directly). Defaults to a real `listTrackedSourceFiles()` call.
|
|
194
|
+
* @param {(relPath: string) => Promise<{ignored:boolean,ruleCount:number}> | {ignored:boolean,ruleCount:number}} [deps.resolveConfig]
|
|
195
|
+
* Per-file coverage resolver. Defaults to a real ESLint instance.
|
|
196
|
+
* @param {Array<{path:string,reason?:string}>} [deps.allowlist] - defaults to
|
|
197
|
+
* the real `loadAllowlist()`.
|
|
198
|
+
* @param {number} [deps.minTrackedFiles] - defaults to MIN_TRACKED_SOURCE_FILES.
|
|
199
|
+
* @returns {Promise<{ ok: boolean, escapes: Array<{path:string}>, violations: Array<{kind:string,path:string|null,detail:string}>, checked: number }>}
|
|
200
|
+
*/
|
|
201
|
+
async function checkGlobCoverage(deps = {}) {
|
|
202
|
+
const minTrackedFiles =
|
|
203
|
+
typeof deps.minTrackedFiles === 'number' ? deps.minTrackedFiles : MIN_TRACKED_SOURCE_FILES;
|
|
204
|
+
|
|
205
|
+
const violations = [];
|
|
206
|
+
|
|
207
|
+
let trackedResult;
|
|
208
|
+
if (deps.trackedFiles === undefined) {
|
|
209
|
+
trackedResult = listTrackedSourceFiles();
|
|
210
|
+
} else if (Array.isArray(deps.trackedFiles)) {
|
|
211
|
+
trackedResult = { ok: true, files: deps.trackedFiles };
|
|
212
|
+
} else {
|
|
213
|
+
trackedResult = deps.trackedFiles;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (!trackedResult.ok) {
|
|
217
|
+
violations.push({
|
|
218
|
+
kind: 'git_failed',
|
|
219
|
+
path: null,
|
|
220
|
+
detail: trackedResult.error || 'listTrackedSourceFiles() failed',
|
|
221
|
+
});
|
|
222
|
+
return { ok: false, escapes: [], violations, checked: 0 };
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const trackedFiles = trackedResult.files;
|
|
226
|
+
|
|
227
|
+
if (trackedFiles.length < minTrackedFiles) {
|
|
228
|
+
violations.push({
|
|
229
|
+
kind: 'tracked_count_below_floor',
|
|
230
|
+
path: null,
|
|
231
|
+
detail: `tracked source file count ${trackedFiles.length} is below the floor of ${minTrackedFiles} — a broken or empty git ls-files must never report a vacuous clean run`,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const trackedSet = new Set(trackedFiles);
|
|
236
|
+
const allowlist = deps.allowlist === undefined ? loadAllowlist() : deps.allowlist;
|
|
237
|
+
|
|
238
|
+
const seenAllowlistPaths = new Set();
|
|
239
|
+
const allowlistPathSet = new Set();
|
|
240
|
+
for (const entry of allowlist) {
|
|
241
|
+
const entryPath = entry && entry.path;
|
|
242
|
+
|
|
243
|
+
if (seenAllowlistPaths.has(entryPath)) {
|
|
244
|
+
violations.push({
|
|
245
|
+
kind: 'allowlist_duplicate',
|
|
246
|
+
path: entryPath,
|
|
247
|
+
detail: 'path appears more than once in the allowlist',
|
|
248
|
+
});
|
|
249
|
+
} else {
|
|
250
|
+
seenAllowlistPaths.add(entryPath);
|
|
251
|
+
}
|
|
252
|
+
allowlistPathSet.add(entryPath);
|
|
253
|
+
|
|
254
|
+
if (!Object.prototype.hasOwnProperty.call(entry, 'reason')) {
|
|
255
|
+
violations.push({
|
|
256
|
+
kind: 'allowlist_missing_reason',
|
|
257
|
+
path: entryPath,
|
|
258
|
+
detail: 'allowlist entry is missing a "reason" key',
|
|
259
|
+
});
|
|
260
|
+
} else if (typeof entry.reason !== 'string' || entry.reason.trim() === '') {
|
|
261
|
+
violations.push({
|
|
262
|
+
kind: 'allowlist_empty_reason',
|
|
263
|
+
path: entryPath,
|
|
264
|
+
detail: 'allowlist entry "reason" is empty or whitespace-only',
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (!trackedSet.has(entryPath)) {
|
|
269
|
+
violations.push({
|
|
270
|
+
kind: 'allowlist_missing_path',
|
|
271
|
+
path: entryPath,
|
|
272
|
+
detail: 'allowlisted path is not a tracked source file',
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const resolveConfig = deps.resolveConfig || createDefaultResolveConfig();
|
|
278
|
+
|
|
279
|
+
const escapes = [];
|
|
280
|
+
let checked = 0;
|
|
281
|
+
|
|
282
|
+
for (const file of trackedFiles) {
|
|
283
|
+
checked += 1;
|
|
284
|
+
const result = await resolveConfig(file);
|
|
285
|
+
const isAllowlisted = allowlistPathSet.has(file);
|
|
286
|
+
|
|
287
|
+
if (result.ignored) {
|
|
288
|
+
// A recorded ESLint `ignores:` decision — never an escape, regardless
|
|
289
|
+
// of allowlist membership.
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (result.ruleCount === 0) {
|
|
294
|
+
if (isAllowlisted) continue;
|
|
295
|
+
escapes.push({ path: file });
|
|
296
|
+
violations.push({
|
|
297
|
+
kind: 'uncovered',
|
|
298
|
+
path: file,
|
|
299
|
+
detail: 'resolves to 0 reachable ESLint rules and is not allowlisted',
|
|
300
|
+
});
|
|
301
|
+
} else if (isAllowlisted) {
|
|
302
|
+
violations.push({
|
|
303
|
+
kind: 'allowlist_stale',
|
|
304
|
+
path: file,
|
|
305
|
+
detail: 'allowlisted path now resolves to >=1 ESLint rule — prune the entry, the allowlist only ratchets down',
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return { ok: violations.length === 0, escapes, violations, checked };
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (require.main === module) {
|
|
314
|
+
checkGlobCoverage()
|
|
315
|
+
.then((result) => {
|
|
316
|
+
if (result.violations.length > 0) {
|
|
317
|
+
console.error(
|
|
318
|
+
`lint-eslint-glob-coverage: ${result.violations.length} violation(s) across ${result.checked} tracked source file(s) (${result.escapes.length} uncovered escape(s))`
|
|
319
|
+
);
|
|
320
|
+
for (const v of result.violations) {
|
|
321
|
+
console.error(` [${v.kind}] ${v.path === null ? '(n/a)' : v.path}${v.detail ? ' — ' + v.detail : ''}`);
|
|
322
|
+
}
|
|
323
|
+
process.exitCode = 1;
|
|
324
|
+
} else {
|
|
325
|
+
console.log(`ok lint-eslint-glob-coverage: ${result.checked} tracked source file(s), 0 escapes`);
|
|
326
|
+
}
|
|
327
|
+
})
|
|
328
|
+
.catch((err) => {
|
|
329
|
+
console.error(err && err.stack ? err.stack : String(err));
|
|
330
|
+
process.exitCode = 1;
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
module.exports = {
|
|
335
|
+
checkGlobCoverage,
|
|
336
|
+
listTrackedSourceFiles,
|
|
337
|
+
loadAllowlist,
|
|
338
|
+
SOURCE_EXT_RE,
|
|
339
|
+
MIN_TRACKED_SOURCE_FILES,
|
|
340
|
+
};
|