@shrkcrft/cli 0.1.0-alpha.30 → 0.1.0-alpha.31
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/dist/asset-preview/apply-asset-preview.js +1 -1
- package/dist/authoring/authoring-kit.d.ts +9 -1
- package/dist/authoring/authoring-kit.d.ts.map +1 -1
- package/dist/authoring/authoring-kit.js +26 -13
- package/dist/bootstrap/unlinked-workspace-dependency.d.ts +11 -0
- package/dist/bootstrap/unlinked-workspace-dependency.d.ts.map +1 -0
- package/dist/bootstrap/unlinked-workspace-dependency.js +99 -0
- package/dist/command-registry.d.ts +100 -1
- package/dist/command-registry.d.ts.map +1 -1
- package/dist/command-registry.js +130 -3
- package/dist/commands/api-diff.command.d.ts.map +1 -1
- package/dist/commands/api-diff.command.js +12 -0
- package/dist/commands/apply.command.d.ts.map +1 -1
- package/dist/commands/apply.command.js +3 -0
- package/dist/commands/arch.command.d.ts.map +1 -1
- package/dist/commands/arch.command.js +26 -7
- package/dist/commands/architecture.command.d.ts.map +1 -1
- package/dist/commands/architecture.command.js +8 -2
- package/dist/commands/baseline.command.d.ts +54 -3
- package/dist/commands/baseline.command.d.ts.map +1 -1
- package/dist/commands/baseline.command.js +582 -74
- package/dist/commands/biome.command.d.ts.map +1 -1
- package/dist/commands/biome.command.js +20 -0
- package/dist/commands/boundaries.command.d.ts +9 -1
- package/dist/commands/boundaries.command.d.ts.map +1 -1
- package/dist/commands/boundaries.command.js +88 -20
- package/dist/commands/bundle.command.d.ts.map +1 -1
- package/dist/commands/bundle.command.js +57 -11
- package/dist/commands/cache-align.command.d.ts.map +1 -1
- package/dist/commands/cache-align.command.js +3 -1
- package/dist/commands/changelog-data.d.ts.map +1 -1
- package/dist/commands/changelog-data.js +138 -0
- package/dist/commands/changes.command.d.ts.map +1 -1
- package/dist/commands/changes.command.js +15 -0
- package/dist/commands/check.command.d.ts.map +1 -1
- package/dist/commands/check.command.js +1241 -322
- package/dist/commands/checks.command.d.ts.map +1 -1
- package/dist/commands/checks.command.js +188 -40
- package/dist/commands/ci.command.d.ts.map +1 -1
- package/dist/commands/ci.command.js +35 -2
- package/dist/commands/code-intel.command.d.ts.map +1 -1
- package/dist/commands/code-intel.command.js +3 -0
- package/dist/commands/command-catalog.d.ts +23 -1
- package/dist/commands/command-catalog.d.ts.map +1 -1
- package/dist/commands/command-catalog.js +152 -35
- package/dist/commands/commands.command.d.ts +21 -3
- package/dist/commands/commands.command.d.ts.map +1 -1
- package/dist/commands/commands.command.js +172 -27
- package/dist/commands/compress.command.d.ts.map +1 -1
- package/dist/commands/compress.command.js +4 -0
- package/dist/commands/constructs.command.d.ts.map +1 -1
- package/dist/commands/constructs.command.js +50 -12
- package/dist/commands/context.command.d.ts.map +1 -1
- package/dist/commands/context.command.js +40 -5
- package/dist/commands/contract-templates.command.d.ts.map +1 -1
- package/dist/commands/contract-templates.command.js +9 -1
- package/dist/commands/contract.command.d.ts.map +1 -1
- package/dist/commands/contract.command.js +35 -0
- package/dist/commands/conventions.command.d.ts.map +1 -1
- package/dist/commands/conventions.command.js +189 -29
- package/dist/commands/coverage.command.d.ts.map +1 -1
- package/dist/commands/coverage.command.js +9 -0
- package/dist/commands/daily.commands.d.ts +0 -1
- package/dist/commands/daily.commands.d.ts.map +1 -1
- package/dist/commands/daily.commands.js +12 -76
- package/dist/commands/dashboard.command.d.ts.map +1 -1
- package/dist/commands/dashboard.command.js +10 -0
- package/dist/commands/dev.command.d.ts.map +1 -1
- package/dist/commands/dev.command.js +45 -2
- package/dist/commands/diagnostics.command.d.ts +0 -2
- package/dist/commands/diagnostics.command.d.ts.map +1 -1
- package/dist/commands/diagnostics.command.js +5 -78
- package/dist/commands/diff-check.command.d.ts +6 -4
- package/dist/commands/diff-check.command.d.ts.map +1 -1
- package/dist/commands/diff-check.command.js +190 -103
- package/dist/commands/docs-references.command.d.ts +13 -0
- package/dist/commands/docs-references.command.d.ts.map +1 -1
- package/dist/commands/docs-references.command.js +269 -72
- package/dist/commands/doctor.command.d.ts.map +1 -1
- package/dist/commands/doctor.command.js +58 -4
- package/dist/commands/drift.command.d.ts.map +1 -1
- package/dist/commands/drift.command.js +17 -4
- package/dist/commands/eslint.command.d.ts.map +1 -1
- package/dist/commands/eslint.command.js +20 -0
- package/dist/commands/export.command.d.ts.map +1 -1
- package/dist/commands/export.command.js +23 -1
- package/dist/commands/feedback-dispatch.command.d.ts.map +1 -1
- package/dist/commands/feedback-dispatch.command.js +29 -0
- package/dist/commands/feedback.command.d.ts.map +1 -1
- package/dist/commands/feedback.command.js +6 -1
- package/dist/commands/finish.command.d.ts.map +1 -1
- package/dist/commands/finish.command.js +32 -8
- package/dist/commands/fix.command.d.ts.map +1 -1
- package/dist/commands/fix.command.js +19 -0
- package/dist/commands/gate.command.d.ts +6 -1
- package/dist/commands/gate.command.d.ts.map +1 -1
- package/dist/commands/gate.command.js +50 -124
- package/dist/commands/gates.command.d.ts +52 -0
- package/dist/commands/gates.command.d.ts.map +1 -1
- package/dist/commands/gates.command.js +811 -185
- package/dist/commands/gen.command.d.ts.map +1 -1
- package/dist/commands/gen.command.js +4 -0
- package/dist/commands/generated.command.d.ts +33 -3
- package/dist/commands/generated.command.d.ts.map +1 -1
- package/dist/commands/generated.command.js +499 -147
- package/dist/commands/graph-code-subverbs.d.ts +15 -0
- package/dist/commands/graph-code-subverbs.d.ts.map +1 -1
- package/dist/commands/graph-code-subverbs.js +198 -24
- package/dist/commands/graph.command.d.ts.map +1 -1
- package/dist/commands/graph.command.js +79 -37
- package/dist/commands/help.command.d.ts +30 -6
- package/dist/commands/help.command.d.ts.map +1 -1
- package/dist/commands/help.command.js +323 -199
- package/dist/commands/helper.command.d.ts +1 -0
- package/dist/commands/helper.command.d.ts.map +1 -1
- package/dist/commands/helper.command.js +195 -56
- package/dist/commands/impact.command.d.ts.map +1 -1
- package/dist/commands/impact.command.js +115 -12
- package/dist/commands/infer.command.d.ts.map +1 -1
- package/dist/commands/infer.command.js +20 -45
- package/dist/commands/ingest.command.d.ts +0 -1
- package/dist/commands/ingest.command.d.ts.map +1 -1
- package/dist/commands/ingest.command.js +25 -41
- package/dist/commands/knowledge-author.command.d.ts +0 -3
- package/dist/commands/knowledge-author.command.d.ts.map +1 -1
- package/dist/commands/knowledge-author.command.js +10 -23
- package/dist/commands/knowledge.command.d.ts.map +1 -1
- package/dist/commands/knowledge.command.js +469 -129
- package/dist/commands/languages.command.d.ts.map +1 -1
- package/dist/commands/languages.command.js +27 -0
- package/dist/commands/lint.command.d.ts.map +1 -1
- package/dist/commands/lint.command.js +3 -0
- package/dist/commands/mcp.command.d.ts +18 -0
- package/dist/commands/mcp.command.d.ts.map +1 -1
- package/dist/commands/mcp.command.js +33 -8
- package/dist/commands/onboard.command.d.ts.map +1 -1
- package/dist/commands/onboard.command.js +20 -0
- package/dist/commands/owners.command.d.ts.map +1 -1
- package/dist/commands/owners.command.js +14 -2
- package/dist/commands/packs-new.d.ts +13 -1
- package/dist/commands/packs-new.d.ts.map +1 -1
- package/dist/commands/packs-new.js +500 -335
- package/dist/commands/packs.command.d.ts.map +1 -1
- package/dist/commands/packs.command.js +378 -36
- package/dist/commands/paths.command.d.ts.map +1 -1
- package/dist/commands/paths.command.js +9 -1
- package/dist/commands/pipelines.command.d.ts.map +1 -1
- package/dist/commands/pipelines.command.js +7 -1
- package/dist/commands/plan-check.command.d.ts.map +1 -1
- package/dist/commands/plan-check.command.js +3 -0
- package/dist/commands/plan.command.d.ts.map +1 -1
- package/dist/commands/plan.command.js +3 -0
- package/dist/commands/playbooks.command.d.ts.map +1 -1
- package/dist/commands/playbooks.command.js +7 -2
- package/dist/commands/policy-lint.command.d.ts +19 -2
- package/dist/commands/policy-lint.command.d.ts.map +1 -1
- package/dist/commands/policy-lint.command.js +224 -65
- package/dist/commands/policy.command.d.ts.map +1 -1
- package/dist/commands/policy.command.js +6 -1
- package/dist/commands/pr.command.d.ts.map +1 -1
- package/dist/commands/pr.command.js +14 -0
- package/dist/commands/presets.command.d.ts.map +1 -1
- package/dist/commands/presets.command.js +12 -27
- package/dist/commands/profiles.command.d.ts.map +1 -1
- package/dist/commands/profiles.command.js +94 -26
- package/dist/commands/provenance.command.js +1 -1
- package/dist/commands/quality.command.d.ts.map +1 -1
- package/dist/commands/quality.command.js +129 -33
- package/dist/commands/recommend.command.d.ts +20 -4
- package/dist/commands/recommend.command.d.ts.map +1 -1
- package/dist/commands/recommend.command.js +172 -278
- package/dist/commands/registrations.command.d.ts.map +1 -1
- package/dist/commands/registrations.command.js +138 -13
- package/dist/commands/registry-lifecycle-run.d.ts +14 -0
- package/dist/commands/registry-lifecycle-run.d.ts.map +1 -0
- package/dist/commands/registry-lifecycle-run.js +336 -0
- package/dist/commands/registry.command.d.ts.map +1 -1
- package/dist/commands/registry.command.js +235 -62
- package/dist/commands/release.command.d.ts.map +1 -1
- package/dist/commands/release.command.js +99 -20
- package/dist/commands/report.command.d.ts.map +1 -1
- package/dist/commands/report.command.js +38 -2
- package/dist/commands/reuse-coverage.command.d.ts +23 -0
- package/dist/commands/reuse-coverage.command.d.ts.map +1 -0
- package/dist/commands/reuse-coverage.command.js +536 -0
- package/dist/commands/reuse.command.d.ts +3 -18
- package/dist/commands/reuse.command.d.ts.map +1 -1
- package/dist/commands/reuse.command.js +395 -244
- package/dist/commands/review.command.d.ts.map +1 -1
- package/dist/commands/review.command.js +33 -1
- package/dist/commands/rounds.command.d.ts.map +1 -1
- package/dist/commands/rounds.command.js +5 -0
- package/dist/commands/safety.command.d.ts.map +1 -1
- package/dist/commands/safety.command.js +9 -0
- package/dist/commands/scaffolds.command.d.ts.map +1 -1
- package/dist/commands/scaffolds.command.js +97 -25
- package/dist/commands/search.command.d.ts +0 -8
- package/dist/commands/search.command.d.ts.map +1 -1
- package/dist/commands/search.command.js +136 -28
- package/dist/commands/self-config-xrefs.command.d.ts +24 -0
- package/dist/commands/self-config-xrefs.command.d.ts.map +1 -0
- package/dist/commands/self-config-xrefs.command.js +170 -0
- package/dist/commands/self-config.command.d.ts.map +1 -1
- package/dist/commands/self-config.command.js +261 -65
- package/dist/commands/smart-context.command.d.ts.map +1 -1
- package/dist/commands/smart-context.command.js +39 -3
- package/dist/commands/spec.command.d.ts.map +1 -1
- package/dist/commands/spec.command.js +3 -0
- package/dist/commands/stats.command.d.ts.map +1 -1
- package/dist/commands/stats.command.js +3 -0
- package/dist/commands/surface.command.d.ts +6 -1
- package/dist/commands/surface.command.d.ts.map +1 -1
- package/dist/commands/surface.command.js +256 -54
- package/dist/commands/task-context.command.js +1 -1
- package/dist/commands/task.command.d.ts.map +1 -1
- package/dist/commands/task.command.js +22 -1
- package/dist/commands/templates.command.d.ts +4 -0
- package/dist/commands/templates.command.d.ts.map +1 -1
- package/dist/commands/templates.command.js +109 -22
- package/dist/commands/test.command.d.ts.map +1 -1
- package/dist/commands/test.command.js +161 -33
- package/dist/commands/tests.command.d.ts.map +1 -1
- package/dist/commands/tests.command.js +29 -3
- package/dist/commands/trace.command.d.ts.map +1 -1
- package/dist/commands/trace.command.js +29 -4
- package/dist/commands/watch.command.d.ts.map +1 -1
- package/dist/commands/watch.command.js +3 -0
- package/dist/commands/why.command.d.ts.map +1 -1
- package/dist/commands/why.command.js +3 -0
- package/dist/commands/wiring.command.d.ts +18 -4
- package/dist/commands/wiring.command.d.ts.map +1 -1
- package/dist/commands/wiring.command.js +360 -73
- package/dist/dashboard/code-intelligence-data.js +4 -4
- package/dist/diff/deleted-orphan-coverage.d.ts +32 -0
- package/dist/diff/deleted-orphan-coverage.d.ts.map +1 -0
- package/dist/diff/deleted-orphan-coverage.js +107 -0
- package/dist/diff/deleted-orphan-scope-notes.d.ts +23 -0
- package/dist/diff/deleted-orphan-scope-notes.d.ts.map +1 -0
- package/dist/diff/deleted-orphan-scope-notes.js +49 -0
- package/dist/diff/deleted-orphans.d.ts +32 -0
- package/dist/diff/deleted-orphans.d.ts.map +1 -1
- package/dist/diff/deleted-orphans.js +42 -2
- package/dist/dispatch/closest-match.d.ts +15 -0
- package/dist/dispatch/closest-match.d.ts.map +1 -0
- package/dist/dispatch/closest-match.js +47 -0
- package/dist/dispatch/global-flags.d.ts +94 -0
- package/dist/dispatch/global-flags.d.ts.map +1 -0
- package/dist/dispatch/global-flags.js +123 -0
- package/dist/dispatch/guard-invocation-input.d.ts +24 -0
- package/dist/dispatch/guard-invocation-input.d.ts.map +1 -0
- package/dist/dispatch/guard-invocation-input.js +1 -0
- package/dist/dispatch/guard-invocation.d.ts +33 -0
- package/dist/dispatch/guard-invocation.d.ts.map +1 -0
- package/dist/dispatch/guard-invocation.js +183 -0
- package/dist/dispatch/help-intercept.d.ts +22 -0
- package/dist/dispatch/help-intercept.d.ts.map +1 -0
- package/dist/dispatch/help-intercept.js +42 -0
- package/dist/dispatch/i-declared-invocation.d.ts +17 -0
- package/dist/dispatch/i-declared-invocation.d.ts.map +1 -0
- package/dist/dispatch/i-declared-invocation.js +1 -0
- package/dist/dispatch/i-unknown-flag-refusal-input.d.ts +28 -0
- package/dist/dispatch/i-unknown-flag-refusal-input.d.ts.map +1 -0
- package/dist/dispatch/i-unknown-flag-refusal-input.js +1 -0
- package/dist/dispatch/invocation-rejection-kind.d.ts +15 -0
- package/dist/dispatch/invocation-rejection-kind.d.ts.map +1 -0
- package/dist/dispatch/invocation-rejection-kind.js +15 -0
- package/dist/dispatch/invocation-rejection.d.ts +18 -0
- package/dist/dispatch/invocation-rejection.d.ts.map +1 -0
- package/dist/dispatch/invocation-rejection.js +1 -0
- package/dist/dispatch/judge-invocation.d.ts +24 -0
- package/dist/dispatch/judge-invocation.d.ts.map +1 -0
- package/dist/dispatch/judge-invocation.js +50 -0
- package/dist/dispatch/positional-mode.d.ts +18 -0
- package/dist/dispatch/positional-mode.d.ts.map +1 -0
- package/dist/dispatch/positional-mode.js +18 -0
- package/dist/dispatch/read-tracking-map.d.ts +28 -0
- package/dist/dispatch/read-tracking-map.d.ts.map +1 -0
- package/dist/dispatch/read-tracking-map.js +58 -0
- package/dist/dispatch/refuse-sibling-valve-flags.d.ts +30 -0
- package/dist/dispatch/refuse-sibling-valve-flags.d.ts.map +1 -0
- package/dist/dispatch/refuse-sibling-valve-flags.js +65 -0
- package/dist/dispatch/subverb-spec.d.ts +26 -0
- package/dist/dispatch/subverb-spec.d.ts.map +1 -0
- package/dist/dispatch/subverb-spec.js +1 -0
- package/dist/dispatch/undocumented-flag-reads.d.ts +22 -0
- package/dist/dispatch/undocumented-flag-reads.d.ts.map +1 -0
- package/dist/dispatch/undocumented-flag-reads.js +283 -0
- package/dist/dispatch/unknown-flag-refusal-mode.d.ts +13 -0
- package/dist/dispatch/unknown-flag-refusal-mode.d.ts.map +1 -0
- package/dist/dispatch/unknown-flag-refusal-mode.js +13 -0
- package/dist/dispatch/unknown-flag-refusal.d.ts +22 -0
- package/dist/dispatch/unknown-flag-refusal.d.ts.map +1 -0
- package/dist/dispatch/unknown-flag-refusal.js +57 -0
- package/dist/dispatch/unread-flags.d.ts +152 -0
- package/dist/dispatch/unread-flags.d.ts.map +1 -0
- package/dist/dispatch/unread-flags.js +295 -0
- package/dist/dispatch/verdict-valve-flag.d.ts +21 -0
- package/dist/dispatch/verdict-valve-flag.d.ts.map +1 -0
- package/dist/dispatch/verdict-valve-flag.js +21 -0
- package/dist/dispatch/walk-declared-subverbs.d.ts +14 -0
- package/dist/dispatch/walk-declared-subverbs.d.ts.map +1 -0
- package/dist/dispatch/walk-declared-subverbs.js +28 -0
- package/dist/exit-codes.d.ts +41 -3
- package/dist/exit-codes.d.ts.map +1 -1
- package/dist/exit-codes.js +153 -14
- package/dist/finish/run-finish.d.ts +72 -5
- package/dist/finish/run-finish.d.ts.map +1 -1
- package/dist/finish/run-finish.js +453 -104
- package/dist/gates/accepted-empty-note.d.ts +10 -0
- package/dist/gates/accepted-empty-note.d.ts.map +1 -0
- package/dist/gates/accepted-empty-note.js +11 -0
- package/dist/gates/allow-empty.d.ts +25 -0
- package/dist/gates/allow-empty.d.ts.map +1 -0
- package/dist/gates/allow-empty.js +27 -0
- package/dist/gates/asset-doctor-failing-units.d.ts +16 -0
- package/dist/gates/asset-doctor-failing-units.d.ts.map +1 -0
- package/dist/gates/asset-doctor-failing-units.js +14 -0
- package/dist/gates/asset-doctor-failure-line.d.ts +16 -0
- package/dist/gates/asset-doctor-failure-line.d.ts.map +1 -0
- package/dist/gates/asset-doctor-failure-line.js +28 -0
- package/dist/gates/empty-rule-advice-lines.d.ts +15 -0
- package/dist/gates/empty-rule-advice-lines.d.ts.map +1 -0
- package/dist/gates/empty-rule-advice-lines.js +20 -0
- package/dist/gates/gate-envelope.d.ts +85 -8
- package/dist/gates/gate-envelope.d.ts.map +1 -1
- package/dist/gates/gate-envelope.js +56 -7
- package/dist/gates/gate-rule-globs.d.ts +37 -3
- package/dist/gates/gate-rule-globs.d.ts.map +1 -1
- package/dist/gates/gate-rule-globs.js +78 -40
- package/dist/gates/gate-rule-view.d.ts +17 -4
- package/dist/gates/gate-rule-view.d.ts.map +1 -1
- package/dist/gates/gate-rule-view.js +105 -90
- package/dist/gates/i-coverage-dead-glob.d.ts +19 -0
- package/dist/gates/i-coverage-dead-glob.d.ts.map +1 -0
- package/dist/gates/i-coverage-dead-glob.js +1 -0
- package/dist/gates/i-coverage-negation.d.ts +13 -0
- package/dist/gates/i-coverage-negation.d.ts.map +1 -0
- package/dist/gates/i-coverage-negation.js +1 -0
- package/dist/gates/i-registration-query-settle-input.d.ts +18 -0
- package/dist/gates/i-registration-query-settle-input.d.ts.map +1 -0
- package/dist/gates/i-registration-query-settle-input.js +1 -0
- package/dist/gates/i-unit-state-note-row.d.ts +16 -0
- package/dist/gates/i-unit-state-note-row.d.ts.map +1 -0
- package/dist/gates/i-unit-state-note-row.js +1 -0
- package/dist/gates/i-unit-state-notes.d.ts +32 -0
- package/dist/gates/i-unit-state-notes.d.ts.map +1 -0
- package/dist/gates/i-unit-state-notes.js +1 -0
- package/dist/gates/incomplete-registry-inventory.d.ts +19 -0
- package/dist/gates/incomplete-registry-inventory.d.ts.map +1 -0
- package/dist/gates/incomplete-registry-inventory.js +63 -0
- package/dist/gates/measure-registration-roles.d.ts +10 -0
- package/dist/gates/measure-registration-roles.d.ts.map +1 -0
- package/dist/gates/measure-registration-roles.js +9 -0
- package/dist/gates/plane-verdict.d.ts +14 -0
- package/dist/gates/plane-verdict.d.ts.map +1 -0
- package/dist/gates/plane-verdict.js +22 -0
- package/dist/gates/qualify-clean-for-units.d.ts +12 -0
- package/dist/gates/qualify-clean-for-units.d.ts.map +1 -0
- package/dist/gates/qualify-clean-for-units.js +18 -0
- package/dist/gates/registration-graph-verdict.d.ts +34 -0
- package/dist/gates/registration-graph-verdict.d.ts.map +1 -0
- package/dist/gates/registration-graph-verdict.js +70 -0
- package/dist/gates/registration-roles.d.ts +9 -0
- package/dist/gates/registration-roles.d.ts.map +1 -0
- package/dist/gates/registration-roles.js +1 -0
- package/dist/gates/registry-liveness.d.ts +11 -0
- package/dist/gates/registry-liveness.d.ts.map +1 -0
- package/dist/gates/registry-liveness.js +13 -0
- package/dist/gates/rule-coverage.d.ts +187 -4
- package/dist/gates/rule-coverage.d.ts.map +1 -1
- package/dist/gates/rule-coverage.js +501 -49
- package/dist/gates/run-gate-planes.d.ts +14 -0
- package/dist/gates/run-gate-planes.d.ts.map +1 -1
- package/dist/gates/run-gate-planes.js +172 -30
- package/dist/gates/scaffold-selftest.d.ts +56 -0
- package/dist/gates/scaffold-selftest.d.ts.map +1 -0
- package/dist/gates/scaffold-selftest.js +119 -0
- package/dist/gates/seam-rejected-rules.d.ts +28 -0
- package/dist/gates/seam-rejected-rules.d.ts.map +1 -0
- package/dist/gates/seam-rejected-rules.js +95 -0
- package/dist/gates/self-test-check.d.ts +29 -0
- package/dist/gates/self-test-check.d.ts.map +1 -0
- package/dist/gates/self-test-check.js +1 -0
- package/dist/gates/self-test-subject.d.ts +28 -0
- package/dist/gates/self-test-subject.d.ts.map +1 -0
- package/dist/gates/self-test-subject.js +1 -0
- package/dist/gates/self-test.d.ts +20 -0
- package/dist/gates/self-test.d.ts.map +1 -0
- package/dist/gates/self-test.js +82 -0
- package/dist/gates/settle-verdict.d.ts +14 -0
- package/dist/gates/settle-verdict.d.ts.map +1 -0
- package/dist/gates/settle-verdict.js +13 -0
- package/dist/gates/settled-verdict.d.ts +8 -0
- package/dist/gates/settled-verdict.d.ts.map +1 -0
- package/dist/gates/settled-verdict.js +1 -0
- package/dist/gates/template-registry-coverage.d.ts +18 -0
- package/dist/gates/template-registry-coverage.d.ts.map +1 -0
- package/dist/gates/template-registry-coverage.js +24 -0
- package/dist/gates/unit-state-notes.d.ts +40 -0
- package/dist/gates/unit-state-notes.d.ts.map +1 -0
- package/dist/gates/unit-state-notes.js +71 -0
- package/dist/gates/verdict-line.d.ts +18 -0
- package/dist/gates/verdict-line.d.ts.map +1 -0
- package/dist/gates/verdict-line.js +40 -0
- package/dist/graph/graph-reuse-lookup.d.ts +10 -0
- package/dist/graph/graph-reuse-lookup.d.ts.map +1 -0
- package/dist/graph/graph-reuse-lookup.js +41 -0
- package/dist/graph/index-behind-hint.d.ts +11 -0
- package/dist/graph/index-behind-hint.d.ts.map +1 -0
- package/dist/graph/index-behind-hint.js +27 -0
- package/dist/knowledge/knowledge-stale-gate-flags.d.ts +3 -0
- package/dist/knowledge/knowledge-stale-gate-flags.d.ts.map +1 -0
- package/dist/knowledge/knowledge-stale-gate-flags.js +1 -0
- package/dist/knowledge/knowledge-stale-gate-input.d.ts +3 -0
- package/dist/knowledge/knowledge-stale-gate-input.d.ts.map +1 -0
- package/dist/knowledge/knowledge-stale-gate-input.js +1 -0
- package/dist/knowledge/knowledge-stale-gate-result.d.ts +3 -0
- package/dist/knowledge/knowledge-stale-gate-result.d.ts.map +1 -0
- package/dist/knowledge/knowledge-stale-gate-result.js +1 -0
- package/dist/knowledge/knowledge-stale-gate.d.ts +10 -0
- package/dist/knowledge/knowledge-stale-gate.d.ts.map +1 -0
- package/dist/knowledge/knowledge-stale-gate.js +9 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +200 -83
- package/dist/output/failure-hints.d.ts.map +1 -1
- package/dist/output/failure-hints.js +11 -9
- package/dist/output/rejected-entries-note.d.ts +57 -0
- package/dist/output/rejected-entries-note.d.ts.map +1 -0
- package/dist/output/rejected-entries-note.js +103 -0
- package/dist/output/stdout-is-pipe.d.ts +13 -0
- package/dist/output/stdout-is-pipe.d.ts.map +1 -0
- package/dist/output/stdout-is-pipe.js +21 -0
- package/dist/packs/stale-build-warning.d.ts +11 -0
- package/dist/packs/stale-build-warning.d.ts.map +1 -0
- package/dist/packs/stale-build-warning.js +23 -0
- package/dist/quality/run-quality.d.ts +123 -0
- package/dist/quality/run-quality.d.ts.map +1 -0
- package/dist/quality/run-quality.js +442 -0
- package/dist/schemas/json-schemas.d.ts +184 -3
- package/dist/schemas/json-schemas.d.ts.map +1 -1
- package/dist/schemas/json-schemas.js +113 -2
- package/dist/shrk.d.ts +3 -0
- package/dist/shrk.d.ts.map +1 -0
- package/dist/shrk.js +30 -0
- package/dist/surface/audience-applicability.d.ts +26 -0
- package/dist/surface/audience-applicability.d.ts.map +1 -0
- package/dist/surface/audience-applicability.js +60 -0
- package/dist/surface/catalog-command-safety.d.ts +18 -0
- package/dist/surface/catalog-command-safety.d.ts.map +1 -0
- package/dist/surface/catalog-command-safety.js +62 -0
- package/dist/surface/cli-command-resolver.d.ts +21 -0
- package/dist/surface/cli-command-resolver.d.ts.map +1 -0
- package/dist/surface/cli-command-resolver.js +87 -0
- package/dist/surface/command-dispatch-kind.d.ts +20 -0
- package/dist/surface/command-dispatch-kind.d.ts.map +1 -0
- package/dist/surface/command-dispatch-kind.js +20 -0
- package/dist/surface/command-index-entry.d.ts +40 -0
- package/dist/surface/command-index-entry.d.ts.map +1 -0
- package/dist/surface/command-index-entry.js +1 -0
- package/dist/surface/command-index.d.ts +77 -0
- package/dist/surface/command-index.d.ts.map +1 -0
- package/dist/surface/command-index.js +323 -0
- package/dist/surface/i-command-index.d.ts +22 -0
- package/dist/surface/i-command-index.d.ts.map +1 -0
- package/dist/surface/i-command-index.js +1 -0
- package/dist/surface/i-command-string-context.d.ts +20 -0
- package/dist/surface/i-command-string-context.d.ts.map +1 -0
- package/dist/surface/i-command-string-context.js +1 -0
- package/dist/surface/i-surface-denial.d.ts +13 -0
- package/dist/surface/i-surface-denial.d.ts.map +1 -0
- package/dist/surface/i-surface-denial.js +1 -0
- package/dist/surface/load-surface-context.d.ts +17 -1
- package/dist/surface/load-surface-context.d.ts.map +1 -1
- package/dist/surface/load-surface-context.js +48 -10
- package/dist/surface/not-enabled-error.d.ts +38 -4
- package/dist/surface/not-enabled-error.d.ts.map +1 -1
- package/dist/surface/not-enabled-error.js +96 -6
- package/dist/surface/profiles.d.ts +7 -0
- package/dist/surface/profiles.d.ts.map +1 -1
- package/dist/surface/resolve-command-string.d.ts +10 -0
- package/dist/surface/resolve-command-string.d.ts.map +1 -0
- package/dist/surface/resolve-command-string.js +572 -0
- package/dist/surface/surface-config-writer.d.ts +7 -2
- package/dist/surface/surface-config-writer.d.ts.map +1 -1
- package/dist/surface/surface-config-writer.js +25 -6
- package/dist/surface/surface-layer.d.ts +11 -0
- package/dist/surface/surface-layer.d.ts.map +1 -0
- package/dist/surface/surface-layer.js +11 -0
- package/dist/surface/surface-refusal-reason.d.ts +16 -0
- package/dist/surface/surface-refusal-reason.d.ts.map +1 -0
- package/dist/surface/surface-refusal-reason.js +16 -0
- package/dist/surface/surface-selector.d.ts +26 -0
- package/dist/surface/surface-selector.d.ts.map +1 -0
- package/dist/surface/surface-selector.js +42 -0
- package/dist/surface/surface-summary.d.ts +61 -18
- package/dist/surface/surface-summary.d.ts.map +1 -1
- package/dist/surface/surface-summary.js +147 -60
- package/dist/surface/tier.d.ts +85 -22
- package/dist/surface/tier.d.ts.map +1 -1
- package/dist/surface/tier.js +132 -30
- package/dist/usage/usage-log.d.ts +6 -1
- package/dist/usage/usage-log.d.ts.map +1 -1
- package/dist/usage/usage-log.js +7 -2
- package/dist/validation/run-validation-loop.d.ts +9 -0
- package/dist/validation/run-validation-loop.d.ts.map +1 -1
- package/dist/validation/run-validation-loop.js +14 -11
- package/dist/validation/typecheck-emitted.d.ts +8 -9
- package/dist/validation/typecheck-emitted.d.ts.map +1 -1
- package/dist/validation/typecheck-emitted.js +17 -97
- package/package.json +34 -34
|
@@ -1,80 +1,180 @@
|
|
|
1
|
-
import { referencedExtractorIds } from '@shrkcrft/core';
|
|
2
|
-
import { inspectSource, runPolicyLint, scanGeneratedFiles, walkMatching, withFileReadCache, wiringSourceSide, } from '@shrkcrft/boundaries';
|
|
3
|
-
import { gateRuleSources } from "./gate-rule-globs.js";
|
|
1
|
+
import { referencedExtractorIds, RuleEmptiness, ruleAssertsEmptyOutput, selectorUnitFails, settleRuleEmptiness, settleUnitLiveness, unitStateLists, UnitLivenessState, } from '@shrkcrft/core';
|
|
2
|
+
import { dotDirsNamedBy, globListLivenessInput, globListSelects, inspectSource, readGlobListUnits, readScopeCoverage, readScopeHasUnread, runPolicyLint, runWiring, scanGeneratedFiles, sourceLivenessRequest, walkMatching, withFileReadCache, wiringSourceSide, } from '@shrkcrft/boundaries';
|
|
3
|
+
import { gateRuleLabeledSources, gateRuleSources } from "./gate-rule-globs.js";
|
|
4
4
|
import { checkDocReferences } from '@shrkcrft/inspector';
|
|
5
|
+
import { buildGateEnvelope } from "./gate-envelope.js";
|
|
6
|
+
import { evaluateSelfTest } from "./self-test.js";
|
|
7
|
+
import { measureRegistrationRoles } from "./measure-registration-roles.js";
|
|
8
|
+
import { baselineLivenessRequest } from "../commands/baseline.command.js";
|
|
9
|
+
import { ExitCode } from "../exit-codes.js";
|
|
5
10
|
export const GATE_COVERAGE_SCHEMA = 'sharkcraft.gate-coverage/v1';
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
return out;
|
|
11
|
+
/**
|
|
12
|
+
* Why a rule its own negations emptied matched nothing — worded into its
|
|
13
|
+
* coverage reason and its envelope `skipReason`, never the "probably stale" of
|
|
14
|
+
* a selector that matched nothing at all.
|
|
15
|
+
*/
|
|
16
|
+
const EMPTIED_BY_NEGATIONS = 'its own negations exclude every file its inclusion globs select';
|
|
17
|
+
/** Why a rule that matched nothing proves nothing, in the words every coverage row prints. */
|
|
18
|
+
const STALE_SELECTOR = 'matched nothing — the selector is probably stale';
|
|
19
|
+
/** A source inspection's read scope, when it left a matched file unread. */
|
|
20
|
+
function inspectionReadScope(insp) {
|
|
21
|
+
return insp.unread.length > 0 ? { readScope: { read: insp.filesScanned, unread: insp.unread } } : {};
|
|
22
|
+
}
|
|
23
|
+
/** How a report names one extraction source: `a/*.ts, b/*.ts (regex-capture)`. */
|
|
24
|
+
function describeSource(src) {
|
|
25
|
+
const kind = src.extract ??
|
|
26
|
+
(src.pattern !== undefined ? 'regex-capture' : src.arrayProperty !== undefined ? 'array-members' : 'extractor');
|
|
27
|
+
const files = (src.files ?? []).join(', ') || '(no files)';
|
|
28
|
+
return `${files} (${kind}${src.$use ? `, via $use:${src.$use}` : ''})`;
|
|
25
29
|
}
|
|
26
|
-
|
|
30
|
+
/** ONE rule-level glob list as the settle reads it, judged off the one reader's walk (memoised under the coverage window). */
|
|
31
|
+
function ruleList(cwd, list, globs, excludeDirs, allowDotDirs) {
|
|
32
|
+
return { list, globs, units: readGlobListUnits(cwd, globs, new Set(excludeDirs), allowDotDirs) };
|
|
33
|
+
}
|
|
34
|
+
/** The labelled-sources request of a source-reading rule (wiring, registry, registration). */
|
|
35
|
+
function sourcesRequest(cwd, view, excludeDirs) {
|
|
36
|
+
return sourceLivenessRequest(cwd, gateRuleLabeledSources(view), excludeDirs, view.id);
|
|
37
|
+
}
|
|
38
|
+
function matchWiring(cwd, view, rule, excludeDirs) {
|
|
27
39
|
const side = wiringSourceSide(rule);
|
|
40
|
+
const sideLabel = rule.chain && rule.chain.length > 0 ? 'chain[0]' : 'declared';
|
|
41
|
+
const base = {
|
|
42
|
+
unitLabel: 'ids',
|
|
43
|
+
idLabel: 'declared tokens',
|
|
44
|
+
consulted: side
|
|
45
|
+
? `wiring rule "${rule.id}" — ${sideLabel} ${describeSource(side)}`
|
|
46
|
+
: `wiring rule "${rule.id}"`,
|
|
47
|
+
liveness: sourcesRequest(cwd, view, excludeDirs),
|
|
48
|
+
primaryLists: [`${sideLabel}.files`],
|
|
49
|
+
};
|
|
28
50
|
if (!side)
|
|
29
|
-
return { filesMatched: 0, unitsMatched: 0,
|
|
51
|
+
return { ...base, filesMatched: 0, unitsMatched: 0, ids: [], error: 'rule sets no source side' };
|
|
30
52
|
const insp = inspectSource(cwd, side, excludeDirs);
|
|
53
|
+
// The REGISTERED side too, through the same evaluator `check wiring` and
|
|
54
|
+
// `gates check` run. A subset rule whose declared selector never produced a
|
|
55
|
+
// registered member is connected — but only partially — and coverage must
|
|
56
|
+
// agree with the check about that, so it asks the check instead of
|
|
57
|
+
// re-deriving the set difference here. (An intended-empty rule's engine
|
|
58
|
+
// record IS its acceptance.)
|
|
59
|
+
const evaluated = insp.error === undefined ? runWiring(cwd, [rule], { excludeDirs }).rules[0] : undefined;
|
|
31
60
|
return {
|
|
61
|
+
...base,
|
|
32
62
|
filesMatched: insp.filesScanned,
|
|
33
63
|
unitsMatched: insp.ids.length,
|
|
34
|
-
unitLabel: 'ids',
|
|
35
64
|
ids: insp.ids,
|
|
36
65
|
...(side.$use ? { viaExtractor: side.$use } : {}),
|
|
37
66
|
...(insp.error ? { error: insp.error } : {}),
|
|
38
67
|
...(insp.hint ? { hint: insp.hint } : {}),
|
|
68
|
+
...(evaluated ? { coverage: evaluated.coverage } : {}),
|
|
69
|
+
...inspectionReadScope(insp),
|
|
39
70
|
};
|
|
40
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* A policy rule's "ids" are its PATTERN MATCHES, exactly as the engine reports
|
|
74
|
+
* each hit: capture group 1 when the pattern has one, else the whole match
|
|
75
|
+
* (whitespace-collapsed, at most 120 chars).
|
|
76
|
+
*
|
|
77
|
+
* Findings AND hits an exemption (`exemptFiles` / `exemptLines`) let through
|
|
78
|
+
* both count — an exempted fixture file is real code the author deliberately
|
|
79
|
+
* allowed, and it is the only liveness pin a policy rule can have ("the
|
|
80
|
+
* forbidden pattern still bites"). A hit the rule's OWN `scan` zone dropped
|
|
81
|
+
* does not count: the zone says that text is prose or a string, and letting it
|
|
82
|
+
* satisfy `expectIds` would be the false signal zones exist to remove.
|
|
83
|
+
*
|
|
84
|
+
* `unitsMatched` stays the content units scanned, so a clean rule with zero
|
|
85
|
+
* hits is still connected (`ok`), not `empty`.
|
|
86
|
+
*/
|
|
41
87
|
function matchPolicy(cwd, rule, excludeDirs) {
|
|
42
88
|
const report = runPolicyLint(cwd, [rule], { excludeDirs });
|
|
43
89
|
const result = report.rules[0];
|
|
90
|
+
// Hits an exemption let through: the fixtures the author deliberately kept.
|
|
91
|
+
// These are the only ids a scaffolded selfTest may pin (see IGateCoverage.pinIds).
|
|
92
|
+
const exempted = report.suppressed
|
|
93
|
+
.filter((s) => s.ruleId === rule.id && (s.via === 'exemptFiles' || s.via === 'exemptLines'))
|
|
94
|
+
.map((s) => s.match);
|
|
95
|
+
const ids = [
|
|
96
|
+
...new Set([
|
|
97
|
+
...report.findings.filter((f) => f.ruleId === rule.id).map((f) => f.match),
|
|
98
|
+
...report.suppressed
|
|
99
|
+
.filter((s) => s.ruleId === rule.id && s.via !== 'scanZone')
|
|
100
|
+
.map((s) => s.match),
|
|
101
|
+
]),
|
|
102
|
+
].sort();
|
|
103
|
+
const own = rule.files ?? [];
|
|
44
104
|
return {
|
|
45
105
|
// A policy rule's "files" and "units" differ only for inline templates.
|
|
46
106
|
filesMatched: result?.unitsScanned ?? 0,
|
|
47
107
|
unitsMatched: result?.unitsScanned ?? 0,
|
|
48
108
|
unitLabel: 'content units',
|
|
49
|
-
|
|
109
|
+
idLabel: 'pattern matches (capture group 1, else the whole match — findings plus exempted hits)',
|
|
110
|
+
consulted: `policy rule "${rule.id}" — /${rule.pattern}/${rule.flags ?? ''} over ` +
|
|
111
|
+
(own.length > 0 ? own.join(', ') : `the ${rule.surface} surface's default globs`),
|
|
112
|
+
ids,
|
|
113
|
+
pinIds: [...new Set(exempted)].sort(),
|
|
114
|
+
// Only the author's own `files[]` is a selector anyone wrote (a surface's
|
|
115
|
+
// default globs are not judged) — the list `runPolicyLint` settles too.
|
|
116
|
+
liveness: {
|
|
117
|
+
subject: rule.id,
|
|
118
|
+
lists: own.length > 0 ? [ruleList(cwd, 'files', own, excludeDirs)] : [],
|
|
119
|
+
marks: rule.expectEmptyUnits ?? [],
|
|
120
|
+
},
|
|
121
|
+
primaryLists: own.length > 0 ? ['files'] : [],
|
|
50
122
|
...(result?.error ? { error: result.error } : {}),
|
|
123
|
+
// The ENGINE's own record, the one `policy-lint` / `gates check` settle on
|
|
124
|
+
// (it names any matched file the reader left unread), never re-derived.
|
|
125
|
+
...(result ? { coverage: result.coverage } : {}),
|
|
126
|
+
// A rule with an unread file carries the file record, whose `examined` is
|
|
127
|
+
// the read count.
|
|
128
|
+
...(result?.unread ? { readScope: { read: result.coverage.examined, unread: result.unread } } : {}),
|
|
51
129
|
};
|
|
52
130
|
}
|
|
53
|
-
function matchRegistry(cwd, decl, excludeDirs) {
|
|
131
|
+
function matchRegistry(cwd, view, decl, excludeDirs) {
|
|
54
132
|
const insp = inspectSource(cwd, decl.source, excludeDirs);
|
|
55
133
|
return {
|
|
56
134
|
filesMatched: insp.filesScanned,
|
|
57
135
|
unitsMatched: insp.ids.length,
|
|
58
136
|
unitLabel: 'ids',
|
|
137
|
+
idLabel: 'registry ids',
|
|
138
|
+
consulted: `registry "${decl.name}" — source ${describeSource(decl.source)}`,
|
|
59
139
|
ids: insp.ids,
|
|
140
|
+
liveness: sourcesRequest(cwd, view, excludeDirs),
|
|
141
|
+
primaryLists: ['source.files'],
|
|
60
142
|
...(decl.source.$use ? { viaExtractor: decl.source.$use } : {}),
|
|
61
143
|
...(insp.error ? { error: insp.error } : {}),
|
|
62
144
|
...(insp.hint ? { hint: insp.hint } : {}),
|
|
145
|
+
...inspectionReadScope(insp),
|
|
63
146
|
};
|
|
64
147
|
}
|
|
65
|
-
function matchRegistration(cwd, idiom, excludeDirs) {
|
|
66
|
-
|
|
148
|
+
function matchRegistration(cwd, view, idiom, excludeDirs) {
|
|
149
|
+
// The ONE per-role measurement `gates check` reads too. Its empty is the
|
|
150
|
+
// declared role's (the idiom's primary selector), and its coverage names
|
|
151
|
+
// every role that examined nothing — an intended-empty role rides on the
|
|
152
|
+
// acceptance instead. So the two verbs agree on "empty", on "partial" and on
|
|
153
|
+
// "accepted" by construction, not by coincidence.
|
|
154
|
+
const roles = measureRegistrationRoles(cwd, idiom, excludeDirs);
|
|
155
|
+
const insp = roles.declared;
|
|
67
156
|
return {
|
|
68
157
|
filesMatched: insp.filesScanned,
|
|
69
158
|
unitsMatched: insp.ids.length,
|
|
70
159
|
unitLabel: 'declared tokens',
|
|
160
|
+
idLabel: 'declared tokens',
|
|
161
|
+
consulted: `registration idiom "${idiom.name}" — declared ${describeSource(idiom.declared)}`,
|
|
71
162
|
ids: insp.ids,
|
|
163
|
+
liveness: sourcesRequest(cwd, view, excludeDirs),
|
|
164
|
+
primaryLists: ['declared.files'],
|
|
165
|
+
coverage: roles.coverage,
|
|
72
166
|
...(idiom.declared.$use ? { viaExtractor: idiom.declared.$use } : {}),
|
|
73
|
-
|
|
167
|
+
// Only the PRIMARY side's error makes the rule misconfigured here, as on
|
|
168
|
+
// the wiring plane. A provided/consumed error is an unexamined role in
|
|
169
|
+
// `roles.coverage`.
|
|
170
|
+
...(roles.roleErrors.declared !== undefined ? { error: roles.roleErrors.declared } : {}),
|
|
74
171
|
...(insp.hint ? { hint: insp.hint } : {}),
|
|
172
|
+
...inspectionReadScope(insp),
|
|
75
173
|
};
|
|
76
174
|
}
|
|
77
175
|
function matchBaseline(cwd, rule, excludeDirs) {
|
|
176
|
+
// THE input request `baseline check` settles too (compute.source + watchFiles).
|
|
177
|
+
const built = baselineLivenessRequest(cwd, rule, excludeDirs);
|
|
78
178
|
// Only the EXTRACTOR half can be inspected without spawning. A command
|
|
79
179
|
// compute is reported honestly as un-inspectable rather than guessed at —
|
|
80
180
|
// `shrk baseline explain --id X` runs it on purpose.
|
|
@@ -90,17 +190,38 @@ function matchBaseline(cwd, rule, excludeDirs) {
|
|
|
90
190
|
filesMatched: 0,
|
|
91
191
|
unitsMatched: 0,
|
|
92
192
|
unitLabel: 'entries (command compute — not inspected; add `watchFiles` to enable the probe)',
|
|
193
|
+
idLabel: 'entries',
|
|
194
|
+
consulted: `baseline "${rule.id}" — a \`command\` compute (never run by coverage)`,
|
|
93
195
|
ids: [],
|
|
196
|
+
// A selfTest here asserts on a set nothing can produce without
|
|
197
|
+
// spawning the command. Report that instead of a fake "got 0" that
|
|
198
|
+
// would keep the rule red forever.
|
|
199
|
+
notEvaluable: 'a `command` baseline is never run by coverage, and this one declares no `watchFiles` to probe — add `watchFiles` (then the selfTest counts watchFiles paths)',
|
|
200
|
+
liveness: built.request,
|
|
201
|
+
primaryLists: [],
|
|
202
|
+
inspectable: false,
|
|
94
203
|
};
|
|
95
204
|
}
|
|
96
|
-
|
|
205
|
+
// The probe walks the POSITIVE set (inclusion globs), then selects through
|
|
206
|
+
// the list — a `!` in watchFiles excludes. EVERY probed path, sorted:
|
|
207
|
+
// `expectIds` may name any watched file, not just whichever five the walk
|
|
208
|
+
// happened to visit first. The one dead-unit decision judges the globs (in
|
|
209
|
+
// the request above), and a directory the walk could not list is an unread
|
|
210
|
+
// entry for it (a glob that may match beneath one is not dead).
|
|
211
|
+
const walked = walkMatching(cwd, watch, new Set(excludeDirs), new Set());
|
|
212
|
+
const probed = walked.filter((p) => globListSelects(p, watch)).sort();
|
|
97
213
|
return {
|
|
98
214
|
filesMatched: probed.length,
|
|
99
215
|
unitsMatched: probed.length,
|
|
100
216
|
// A zero here is a REAL empty (stale watchFiles), so the label must not
|
|
101
217
|
// carry the "not inspected" marker that suppresses the empty verdict.
|
|
102
218
|
unitLabel: 'watchFiles input(s) (compute unverified — command never run)',
|
|
103
|
-
|
|
219
|
+
idLabel: 'watchFiles paths',
|
|
220
|
+
consulted: `baseline "${rule.id}" — watchFiles ${watch.join(', ')} (probed; the command is never run)`,
|
|
221
|
+
ids: probed,
|
|
222
|
+
liveness: built.request,
|
|
223
|
+
// The probe IS this rule's match in coverage: its watchFiles is primary.
|
|
224
|
+
primaryLists: ['watchFiles'],
|
|
104
225
|
};
|
|
105
226
|
}
|
|
106
227
|
const insp = inspectSource(cwd, rule.compute.source, excludeDirs);
|
|
@@ -108,10 +229,15 @@ function matchBaseline(cwd, rule, excludeDirs) {
|
|
|
108
229
|
filesMatched: insp.filesScanned,
|
|
109
230
|
unitsMatched: insp.ids.length,
|
|
110
231
|
unitLabel: 'entries',
|
|
232
|
+
idLabel: 'entries',
|
|
233
|
+
consulted: `baseline "${rule.id}" — compute.source ${describeSource(rule.compute.source)}`,
|
|
111
234
|
ids: insp.ids,
|
|
235
|
+
liveness: built.request,
|
|
236
|
+
primaryLists: built.primaryLists,
|
|
112
237
|
...(rule.compute.source.$use ? { viaExtractor: rule.compute.source.$use } : {}),
|
|
113
238
|
...(insp.error ? { error: insp.error } : {}),
|
|
114
239
|
...(insp.hint ? { hint: insp.hint } : {}),
|
|
240
|
+
...inspectionReadScope(insp),
|
|
115
241
|
};
|
|
116
242
|
}
|
|
117
243
|
/**
|
|
@@ -127,18 +253,48 @@ function matchDocReference(cwd, rule, inspection, excludeDirs) {
|
|
|
127
253
|
filesMatched: res.filesScanned,
|
|
128
254
|
unitsMatched: res.tokensChecked,
|
|
129
255
|
unitLabel: 'doc reference(s)',
|
|
256
|
+
idLabel: 'validated doc-reference tokens',
|
|
257
|
+
consulted: docReferenceConsulted(rule),
|
|
130
258
|
ids: [...new Set(res.tokens.filter((t) => t.skipped === undefined).map((t) => t.token))].sort(),
|
|
259
|
+
// The rule's `files` judged per unit off the SAME walk the check reads (its
|
|
260
|
+
// dot-dirs included; a memo hit under `withFileReadCache`): a live negation
|
|
261
|
+
// is printed with what it excludes, a dead glob or a `!` excluding nothing
|
|
262
|
+
// is a dead unit — as on every other plane.
|
|
263
|
+
liveness: {
|
|
264
|
+
subject: rule.id,
|
|
265
|
+
lists: [ruleList(cwd, 'files', rule.files, excludeDirs, dotDirsNamedBy(rule.files))],
|
|
266
|
+
marks: rule.expectEmptyUnits ?? [],
|
|
267
|
+
},
|
|
268
|
+
primaryLists: ['files'],
|
|
131
269
|
...(res.error ? { error: res.error } : {}),
|
|
270
|
+
...(res.readScope ? { readScope: res.readScope } : {}),
|
|
132
271
|
};
|
|
133
272
|
}
|
|
273
|
+
function docReferenceConsulted(rule) {
|
|
274
|
+
return (`doc-reference rule "${rule.id}" — /${rule.tokenPattern}/${rule.tokenPatternFlags ?? ''} over ${rule.files.join(', ')}, ` +
|
|
275
|
+
`resolved as ${rule.resolvesAs.join(' | ')}`);
|
|
276
|
+
}
|
|
134
277
|
function matchGenerated(cwd, rule, excludeDirs) {
|
|
135
278
|
const scan = scanGeneratedFiles(cwd, rule, excludeDirs);
|
|
136
279
|
const files = [...scan.generated.keys()];
|
|
280
|
+
// `generatedGlob` judged per unit off the walk `scanGeneratedFiles` just
|
|
281
|
+
// read (a memo hit). `sources[].glob`, `outsideGlob` and `handMaintained`
|
|
282
|
+
// are not judged here: the writers partition the generated set (`unclassified`
|
|
283
|
+
// reports a gap), and a stale bless has its own finding.
|
|
137
284
|
return {
|
|
138
285
|
filesMatched: files.length,
|
|
139
286
|
unitsMatched: files.length,
|
|
140
287
|
unitLabel: 'generated files',
|
|
288
|
+
idLabel: 'generated file paths',
|
|
289
|
+
consulted: `generated artifact "${rule.id}" — ${rule.generatedGlob.join(', ')}`,
|
|
141
290
|
ids: files,
|
|
291
|
+
liveness: {
|
|
292
|
+
subject: rule.id,
|
|
293
|
+
lists: [ruleList(cwd, 'generatedGlob', rule.generatedGlob, excludeDirs)],
|
|
294
|
+
marks: rule.expectEmptyUnits ?? [],
|
|
295
|
+
},
|
|
296
|
+
primaryLists: ['generatedGlob'],
|
|
297
|
+
...(readScopeHasUnread(scan.readScope) ? { readScope: scan.readScope } : {}),
|
|
142
298
|
};
|
|
143
299
|
}
|
|
144
300
|
/**
|
|
@@ -160,64 +316,184 @@ function buildGateCoverageUncached(cwd, rules, excludeDirs, extractors, includeA
|
|
|
160
316
|
let match;
|
|
161
317
|
switch (view.plane) {
|
|
162
318
|
case 'wiring':
|
|
163
|
-
match = matchWiring(cwd, view.raw, excludeDirs);
|
|
319
|
+
match = matchWiring(cwd, view, view.raw, excludeDirs);
|
|
164
320
|
break;
|
|
165
321
|
case 'policy':
|
|
166
322
|
match = matchPolicy(cwd, view.raw, excludeDirs);
|
|
167
323
|
break;
|
|
168
324
|
case 'registry':
|
|
169
|
-
match = matchRegistry(cwd, view.raw, excludeDirs);
|
|
325
|
+
match = matchRegistry(cwd, view, view.raw, excludeDirs);
|
|
170
326
|
break;
|
|
171
327
|
case 'registration':
|
|
172
|
-
match = matchRegistration(cwd, view.raw, excludeDirs);
|
|
328
|
+
match = matchRegistration(cwd, view, view.raw, excludeDirs);
|
|
173
329
|
break;
|
|
174
330
|
case 'baseline':
|
|
175
331
|
match = matchBaseline(cwd, view.raw, excludeDirs);
|
|
176
332
|
break;
|
|
177
|
-
case 'doc-reference':
|
|
333
|
+
case 'doc-reference': {
|
|
178
334
|
// The inspection is only built when this plane is actually present, so
|
|
179
335
|
// a repo without it never pays for the registries.
|
|
336
|
+
const rule = view.raw;
|
|
180
337
|
match = inspection
|
|
181
|
-
? matchDocReference(cwd,
|
|
338
|
+
? matchDocReference(cwd, rule, inspection, excludeDirs)
|
|
182
339
|
: {
|
|
183
340
|
filesMatched: 0,
|
|
184
341
|
unitsMatched: 0,
|
|
185
342
|
unitLabel: 'doc reference(s) (registries not loaded — not inspected)',
|
|
343
|
+
idLabel: 'validated doc-reference tokens',
|
|
344
|
+
consulted: docReferenceConsulted(rule),
|
|
186
345
|
ids: [],
|
|
346
|
+
notEvaluable: 'the registries a doc reference resolves against were not loaded',
|
|
347
|
+
liveness: { subject: rule.id, lists: [], marks: [] },
|
|
348
|
+
primaryLists: [],
|
|
349
|
+
inspectable: false,
|
|
187
350
|
};
|
|
188
351
|
break;
|
|
352
|
+
}
|
|
189
353
|
default:
|
|
190
354
|
match = matchGenerated(cwd, view.raw, excludeDirs);
|
|
191
355
|
break;
|
|
192
356
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
//
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
const
|
|
357
|
+
// ONE evaluator for every plane (and for `gates try`). A selector that
|
|
358
|
+
// could not run has no extracted set, so its expectations are unmeasured —
|
|
359
|
+
// reported as such, never as a fabricated "got 0".
|
|
360
|
+
const checks = evaluateSelfTest(view.selfTest, match.error !== undefined && match.notEvaluable === undefined
|
|
361
|
+
? { ...match, notEvaluable: `the selector could not run (${match.error})` }
|
|
362
|
+
: match);
|
|
363
|
+
const failedChecks = checks.filter((c) => c.status === 'failed');
|
|
364
|
+
const unevaluable = checks.filter((c) => c.status === 'not-evaluable');
|
|
365
|
+
const expectationFailures = failedChecks.map((c) => c.message);
|
|
366
|
+
// A selfTest field this plane shape can never evaluate is a misconfigured
|
|
367
|
+
// rule (it can never pass), so it surfaces as the rule's error.
|
|
368
|
+
const error = match.error ?? (unevaluable.length > 0 ? unevaluable.map((c) => c.message).join('; ') : undefined);
|
|
369
|
+
// A structured flag, never a substring of the human label: the quality
|
|
370
|
+
// bundle reads the same fact to settle such a rule on its check's coverage.
|
|
371
|
+
const uninspected = match.inspectable === false;
|
|
372
|
+
// THE gate-plane glob settle (round 13): core's `settleUnitLiveness` over
|
|
373
|
+
// THE observation predicate (`globListLivenessInput`) and every list the
|
|
374
|
+
// rule reads, with its `expectEmpty` markers — the input each plane engine
|
|
375
|
+
// builds too, so `gates coverage`, `gates try`, `quality` and every plane
|
|
376
|
+
// verb judge one glob alike. `settled.dead` is the UNMARKED dead units
|
|
377
|
+
// only; a marked glob is intended-empty (record B) or went-live.
|
|
378
|
+
const settled = settleUnitLiveness(globListLivenessInput(match.liveness));
|
|
379
|
+
const lists = match.liveness.lists;
|
|
380
|
+
const primaryList = lists.find((l) => match.primaryLists.includes(l.list));
|
|
381
|
+
const labelOf = (l, glob) => (l.label !== undefined ? `${l.label}: ${glob}` : glob);
|
|
382
|
+
const negations = lists.flatMap((l) => l.units.negations.map((n) => ({ selector: labelOf(l, n.glob), excludes: n.excludes })));
|
|
383
|
+
const excludedByNegations = primaryList !== undefined && primaryList.units.allExcluded
|
|
384
|
+
? primaryList.units.negations.map((n) => ({ selector: labelOf(primaryList, n.glob), excludes: n.excludes }))
|
|
385
|
+
: undefined;
|
|
386
|
+
const deadGlobUnits = settled.dead.map((u) => ({
|
|
387
|
+
selector: u.label,
|
|
388
|
+
glob: u.unit,
|
|
389
|
+
negation: u.unit.startsWith('!'),
|
|
390
|
+
reason: u.deadReason ?? 'matched 0 files',
|
|
391
|
+
}));
|
|
392
|
+
// A selector that matched a file the reader could not read matched
|
|
393
|
+
// something: it is not stale, so it is never `empty` (and a failOnEmpty
|
|
394
|
+
// rule never FAILS on it). Its coverage names the unread file instead.
|
|
395
|
+
const matchedUnread = readScopeHasUnread(match.readScope);
|
|
396
|
+
// THE rule-emptiness settle (round 13) — the one call that replaces the
|
|
397
|
+
// three `expectEmpty` consults: a FENCE's asserted empty set over live
|
|
398
|
+
// inputs (`ruleAssertsEmptyOutput`), a rule whose every primary inclusion
|
|
399
|
+
// glob is intended-empty and matched no file, or the loud skip. A fence
|
|
400
|
+
// over a DEAD input is stale, never accepted; 0 units out of live files is
|
|
401
|
+
// never assertable.
|
|
402
|
+
const emptiness = settleRuleEmptiness({
|
|
403
|
+
subject: view.id,
|
|
404
|
+
unitLabel: match.unitLabel,
|
|
405
|
+
filesMatched: match.filesMatched,
|
|
406
|
+
unitsMatched: match.unitsMatched,
|
|
407
|
+
unread: matchedUnread,
|
|
408
|
+
emptiedByNegations: excludedByNegations !== undefined,
|
|
409
|
+
emptiedReason: `matched nothing — ${EMPTIED_BY_NEGATIONS}`,
|
|
410
|
+
liveness: settled,
|
|
411
|
+
primaryLists: match.primaryLists,
|
|
412
|
+
assertsEmptyOutput: ruleAssertsEmptyOutput(view),
|
|
413
|
+
failOnEmpty: view.failOnEmpty,
|
|
414
|
+
noFilesReason: STALE_SELECTOR,
|
|
415
|
+
noUnitsReason: STALE_SELECTOR,
|
|
416
|
+
});
|
|
417
|
+
const accepted = emptiness.state === RuleEmptiness.AssertedEmptyOutput || emptiness.state === RuleEmptiness.IntendedEmpty;
|
|
418
|
+
const status = error !== undefined
|
|
200
419
|
? 'error'
|
|
201
|
-
:
|
|
420
|
+
: failedChecks.length > 0
|
|
202
421
|
? 'failed-expectation'
|
|
203
|
-
:
|
|
422
|
+
: !uninspected && emptiness.skipped
|
|
204
423
|
? 'empty'
|
|
205
424
|
: 'ok';
|
|
425
|
+
// The scope this coverage run could actually see. A plane whose engine
|
|
426
|
+
// knows more supplies its own record (wiring, policy, registration — an
|
|
427
|
+
// intended-empty rule's record IS its acceptance); an accepted empty is the
|
|
428
|
+
// settle's own record; a rule coverage could not inspect examined nothing
|
|
429
|
+
// — it is never reported "connected" on faith. Every other plane's record
|
|
430
|
+
// folds the reader's unread files through the one rule, `readScopeCoverage`.
|
|
431
|
+
const coverage = match.coverage ??
|
|
432
|
+
readScopeCoverage(uninspected
|
|
433
|
+
? {
|
|
434
|
+
unit: 'inspectable inputs',
|
|
435
|
+
expected: 1,
|
|
436
|
+
examined: 0,
|
|
437
|
+
reason: `not inspected — ${match.unitLabel}`,
|
|
438
|
+
}
|
|
439
|
+
: (emptiness.coverage ?? {
|
|
440
|
+
unit: match.unitLabel,
|
|
441
|
+
expected: match.unitsMatched,
|
|
442
|
+
examined: match.unitsMatched,
|
|
443
|
+
...(match.unitsMatched === 0
|
|
444
|
+
? {
|
|
445
|
+
// A rule that could not RUN is misconfigured, not stale:
|
|
446
|
+
// its zero is no evidence about the selector at all
|
|
447
|
+
// (round 12 review, R12-X3).
|
|
448
|
+
reason: error !== undefined
|
|
449
|
+
? 'NOT evaluated — the rule is misconfigured (see its error)'
|
|
450
|
+
: (emptiness.skipReason ?? STALE_SELECTOR),
|
|
451
|
+
}
|
|
452
|
+
: {}),
|
|
453
|
+
}), match.readScope);
|
|
454
|
+
const nonLive = settled.units.filter((u) => u.state !== UnitLivenessState.Live);
|
|
206
455
|
out.push({
|
|
207
456
|
id: view.id,
|
|
208
457
|
plane: view.plane,
|
|
209
458
|
...(view.description ? { description: view.description } : {}),
|
|
210
459
|
status,
|
|
460
|
+
coverage,
|
|
461
|
+
...(settled.acceptance !== undefined ? { unitAcceptance: settled.acceptance } : {}),
|
|
462
|
+
...(settled.dead.length + settled.intendedEmpty.length + settled.wentLive.length > 0
|
|
463
|
+
? { units: unitStateLists(settled) }
|
|
464
|
+
: {}),
|
|
465
|
+
...(nonLive.length > 0 ? { unitLiveness: nonLive } : {}),
|
|
466
|
+
...(emptiness.state !== RuleEmptiness.Matched ? { emptiness: emptiness.state } : {}),
|
|
467
|
+
...(emptiness.cause === 'dead-input' && emptiness.skipReason !== undefined
|
|
468
|
+
? { emptyReason: emptiness.skipReason }
|
|
469
|
+
: {}),
|
|
211
470
|
filesMatched: match.filesMatched,
|
|
212
471
|
unitsMatched: match.unitsMatched,
|
|
213
|
-
unitLabel:
|
|
472
|
+
unitLabel: emptiness.state === RuleEmptiness.AssertedEmptyOutput
|
|
473
|
+
? `${match.unitLabel} (empty — the asserted state)`
|
|
474
|
+
: emptiness.state === RuleEmptiness.IntendedEmpty
|
|
475
|
+
? `${match.unitLabel} (empty — asserted by expectEmpty)`
|
|
476
|
+
: match.unitLabel,
|
|
477
|
+
idLabel: match.idLabel,
|
|
478
|
+
consulted: match.consulted,
|
|
214
479
|
sampleIds: match.ids.slice(0, 5),
|
|
215
480
|
...(includeAllIds ? { allIds: match.ids } : {}),
|
|
481
|
+
...(match.pinIds !== undefined ? { pinIds: match.pinIds } : {}),
|
|
482
|
+
...(uninspected ? { inspectable: false } : {}),
|
|
216
483
|
failOnEmpty: view.failOnEmpty,
|
|
217
|
-
...(
|
|
218
|
-
|
|
484
|
+
...(error !== undefined ? { error } : {}),
|
|
485
|
+
// A diagnosis of a probably-unintended zero (the import-edges barrel
|
|
486
|
+
// hint) is never printed over an ACCEPTED empty: it would invite the
|
|
487
|
+
// author to "fix" a correct fence.
|
|
488
|
+
...(match.hint && !accepted ? { hint: match.hint } : {}),
|
|
219
489
|
...(match.viaExtractor ? { viaExtractor: match.viaExtractor } : {}),
|
|
220
490
|
expectationFailures,
|
|
491
|
+
...(checks.length > 0 ? { selfTestChecks: checks } : {}),
|
|
492
|
+
deadGlobs: deadGlobUnits.map((u) => u.selector),
|
|
493
|
+
deadGlobUnits,
|
|
494
|
+
negations,
|
|
495
|
+
...(excludedByNegations !== undefined ? { excludedByNegations } : {}),
|
|
496
|
+
globsChecked: lists.reduce((n, l) => n + l.units.checked, 0),
|
|
221
497
|
});
|
|
222
498
|
}
|
|
223
499
|
// Report each SHARED extractor once, with the rules that consume it. One
|
|
@@ -274,7 +550,183 @@ function buildGateCoverageUncached(cwd, rules, excludeDirs, extractors, includeA
|
|
|
274
550
|
empty,
|
|
275
551
|
errored,
|
|
276
552
|
expectationFailures,
|
|
553
|
+
deadGlobCount: out.filter(reportsDeadGlobs).reduce((n, r) => n + r.deadGlobs.length, 0),
|
|
277
554
|
extractors: extractorCoverage,
|
|
278
555
|
verdict: empty + errored + expectationFailures > 0 ? 'stale' : 'pass',
|
|
279
556
|
};
|
|
280
557
|
}
|
|
558
|
+
/**
|
|
559
|
+
* The coverage report with every pack rule the merge seam REJECTED folded in as
|
|
560
|
+
* a misconfigured (`error`) row (round 12 review, R12-X1) — from THE rows
|
|
561
|
+
* `seamRejectedRules` builds for `gates check`, so the coverage verb and the
|
|
562
|
+
* check cannot disagree about a rule that never ran. It counts in `total` and
|
|
563
|
+
* `errored`, so `settleGateCoverage` fails it (exit 1) and names it unexamined.
|
|
564
|
+
*/
|
|
565
|
+
export function withRejectedRules(report, rejected) {
|
|
566
|
+
if (rejected.length === 0)
|
|
567
|
+
return report;
|
|
568
|
+
const rows = rejected.map((r) => ({
|
|
569
|
+
id: r.id,
|
|
570
|
+
plane: r.type,
|
|
571
|
+
status: 'error',
|
|
572
|
+
coverage: r.coverage,
|
|
573
|
+
filesMatched: 0,
|
|
574
|
+
unitsMatched: 0,
|
|
575
|
+
unitLabel: 'units (rejected at the pack-plane merge seam — not evaluated)',
|
|
576
|
+
idLabel: 'extracted ids',
|
|
577
|
+
consulted: 'nothing — the pack element failed validation before any selector ran',
|
|
578
|
+
sampleIds: [],
|
|
579
|
+
failOnEmpty: true,
|
|
580
|
+
...(r.error !== undefined ? { error: r.error } : {}),
|
|
581
|
+
expectationFailures: [],
|
|
582
|
+
deadGlobs: [],
|
|
583
|
+
deadGlobUnits: [],
|
|
584
|
+
negations: [],
|
|
585
|
+
globsChecked: 0,
|
|
586
|
+
}));
|
|
587
|
+
const all = [...report.rules, ...rows];
|
|
588
|
+
const errored = all.filter((r) => r.status === 'error').length;
|
|
589
|
+
return {
|
|
590
|
+
...report,
|
|
591
|
+
rules: all,
|
|
592
|
+
total: all.length,
|
|
593
|
+
errored,
|
|
594
|
+
verdict: report.empty + errored + report.expectationFailures > 0 ? 'stale' : 'pass',
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Whether a rule's dead globs are a finding of their OWN: the rule is connected
|
|
599
|
+
* (it matched something, or it is an inspected fence / clean rule reported
|
|
600
|
+
* `ok`), so sibling globs can hide the dead ones.
|
|
601
|
+
*
|
|
602
|
+
* A rule already reported as matching nothing has no live sibling to hide
|
|
603
|
+
* behind. Its "matched nothing" verdict (skip, or failOnEmpty failure) already
|
|
604
|
+
* says it, so its dead globs are not counted, drawn or failed a second time.
|
|
605
|
+
* `--fail-on-dead-units` must never turn a soft-empty rule's `2` into a `1`.
|
|
606
|
+
* The report count, the ⚠ lines, the settle and the quality notes all read
|
|
607
|
+
* this one predicate.
|
|
608
|
+
*/
|
|
609
|
+
export function reportsDeadGlobs(r) {
|
|
610
|
+
if (r.deadGlobs.length === 0 || r.status === 'empty')
|
|
611
|
+
return false;
|
|
612
|
+
return r.status === 'ok' || r.unitsMatched > 0;
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* THE dead units of a coverage row, each with its reason — what the ⚠ line,
|
|
616
|
+
* the `--fail-on-dead-units` violation and the `shrk quality` note all print,
|
|
617
|
+
* so the three cannot word one unit differently. A row built without
|
|
618
|
+
* `deadGlobUnits` (a hand-built report) falls back to its `deadGlobs` labels,
|
|
619
|
+
* read as inclusion globs that matched nothing.
|
|
620
|
+
*/
|
|
621
|
+
export function coverageDeadUnits(r) {
|
|
622
|
+
if (r.deadGlobUnits !== undefined && r.deadGlobUnits.length === r.deadGlobs.length)
|
|
623
|
+
return r.deadGlobUnits;
|
|
624
|
+
return r.deadGlobs.map((g) => ({ selector: g, glob: g, negation: false, reason: 'matched 0 files' }));
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* THE went-live units of a coverage row (round 13): each glob marked
|
|
628
|
+
* `expectEmpty` whose target now exists — the fence went live. What the ⚠
|
|
629
|
+
* `expectEmpty is stale` rows, the `--fail-on-dead-units` violation and the
|
|
630
|
+
* `shrk quality` note print.
|
|
631
|
+
*/
|
|
632
|
+
export function coverageWentLiveUnits(r) {
|
|
633
|
+
return (r.unitLiveness ?? []).filter((u) => u.state === UnitLivenessState.WentLive);
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* The selector units that FAIL a coverage row under the given flags — decided
|
|
637
|
+
* by THE predicate every `--fail-on-dead-units` consumer calls
|
|
638
|
+
* (`selectorUnitFails`, core): an unmarked dead glob of a connected rule
|
|
639
|
+
* ({@link reportsDeadGlobs}), and a LOCAL went-live marker. A pack marker that
|
|
640
|
+
* went live is INFO, never a failure; an intended-empty unit never fails.
|
|
641
|
+
*/
|
|
642
|
+
export function coverageUnitFailures(r, flags) {
|
|
643
|
+
const dead = reportsDeadGlobs(r)
|
|
644
|
+
? coverageDeadUnits(r)
|
|
645
|
+
.filter(() => selectorUnitFails({ state: UnitLivenessState.Dead }, flags))
|
|
646
|
+
.map((u) => ({ selector: u.selector, message: `${u.reason} (--fail-on-dead-units)` }))
|
|
647
|
+
: [];
|
|
648
|
+
const wentLive = coverageWentLiveUnits(r)
|
|
649
|
+
.filter((u) => selectorUnitFails(u, flags))
|
|
650
|
+
.map((u) => ({ selector: u.label, message: `${u.message} (--fail-on-dead-units)` }));
|
|
651
|
+
return [...dead, ...wentLive];
|
|
652
|
+
}
|
|
653
|
+
/** `declared: src/moved/*.ts (matched 0 files), !src/nowhere/** (excludes nothing — …)`. */
|
|
654
|
+
export function formatDeadUnits(units) {
|
|
655
|
+
return units.map((u) => `${u.selector} (${u.reason})`).join(', ');
|
|
656
|
+
}
|
|
657
|
+
/** `declared: !src/**\/*.spec.ts (1 file), !docs/drafts/** (3 files)`. */
|
|
658
|
+
export function formatNegations(negations) {
|
|
659
|
+
return negations.map((n) => `${n.selector} (${n.excludes} file${n.excludes === 1 ? '' : 's'})`).join(', ');
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Settle a coverage report into the shared `gate` envelope — THE derivation of
|
|
663
|
+
* what `gates coverage` concludes.
|
|
664
|
+
*
|
|
665
|
+
* `gates coverage` and `shrk quality`'s coverage item both call this, so the
|
|
666
|
+
* pre-push bundle cannot pass a rule set the verb itself reports broken (a
|
|
667
|
+
* failed selfTest, a stale failOnEmpty selector, a partial rule). A rule that
|
|
668
|
+
* matched nothing is not-verified (2) by default; `failOnEmpty` on the rule
|
|
669
|
+
* makes it a failure (1); `failOnDeadUnits` makes a dead glob inside a
|
|
670
|
+
* connected rule — or a local marker whose target went live — a failure too
|
|
671
|
+
* (`selectorUnitFails`). Each rule's `expectEmpty` acceptance rides on its
|
|
672
|
+
* envelope rule (`unitAcceptance`) into the one settle.
|
|
673
|
+
*/
|
|
674
|
+
export function settleGateCoverage(report, options = {}) {
|
|
675
|
+
const flags = {
|
|
676
|
+
failOnDeadUnits: options.failOnDeadUnits === true,
|
|
677
|
+
// `gates coverage` is not where --strict promotes warnings (check boundaries is).
|
|
678
|
+
strict: false,
|
|
679
|
+
strictPromotesWarnings: false,
|
|
680
|
+
};
|
|
681
|
+
const unitFailures = (r) => coverageUnitFailures(r, flags);
|
|
682
|
+
const deadFails = (r) => unitFailures(r).length > 0;
|
|
683
|
+
const hard = report.rules.filter((r) => r.status === 'error' ||
|
|
684
|
+
r.status === 'failed-expectation' ||
|
|
685
|
+
(r.status === 'empty' && r.failOnEmpty) ||
|
|
686
|
+
deadFails(r));
|
|
687
|
+
const softEmpty = report.rules.filter((r) => r.status === 'empty' && !r.failOnEmpty);
|
|
688
|
+
const proposed = hard.length > 0 ? ExitCode.Failure : softEmpty.length > 0 ? ExitCode.NotVerified : ExitCode.VerifiedPass;
|
|
689
|
+
const unconnected = report.rules
|
|
690
|
+
.filter((r) => r.status === 'empty' || r.status === 'error')
|
|
691
|
+
.map((r) => r.id);
|
|
692
|
+
return buildGateEnvelope('gates coverage', proposed, report.rules.map((r) => ({
|
|
693
|
+
id: r.id,
|
|
694
|
+
type: r.plane,
|
|
695
|
+
status: r.status === 'ok'
|
|
696
|
+
? deadFails(r)
|
|
697
|
+
? 'failed'
|
|
698
|
+
: 'passed'
|
|
699
|
+
: r.status === 'empty'
|
|
700
|
+
? r.failOnEmpty || deadFails(r)
|
|
701
|
+
? 'failed'
|
|
702
|
+
: 'skipped'
|
|
703
|
+
: r.status === 'error'
|
|
704
|
+
? 'error'
|
|
705
|
+
: 'failed',
|
|
706
|
+
severity: r.failOnEmpty || deadFails(r) ? 'error' : 'warning',
|
|
707
|
+
counts: { files: r.filesMatched, units: r.unitsMatched },
|
|
708
|
+
violations: [
|
|
709
|
+
...r.expectationFailures.map((f) => ({ id: r.id, message: f })),
|
|
710
|
+
...unitFailures(r).map((f) => ({ id: f.selector, message: f.message })),
|
|
711
|
+
],
|
|
712
|
+
...(r.status === 'empty'
|
|
713
|
+
? {
|
|
714
|
+
skipReason: r.emptyReason ??
|
|
715
|
+
(r.excludedByNegations !== undefined
|
|
716
|
+
? `matched 0 ${r.unitLabel} — ${EMPTIED_BY_NEGATIONS}`
|
|
717
|
+
: `matched 0 ${r.unitLabel}`),
|
|
718
|
+
}
|
|
719
|
+
: {}),
|
|
720
|
+
...(r.error ? { error: r.error } : {}),
|
|
721
|
+
coverage: r.coverage,
|
|
722
|
+
...(r.unitAcceptance !== undefined ? { unitAcceptance: r.unitAcceptance } : {}),
|
|
723
|
+
...(r.units !== undefined ? { units: r.units } : {}),
|
|
724
|
+
})), {
|
|
725
|
+
unit: 'rules',
|
|
726
|
+
expected: report.total,
|
|
727
|
+
examined: report.total - unconnected.length,
|
|
728
|
+
...(unconnected.length > 0
|
|
729
|
+
? { unexamined: unconnected, reason: 'matched nothing or could not run' }
|
|
730
|
+
: {}),
|
|
731
|
+
});
|
|
732
|
+
}
|