@shrkcrft/inspector 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/acceptance-replay.js +1 -1
- package/dist/agent-contract-templates.js +6 -6
- package/dist/agent-contract.d.ts.map +1 -1
- package/dist/agent-contract.js +13 -8
- package/dist/agent-orchestration.js +2 -2
- package/dist/agent-task-prep.d.ts +16 -0
- package/dist/agent-task-prep.d.ts.map +1 -1
- package/dist/agent-task-prep.js +51 -4
- package/dist/ai-readiness.d.ts.map +1 -1
- package/dist/ai-readiness.js +21 -3
- package/dist/architecture-map.d.ts +16 -0
- package/dist/architecture-map.d.ts.map +1 -1
- package/dist/architecture-map.js +42 -26
- package/dist/area-explore.d.ts +2 -2
- package/dist/area-explore.d.ts.map +1 -1
- package/dist/area-explore.js +36 -16
- package/dist/area-map.d.ts +56 -11
- package/dist/area-map.d.ts.map +1 -1
- package/dist/area-map.js +106 -25
- package/dist/asset-doctor-proposed-exit.d.ts +21 -0
- package/dist/asset-doctor-proposed-exit.d.ts.map +1 -0
- package/dist/asset-doctor-proposed-exit.js +22 -0
- package/dist/asset-provenance.js +1 -1
- package/dist/boundaries-changed-only.d.ts +24 -1
- package/dist/boundaries-changed-only.d.ts.map +1 -1
- package/dist/boundaries-changed-only.js +12 -2
- package/dist/boundary-check-options.model.d.ts +40 -0
- package/dist/boundary-check-options.model.d.ts.map +1 -0
- package/dist/boundary-check-options.model.js +1 -0
- package/dist/boundary-check-result.model.d.ts +89 -0
- package/dist/boundary-check-result.model.d.ts.map +1 -0
- package/dist/boundary-check-result.model.js +1 -0
- package/dist/boundary-configuration-status.d.ts +38 -0
- package/dist/boundary-configuration-status.d.ts.map +1 -0
- package/dist/boundary-configuration-status.js +118 -0
- package/dist/boundary-configuration-status.model.d.ts +37 -0
- package/dist/boundary-configuration-status.model.d.ts.map +1 -0
- package/dist/boundary-configuration-status.model.js +1 -0
- package/dist/boundary-load-issue.model.d.ts +30 -0
- package/dist/boundary-load-issue.model.d.ts.map +1 -0
- package/dist/boundary-load-issue.model.js +1 -0
- package/dist/boundary-rule-check.model.d.ts +44 -0
- package/dist/boundary-rule-check.model.d.ts.map +1 -0
- package/dist/boundary-rule-check.model.js +1 -0
- package/dist/boundary-rule-invalidation.model.d.ts +31 -0
- package/dist/boundary-rule-invalidation.model.d.ts.map +1 -0
- package/dist/boundary-rule-invalidation.model.js +1 -0
- package/dist/boundary-rule-set-diff.model.d.ts +75 -0
- package/dist/boundary-rule-set-diff.model.d.ts.map +1 -0
- package/dist/boundary-rule-set-diff.model.js +1 -0
- package/dist/boundary-rule-sources.d.ts +28 -0
- package/dist/boundary-rule-sources.d.ts.map +1 -0
- package/dist/boundary-rule-sources.js +110 -0
- package/dist/boundary-stale-exception-finding.model.d.ts +12 -0
- package/dist/boundary-stale-exception-finding.model.d.ts.map +1 -0
- package/dist/boundary-stale-exception-finding.model.js +1 -0
- package/dist/boundary-unit-liveness.d.ts +35 -0
- package/dist/boundary-unit-liveness.d.ts.map +1 -0
- package/dist/boundary-unit-liveness.js +71 -0
- package/dist/change-intent.d.ts +3 -0
- package/dist/change-intent.d.ts.map +1 -1
- package/dist/change-intent.js +61 -27
- package/dist/changes-summary.d.ts.map +1 -1
- package/dist/changes-summary.js +19 -9
- package/dist/ci-integrity-report.js +1 -1
- package/dist/ci-predict.d.ts.map +1 -1
- package/dist/ci-predict.js +38 -5
- package/dist/code-intelligence-doctor.d.ts +6 -0
- package/dist/code-intelligence-doctor.d.ts.map +1 -1
- package/dist/code-intelligence-doctor.js +22 -7
- package/dist/command-recommender.d.ts +45 -2
- package/dist/command-recommender.d.ts.map +1 -1
- package/dist/command-recommender.js +41 -263
- package/dist/command-resolution-status.d.ts +44 -0
- package/dist/command-resolution-status.d.ts.map +1 -0
- package/dist/command-resolution-status.js +44 -0
- package/dist/command-safety-level.d.ts +15 -0
- package/dist/command-safety-level.d.ts.map +1 -0
- package/dist/command-safety-level.js +43 -0
- package/dist/command-taxonomy.js +1 -1
- package/dist/compliance-evidence.js +1 -1
- package/dist/compliance-profiles.js +1 -1
- package/dist/construct-registry.d.ts +40 -0
- package/dist/construct-registry.d.ts.map +1 -1
- package/dist/construct-registry.js +186 -82
- package/dist/context-tuning.d.ts +4 -0
- package/dist/context-tuning.d.ts.map +1 -1
- package/dist/context-tuning.js +10 -7
- package/dist/contract-template-registry.d.ts +10 -0
- package/dist/contract-template-registry.d.ts.map +1 -1
- package/dist/contract-template-registry.js +59 -33
- package/dist/contribution-kind.d.ts +52 -0
- package/dist/contribution-kind.d.ts.map +1 -0
- package/dist/contribution-kind.js +52 -0
- package/dist/contribution-load-failures.d.ts +106 -0
- package/dist/contribution-load-failures.d.ts.map +1 -0
- package/dist/contribution-load-failures.js +575 -0
- package/dist/contributions-report.d.ts +28 -0
- package/dist/contributions-report.d.ts.map +1 -0
- package/dist/contributions-report.js +242 -0
- package/dist/convention-registry.d.ts +22 -0
- package/dist/convention-registry.d.ts.map +1 -1
- package/dist/convention-registry.js +79 -39
- package/dist/coverage-report.d.ts.map +1 -1
- package/dist/coverage-report.js +6 -6
- package/dist/custom-checks.d.ts +60 -1
- package/dist/custom-checks.d.ts.map +1 -1
- package/dist/custom-checks.js +159 -6
- package/dist/dashboard/dashboard-data.d.ts +6 -0
- package/dist/dashboard/dashboard-data.d.ts.map +1 -1
- package/dist/dashboard/dashboard-data.js +99 -8
- package/dist/dashboard/dashboard-knowledge.d.ts.map +1 -1
- package/dist/dashboard/dashboard-knowledge.js +14 -2
- package/dist/decision-records.d.ts +20 -0
- package/dist/decision-records.d.ts.map +1 -1
- package/dist/decision-records.js +68 -20
- package/dist/declared-cross-references.d.ts +61 -0
- package/dist/declared-cross-references.d.ts.map +1 -0
- package/dist/declared-cross-references.js +550 -0
- package/dist/declared-gate-plane-rules.d.ts +24 -0
- package/dist/declared-gate-plane-rules.d.ts.map +1 -0
- package/dist/declared-gate-plane-rules.js +39 -0
- package/dist/declared-reference-coverage.d.ts +27 -0
- package/dist/declared-reference-coverage.d.ts.map +1 -0
- package/dist/declared-reference-coverage.js +50 -0
- package/dist/declared-xref-status.d.ts +19 -0
- package/dist/declared-xref-status.d.ts.map +1 -0
- package/dist/declared-xref-status.js +19 -0
- package/dist/delegate-pack-recipes.d.ts +13 -2
- package/dist/delegate-pack-recipes.d.ts.map +1 -1
- package/dist/delegate-pack-recipes.js +45 -14
- package/dist/demo-package.js +2 -2
- package/dist/demo-script.js +2 -2
- package/dist/demo-workflow.js +3 -3
- package/dist/dev-cycle.js +1 -1
- package/dist/dev-session.js +1 -1
- package/dist/doc-references.d.ts +23 -2
- package/dist/doc-references.d.ts.map +1 -1
- package/dist/doc-references.js +96 -17
- package/dist/doctor-result.d.ts +8 -0
- package/dist/doctor-result.d.ts.map +1 -1
- package/dist/doctor-verdict-kind.d.ts +19 -0
- package/dist/doctor-verdict-kind.d.ts.map +1 -0
- package/dist/doctor-verdict-kind.js +19 -0
- package/dist/doctor-verdict.d.ts +18 -0
- package/dist/doctor-verdict.d.ts.map +1 -0
- package/dist/doctor-verdict.js +28 -0
- package/dist/drift.d.ts +17 -0
- package/dist/drift.d.ts.map +1 -1
- package/dist/drift.js +40 -10
- package/dist/entrypoint-matrix.d.ts.map +1 -1
- package/dist/entrypoint-matrix.js +4 -1
- package/dist/feedback-ingestion.d.ts +28 -2
- package/dist/feedback-ingestion.d.ts.map +1 -1
- package/dist/feedback-ingestion.js +68 -19
- package/dist/fix-preview.d.ts.map +1 -1
- package/dist/fix-preview.js +9 -5
- package/dist/framework-extractor-outcomes.d.ts +27 -0
- package/dist/framework-extractor-outcomes.d.ts.map +1 -0
- package/dist/framework-extractor-outcomes.js +83 -0
- package/dist/fuzzy-impact.js +1 -1
- package/dist/healing-plan.d.ts.map +1 -1
- package/dist/healing-plan.js +3 -4
- package/dist/helper-catalog.d.ts +25 -0
- package/dist/helper-catalog.d.ts.map +1 -0
- package/dist/helper-catalog.js +91 -0
- package/dist/helper-registry.d.ts.map +1 -1
- package/dist/helper-registry.js +17 -1
- package/dist/helper-view.d.ts +33 -0
- package/dist/helper-view.d.ts.map +1 -0
- package/dist/helper-view.js +1 -0
- package/dist/i-asset-doctor-flags.d.ts +16 -0
- package/dist/i-asset-doctor-flags.d.ts.map +1 -0
- package/dist/i-asset-doctor-flags.js +1 -0
- package/dist/i-command-resolution.d.ts +22 -0
- package/dist/i-command-resolution.d.ts.map +1 -0
- package/dist/i-command-resolution.js +1 -0
- package/dist/i-command-resolve-options.d.ts +24 -0
- package/dist/i-command-resolve-options.d.ts.map +1 -0
- package/dist/i-command-resolve-options.js +1 -0
- package/dist/i-command-safety.d.ts +13 -0
- package/dist/i-command-safety.d.ts.map +1 -0
- package/dist/i-command-safety.js +1 -0
- package/dist/i-contribution-accepted-entry.d.ts +18 -0
- package/dist/i-contribution-accepted-entry.d.ts.map +1 -0
- package/dist/i-contribution-accepted-entry.js +1 -0
- package/dist/i-contribution-entry-rejection.d.ts +21 -0
- package/dist/i-contribution-entry-rejection.d.ts.map +1 -0
- package/dist/i-contribution-entry-rejection.js +1 -0
- package/dist/i-contribution-file-issue.d.ts +18 -0
- package/dist/i-contribution-file-issue.d.ts.map +1 -0
- package/dist/i-contribution-file-issue.js +1 -0
- package/dist/i-contribution-file-report.d.ts +40 -0
- package/dist/i-contribution-file-report.d.ts.map +1 -0
- package/dist/i-contribution-file-report.js +1 -0
- package/dist/i-contribution-file-validation.d.ts +24 -0
- package/dist/i-contribution-file-validation.d.ts.map +1 -0
- package/dist/i-contribution-file-validation.js +1 -0
- package/dist/i-contributions-report.d.ts +31 -0
- package/dist/i-contributions-report.d.ts.map +1 -0
- package/dist/i-contributions-report.js +1 -0
- package/dist/i-declared-xref-field.d.ts +25 -0
- package/dist/i-declared-xref-field.d.ts.map +1 -0
- package/dist/i-declared-xref-field.js +1 -0
- package/dist/i-declared-xref-issue.d.ts +25 -0
- package/dist/i-declared-xref-issue.d.ts.map +1 -0
- package/dist/i-declared-xref-issue.js +1 -0
- package/dist/i-declared-xref-report.d.ts +48 -0
- package/dist/i-declared-xref-report.d.ts.map +1 -0
- package/dist/i-declared-xref-report.js +1 -0
- package/dist/i-declared-xref-row.d.ts +29 -0
- package/dist/i-declared-xref-row.d.ts.map +1 -0
- package/dist/i-declared-xref-row.js +1 -0
- package/dist/i-doctor-verdict.d.ts +10 -0
- package/dist/i-doctor-verdict.d.ts.map +1 -0
- package/dist/i-doctor-verdict.js +1 -0
- package/dist/i-kind-outcomes.d.ts +13 -0
- package/dist/i-kind-outcomes.d.ts.map +1 -0
- package/dist/i-kind-outcomes.js +1 -0
- package/dist/i-pack-doctor-verdict.d.ts +15 -0
- package/dist/i-pack-doctor-verdict.d.ts.map +1 -0
- package/dist/i-pack-doctor-verdict.js +1 -0
- package/dist/i-probed-id-field.d.ts +17 -0
- package/dist/i-probed-id-field.d.ts.map +1 -0
- package/dist/i-probed-id-field.js +1 -0
- package/dist/i-reference-kind-declaration.d.ts +38 -0
- package/dist/i-reference-kind-declaration.d.ts.map +1 -0
- package/dist/i-reference-kind-declaration.js +1 -0
- package/dist/i-reference-warm-options.d.ts +21 -0
- package/dist/i-reference-warm-options.d.ts.map +1 -0
- package/dist/i-reference-warm-options.js +1 -0
- package/dist/i-registry-outcomes.d.ts +16 -0
- package/dist/i-registry-outcomes.d.ts.map +1 -0
- package/dist/i-registry-outcomes.js +1 -0
- package/dist/i-scaffold-pattern-doctor-report.d.ts +35 -0
- package/dist/i-scaffold-pattern-doctor-report.d.ts.map +1 -0
- package/dist/i-scaffold-pattern-doctor-report.js +1 -0
- package/dist/i-search-tuning-key-probe.d.ts +30 -0
- package/dist/i-search-tuning-key-probe.d.ts.map +1 -0
- package/dist/i-search-tuning-key-probe.js +1 -0
- package/dist/i-search-tuning-lint-issue.d.ts +61 -0
- package/dist/i-search-tuning-lint-issue.d.ts.map +1 -0
- package/dist/i-search-tuning-lint-issue.js +1 -0
- package/dist/i-search-tuning-lint-report.d.ts +38 -0
- package/dist/i-search-tuning-lint-report.d.ts.map +1 -0
- package/dist/i-search-tuning-lint-report.js +1 -0
- package/dist/i-unresolvable-reference-scan.d.ts +14 -0
- package/dist/i-unresolvable-reference-scan.d.ts.map +1 -0
- package/dist/i-unresolvable-reference-scan.js +1 -0
- package/dist/i-unresolvable-reference.d.ts +29 -0
- package/dist/i-unresolvable-reference.d.ts.map +1 -0
- package/dist/i-unresolvable-reference.js +1 -0
- package/dist/i-workspace-profile-payload.d.ts +12 -0
- package/dist/i-workspace-profile-payload.d.ts.map +1 -0
- package/dist/i-workspace-profile-payload.js +1 -0
- package/dist/impact-analysis.d.ts +15 -0
- package/dist/impact-analysis.d.ts.map +1 -1
- package/dist/impact-analysis.js +58 -13
- package/dist/impact-render.d.ts.map +1 -1
- package/dist/impact-render.js +22 -0
- package/dist/import-hygiene.d.ts +35 -1
- package/dist/import-hygiene.d.ts.map +1 -1
- package/dist/import-hygiene.js +107 -13
- package/dist/index.d.ts +141 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +172 -0
- package/dist/inspection-discovery.d.ts +45 -0
- package/dist/inspection-discovery.d.ts.map +1 -0
- package/dist/inspection-discovery.js +70 -0
- package/dist/knowledge-advisory-code.d.ts +17 -0
- package/dist/knowledge-advisory-code.d.ts.map +1 -0
- package/dist/knowledge-advisory-code.js +17 -0
- package/dist/knowledge-aged-entry.d.ts +10 -0
- package/dist/knowledge-aged-entry.d.ts.map +1 -0
- package/dist/knowledge-aged-entry.js +1 -0
- package/dist/knowledge-authoring.d.ts +24 -1
- package/dist/knowledge-authoring.d.ts.map +1 -1
- package/dist/knowledge-authoring.js +46 -7
- package/dist/knowledge-entry-verdict-record.d.ts +22 -0
- package/dist/knowledge-entry-verdict-record.d.ts.map +1 -0
- package/dist/knowledge-entry-verdict-record.js +1 -0
- package/dist/knowledge-entry-verdict.d.ts +17 -0
- package/dist/knowledge-entry-verdict.d.ts.map +1 -0
- package/dist/knowledge-entry-verdict.js +17 -0
- package/dist/knowledge-graph.d.ts +6 -0
- package/dist/knowledge-graph.d.ts.map +1 -1
- package/dist/knowledge-graph.js +18 -7
- package/dist/knowledge-kind-bucket.d.ts +19 -0
- package/dist/knowledge-kind-bucket.d.ts.map +1 -0
- package/dist/knowledge-kind-bucket.js +1 -0
- package/dist/knowledge-load-failure.d.ts +23 -0
- package/dist/knowledge-load-failure.d.ts.map +1 -0
- package/dist/knowledge-load-failure.js +1 -0
- package/dist/knowledge-reference-kind-bucket.d.ts +11 -0
- package/dist/knowledge-reference-kind-bucket.d.ts.map +1 -0
- package/dist/knowledge-reference-kind-bucket.js +1 -0
- package/dist/knowledge-stale-advisory.d.ts +14 -0
- package/dist/knowledge-stale-advisory.d.ts.map +1 -0
- package/dist/knowledge-stale-advisory.js +1 -0
- package/dist/knowledge-stale-coverage.d.ts +19 -0
- package/dist/knowledge-stale-coverage.d.ts.map +1 -0
- package/dist/knowledge-stale-coverage.js +1 -0
- package/dist/knowledge-stale-gate-flags.d.ts +33 -0
- package/dist/knowledge-stale-gate-flags.d.ts.map +1 -0
- package/dist/knowledge-stale-gate-flags.js +1 -0
- package/dist/knowledge-stale-gate-input.d.ts +46 -0
- package/dist/knowledge-stale-gate-input.d.ts.map +1 -0
- package/dist/knowledge-stale-gate-input.js +1 -0
- package/dist/knowledge-stale-gate-result.d.ts +33 -0
- package/dist/knowledge-stale-gate-result.d.ts.map +1 -0
- package/dist/knowledge-stale-gate-result.js +1 -0
- package/dist/knowledge-stale-gate-rule.d.ts +33 -0
- package/dist/knowledge-stale-gate-rule.d.ts.map +1 -0
- package/dist/knowledge-stale-gate-rule.js +1 -0
- package/dist/knowledge-stale-gate-violation.d.ts +13 -0
- package/dist/knowledge-stale-gate-violation.d.ts.map +1 -0
- package/dist/knowledge-stale-gate-violation.js +1 -0
- package/dist/knowledge-stale-gate.d.ts +83 -0
- package/dist/knowledge-stale-gate.d.ts.map +1 -0
- package/dist/knowledge-stale-gate.js +429 -0
- package/dist/knowledge-stale-quality-gate.d.ts +26 -0
- package/dist/knowledge-stale-quality-gate.d.ts.map +1 -0
- package/dist/knowledge-stale-quality-gate.js +110 -0
- package/dist/knowledge-stale.d.ts +122 -9
- package/dist/knowledge-stale.d.ts.map +1 -1
- package/dist/knowledge-stale.js +996 -291
- package/dist/knowledge-unverifiable-reason.d.ts +12 -0
- package/dist/knowledge-unverifiable-reason.d.ts.map +1 -0
- package/dist/knowledge-unverifiable-reason.js +12 -0
- package/dist/loader-diagnostics.d.ts +14 -2
- package/dist/loader-diagnostics.d.ts.map +1 -1
- package/dist/match-terms.d.ts +48 -0
- package/dist/match-terms.d.ts.map +1 -0
- package/dist/match-terms.js +155 -0
- package/dist/migration-profile-registry.d.ts +10 -0
- package/dist/migration-profile-registry.d.ts.map +1 -1
- package/dist/migration-profile-registry.js +57 -34
- package/dist/migration-readiness.d.ts.map +1 -1
- package/dist/migration-readiness.js +1 -3
- package/dist/nearest-id.d.ts +10 -26
- package/dist/nearest-id.d.ts.map +1 -1
- package/dist/nearest-id.js +9 -59
- package/dist/pack-asset-freshness.d.ts +65 -0
- package/dist/pack-asset-freshness.d.ts.map +1 -0
- package/dist/pack-asset-freshness.js +340 -0
- package/dist/pack-author-ux.d.ts +24 -3
- package/dist/pack-author-ux.d.ts.map +1 -1
- package/dist/pack-author-ux.js +87 -93
- package/dist/pack-contributions-inventory.d.ts +79 -39
- package/dist/pack-contributions-inventory.d.ts.map +1 -1
- package/dist/pack-contributions-inventory.js +443 -286
- package/dist/pack-doctor-verdict.d.ts +29 -0
- package/dist/pack-doctor-verdict.d.ts.map +1 -0
- package/dist/pack-doctor-verdict.js +45 -0
- package/dist/pack-doctor.d.ts +74 -1
- package/dist/pack-doctor.d.ts.map +1 -1
- package/dist/pack-doctor.js +281 -1
- package/dist/pack-helper-plan.d.ts +24 -0
- package/dist/pack-helper-plan.d.ts.map +1 -0
- package/dist/pack-helper-plan.js +77 -0
- package/dist/pack-helper-registry.d.ts +14 -0
- package/dist/pack-helper-registry.d.ts.map +1 -1
- package/dist/pack-helper-registry.js +76 -37
- package/dist/pack-manifest-reader.d.ts +8 -0
- package/dist/pack-manifest-reader.d.ts.map +1 -0
- package/dist/pack-manifest-reader.js +79 -0
- package/dist/pack-release-check.d.ts +14 -1
- package/dist/pack-release-check.d.ts.map +1 -1
- package/dist/pack-release-check.js +23 -1
- package/dist/pack-signature-status.d.ts +18 -6
- package/dist/pack-signature-status.d.ts.map +1 -1
- package/dist/pack-signature-status.js +59 -105
- package/dist/pack-test-runner.d.ts +27 -5
- package/dist/pack-test-runner.d.ts.map +1 -1
- package/dist/pack-test-runner.js +91 -35
- package/dist/pack-typecheck.d.ts +8 -0
- package/dist/pack-typecheck.d.ts.map +1 -0
- package/dist/pack-typecheck.js +76 -0
- package/dist/plan-review.d.ts +2 -0
- package/dist/plan-review.d.ts.map +1 -1
- package/dist/plan-review.js +17 -5
- package/dist/plan-simulation.d.ts.map +1 -1
- package/dist/plan-simulation.js +16 -5
- package/dist/playbook-load-issue.d.ts +16 -0
- package/dist/playbook-load-issue.d.ts.map +1 -0
- package/dist/playbook-load-issue.js +1 -0
- package/dist/playbook-registry.d.ts +32 -1
- package/dist/playbook-registry.d.ts.map +1 -1
- package/dist/playbook-registry.js +144 -55
- package/dist/policy-declaration.d.ts +18 -0
- package/dist/policy-declaration.d.ts.map +1 -0
- package/dist/policy-declaration.js +1 -0
- package/dist/policy-engine.d.ts +8 -0
- package/dist/policy-engine.d.ts.map +1 -1
- package/dist/policy-engine.js +26 -9
- package/dist/policy-overrides.d.ts.map +1 -1
- package/dist/policy-overrides.js +4 -4
- package/dist/policy-registry.d.ts +27 -0
- package/dist/policy-registry.d.ts.map +1 -1
- package/dist/policy-registry.js +87 -20
- package/dist/probed-id-fields.d.ts +21 -0
- package/dist/probed-id-fields.d.ts.map +1 -0
- package/dist/probed-id-fields.js +25 -0
- package/dist/probed-id-source.d.ts +11 -0
- package/dist/probed-id-source.d.ts.map +1 -0
- package/dist/probed-id-source.js +11 -0
- package/dist/profile-registry.d.ts +25 -2
- package/dist/profile-registry.d.ts.map +1 -1
- package/dist/profile-registry.js +59 -6
- package/dist/quality-gate-examination.d.ts +15 -0
- package/dist/quality-gate-examination.d.ts.map +1 -0
- package/dist/quality-gate-examination.js +15 -0
- package/dist/quality-gate-row-status.d.ts +19 -0
- package/dist/quality-gate-row-status.d.ts.map +1 -0
- package/dist/quality-gate-row-status.js +28 -0
- package/dist/quality-gate-status.d.ts +16 -0
- package/dist/quality-gate-status.d.ts.map +1 -0
- package/dist/quality-gate-status.js +16 -0
- package/dist/quality-html.d.ts.map +1 -1
- package/dist/quality-html.js +14 -3
- package/dist/quality-report-coverage.d.ts +26 -0
- package/dist/quality-report-coverage.d.ts.map +1 -0
- package/dist/quality-report-coverage.js +48 -0
- package/dist/quality-report.d.ts +28 -1
- package/dist/quality-report.d.ts.map +1 -1
- package/dist/quality-report.js +263 -35
- package/dist/query-intent-kind.d.ts +18 -0
- package/dist/query-intent-kind.d.ts.map +1 -0
- package/dist/query-intent-kind.js +18 -0
- package/dist/query-intent-result.d.ts +23 -0
- package/dist/query-intent-result.d.ts.map +1 -0
- package/dist/query-intent-result.js +1 -0
- package/dist/query-intent.d.ts +18 -0
- package/dist/query-intent.d.ts.map +1 -0
- package/dist/query-intent.js +336 -0
- package/dist/query-resolver.d.ts +18 -0
- package/dist/query-resolver.d.ts.map +1 -1
- package/dist/query-resolver.js +7 -4
- package/dist/ranked-recommendations.d.ts +36 -0
- package/dist/ranked-recommendations.d.ts.map +1 -0
- package/dist/ranked-recommendations.js +1 -0
- package/dist/ranker-explainability.d.ts.map +1 -1
- package/dist/ranker-explainability.js +38 -10
- package/dist/recommend-recipe.d.ts +17 -0
- package/dist/recommend-recipe.d.ts.map +1 -0
- package/dist/recommend-recipe.js +1 -0
- package/dist/recommend-recipes.d.ts +9 -0
- package/dist/recommend-recipes.d.ts.map +1 -0
- package/dist/recommend-recipes.js +106 -0
- package/dist/recommendation-candidate.d.ts +30 -0
- package/dist/recommendation-candidate.d.ts.map +1 -0
- package/dist/recommendation-candidate.js +1 -0
- package/dist/recommendation-confidence.d.ts +27 -0
- package/dist/recommendation-confidence.d.ts.map +1 -0
- package/dist/recommendation-confidence.js +1 -0
- package/dist/recommendation-ranking-options.d.ts +24 -0
- package/dist/recommendation-ranking-options.d.ts.map +1 -0
- package/dist/recommendation-ranking-options.js +1 -0
- package/dist/recommendation-ranking.d.ts +50 -0
- package/dist/recommendation-ranking.d.ts.map +1 -0
- package/dist/recommendation-ranking.js +527 -0
- package/dist/recommendation-source.d.ts +23 -0
- package/dist/recommendation-source.d.ts.map +1 -0
- package/dist/recommendation-source.js +23 -0
- package/dist/recommendation-suppression.d.ts +14 -0
- package/dist/recommendation-suppression.d.ts.map +1 -0
- package/dist/recommendation-suppression.js +14 -0
- package/dist/reference-asset-kind.d.ts +14 -0
- package/dist/reference-asset-kind.d.ts.map +1 -0
- package/dist/reference-asset-kind.js +14 -0
- package/dist/reference-content-check.d.ts +32 -0
- package/dist/reference-content-check.d.ts.map +1 -0
- package/dist/reference-content-check.js +143 -0
- package/dist/reference-failure.d.ts +31 -0
- package/dist/reference-failure.d.ts.map +1 -0
- package/dist/reference-failure.js +31 -0
- package/dist/reference-id-status.d.ts +15 -0
- package/dist/reference-id-status.d.ts.map +1 -0
- package/dist/reference-id-status.js +15 -0
- package/dist/reference-kind-declarations.d.ts +42 -0
- package/dist/reference-kind-declarations.d.ts.map +1 -0
- package/dist/reference-kind-declarations.js +142 -0
- package/dist/reference-lookup.d.ts +6 -0
- package/dist/reference-lookup.d.ts.map +1 -1
- package/dist/reference-lookup.js +13 -5
- package/dist/reference-registry.d.ts +109 -11
- package/dist/reference-registry.d.ts.map +1 -1
- package/dist/reference-registry.js +186 -30
- package/dist/reference-subject.d.ts +20 -0
- package/dist/reference-subject.d.ts.map +1 -0
- package/dist/reference-subject.js +1 -0
- package/dist/registration-hint-discovery-status.d.ts +25 -0
- package/dist/registration-hint-discovery-status.d.ts.map +1 -0
- package/dist/registration-hint-discovery-status.js +25 -0
- package/dist/registration-hint-registry.d.ts +80 -0
- package/dist/registration-hint-registry.d.ts.map +1 -1
- package/dist/registration-hint-registry.js +356 -138
- package/dist/registry-lifecycle.d.ts +200 -19
- package/dist/registry-lifecycle.d.ts.map +1 -1
- package/dist/registry-lifecycle.js +526 -136
- package/dist/release-readiness.d.ts.map +1 -1
- package/dist/release-readiness.js +10 -7
- package/dist/release-smoke.d.ts.map +1 -1
- package/dist/release-smoke.js +11 -7
- package/dist/report-site.d.ts.map +1 -1
- package/dist/report-site.js +25 -7
- package/dist/repository-intelligence.d.ts.map +1 -1
- package/dist/repository-intelligence.js +3 -2
- package/dist/repository-knowledge-model.d.ts.map +1 -1
- package/dist/repository-knowledge-model.js +18 -5
- package/dist/resolve-project-config.d.ts +64 -0
- package/dist/resolve-project-config.d.ts.map +1 -1
- package/dist/resolve-project-config.js +240 -32
- package/dist/reuse/compute-reuse-coverage.d.ts +29 -0
- package/dist/reuse/compute-reuse-coverage.d.ts.map +1 -0
- package/dist/reuse/compute-reuse-coverage.js +198 -0
- package/dist/reuse/rank-reuse-candidates.d.ts +38 -0
- package/dist/reuse/rank-reuse-candidates.d.ts.map +1 -0
- package/dist/reuse/rank-reuse-candidates.js +212 -0
- package/dist/reuse/rank-reuse-options.d.ts +20 -0
- package/dist/reuse/rank-reuse-options.d.ts.map +1 -0
- package/dist/reuse/rank-reuse-options.js +1 -0
- package/dist/reuse/rank-reuse-suggestions.d.ts +15 -0
- package/dist/reuse/rank-reuse-suggestions.d.ts.map +1 -0
- package/dist/reuse/rank-reuse-suggestions.js +31 -0
- package/dist/reuse/resolve-curated-reuse.d.ts +43 -0
- package/dist/reuse/resolve-curated-reuse.d.ts.map +1 -0
- package/dist/reuse/resolve-curated-reuse.js +115 -0
- package/dist/reuse/reuse-candidate.d.ts +29 -0
- package/dist/reuse/reuse-candidate.d.ts.map +1 -0
- package/dist/reuse/reuse-candidate.js +1 -0
- package/dist/reuse/reuse-coverage-report.d.ts +74 -0
- package/dist/reuse/reuse-coverage-report.d.ts.map +1 -0
- package/dist/reuse/reuse-coverage-report.js +1 -0
- package/dist/reuse/reuse-curated-coverage.d.ts +36 -0
- package/dist/reuse/reuse-curated-coverage.d.ts.map +1 -0
- package/dist/reuse/reuse-curated-coverage.js +1 -0
- package/dist/reuse/reuse-curated-resolution.d.ts +36 -0
- package/dist/reuse/reuse-curated-resolution.d.ts.map +1 -0
- package/dist/reuse/reuse-curated-resolution.js +1 -0
- package/dist/reuse/reuse-curated-status.d.ts +21 -0
- package/dist/reuse/reuse-curated-status.d.ts.map +1 -0
- package/dist/reuse/reuse-curated-status.js +21 -0
- package/dist/reuse/reuse-match-detail.d.ts +15 -0
- package/dist/reuse/reuse-match-detail.d.ts.map +1 -0
- package/dist/reuse/reuse-match-detail.js +1 -0
- package/dist/reuse/reuse-ranking.d.ts +37 -0
- package/dist/reuse/reuse-ranking.d.ts.map +1 -0
- package/dist/reuse/reuse-ranking.js +1 -0
- package/dist/reuse/reuse-suggestion.d.ts +19 -0
- package/dist/reuse/reuse-suggestion.d.ts.map +1 -0
- package/dist/reuse/reuse-suggestion.js +1 -0
- package/dist/reuse/reuse-symbol-lookup.d.ts +28 -0
- package/dist/reuse/reuse-symbol-lookup.d.ts.map +1 -0
- package/dist/reuse/reuse-symbol-lookup.js +1 -0
- package/dist/reuse/reuse-tokenize.d.ts +11 -0
- package/dist/reuse/reuse-tokenize.d.ts.map +1 -0
- package/dist/reuse/reuse-tokenize.js +26 -0
- package/dist/reuse/score-reuse-name.d.ts +16 -0
- package/dist/reuse/score-reuse-name.d.ts.map +1 -0
- package/dist/reuse/score-reuse-name.js +35 -0
- package/dist/reuse/score-reuse-primitive.d.ts +33 -0
- package/dist/reuse/score-reuse-primitive.d.ts.map +1 -0
- package/dist/reuse/score-reuse-primitive.js +92 -0
- package/dist/review-packet.d.ts +2 -0
- package/dist/review-packet.d.ts.map +1 -1
- package/dist/review-packet.js +13 -6
- package/dist/role-views.d.ts.map +1 -1
- package/dist/role-views.js +16 -16
- package/dist/routing-recommends-channels.d.ts +24 -0
- package/dist/routing-recommends-channels.d.ts.map +1 -0
- package/dist/routing-recommends-channels.js +19 -0
- package/dist/run-boundary-check.d.ts +118 -0
- package/dist/run-boundary-check.d.ts.map +1 -0
- package/dist/run-boundary-check.js +592 -0
- package/dist/safety-audit.js +1 -1
- package/dist/scaffold-coverage.js +1 -1
- package/dist/scaffold-pattern-doctor-report.d.ts +19 -0
- package/dist/scaffold-pattern-doctor-report.d.ts.map +1 -0
- package/dist/scaffold-pattern-doctor-report.js +54 -0
- package/dist/scaffold-patterns.d.ts +75 -1
- package/dist/scaffold-patterns.d.ts.map +1 -1
- package/dist/scaffold-patterns.js +375 -84
- package/dist/schema-inventory.d.ts.map +1 -1
- package/dist/schema-inventory.js +4 -3
- package/dist/search-document-id.d.ts +52 -0
- package/dist/search-document-id.d.ts.map +1 -0
- package/dist/search-document-id.js +72 -0
- package/dist/search-document-prefix.d.ts +7 -0
- package/dist/search-document-prefix.d.ts.map +1 -0
- package/dist/search-document-prefix.js +1 -0
- package/dist/search-index.d.ts.map +1 -1
- package/dist/search-index.js +20 -23
- package/dist/search-tuning-explain.d.ts +6 -0
- package/dist/search-tuning-explain.d.ts.map +1 -1
- package/dist/search-tuning-explain.js +19 -17
- package/dist/search-tuning-key-probes.d.ts +16 -0
- package/dist/search-tuning-key-probes.d.ts.map +1 -0
- package/dist/search-tuning-key-probes.js +65 -0
- package/dist/search-tuning-key-resolution.d.ts +25 -0
- package/dist/search-tuning-key-resolution.d.ts.map +1 -0
- package/dist/search-tuning-key-resolution.js +1 -0
- package/dist/search-tuning-key-resolver.d.ts +4 -0
- package/dist/search-tuning-key-resolver.d.ts.map +1 -0
- package/dist/search-tuning-key-resolver.js +107 -0
- package/dist/search-tuning-key-status.d.ts +24 -0
- package/dist/search-tuning-key-status.d.ts.map +1 -0
- package/dist/search-tuning-key-status.js +24 -0
- package/dist/search-tuning-lint.d.ts +9 -0
- package/dist/search-tuning-lint.d.ts.map +1 -0
- package/dist/search-tuning-lint.js +468 -0
- package/dist/search-tuning-registry.d.ts +43 -0
- package/dist/search-tuning-registry.d.ts.map +1 -1
- package/dist/search-tuning-registry.js +214 -49
- package/dist/self-audit.d.ts +12 -0
- package/dist/self-audit.d.ts.map +1 -1
- package/dist/self-audit.js +36 -10
- package/dist/self-config-doctor-v2.d.ts +145 -3
- package/dist/self-config-doctor-v2.d.ts.map +1 -1
- package/dist/self-config-doctor-v2.js +1304 -181
- package/dist/self-config-doctor.d.ts +20 -1
- package/dist/self-config-doctor.d.ts.map +1 -1
- package/dist/self-config-doctor.js +53 -280
- package/dist/settled-unit-states.d.ts +9 -0
- package/dist/settled-unit-states.d.ts.map +1 -0
- package/dist/settled-unit-states.js +14 -0
- package/dist/sharkcraft-inspector.d.ts +34 -0
- package/dist/sharkcraft-inspector.d.ts.map +1 -1
- package/dist/sharkcraft-inspector.js +273 -26
- package/dist/spec/spec-evidence.d.ts.map +1 -1
- package/dist/spec/spec-evidence.js +14 -20
- package/dist/split-identifier.d.ts +21 -0
- package/dist/split-identifier.d.ts.map +1 -0
- package/dist/split-identifier.js +27 -0
- package/dist/start-here.d.ts.map +1 -1
- package/dist/start-here.js +1 -2
- package/dist/substitute-placeholders.d.ts +8 -0
- package/dist/substitute-placeholders.d.ts.map +1 -0
- package/dist/substitute-placeholders.js +9 -0
- package/dist/symbol-index.d.ts +33 -0
- package/dist/symbol-index.d.ts.map +1 -1
- package/dist/symbol-index.js +241 -3
- package/dist/symbol-member-entry.d.ts +26 -0
- package/dist/symbol-member-entry.d.ts.map +1 -0
- package/dist/symbol-member-entry.js +1 -0
- package/dist/symbol-member-kind.d.ts +14 -0
- package/dist/symbol-member-kind.d.ts.map +1 -0
- package/dist/symbol-member-kind.js +14 -0
- package/dist/task-packet.d.ts.map +1 -1
- package/dist/task-packet.js +52 -9
- package/dist/task-ranker.d.ts +8 -0
- package/dist/task-ranker.d.ts.map +1 -1
- package/dist/task-ranker.js +25 -13
- package/dist/task-risk.js +1 -1
- package/dist/task-routing-hint-registry.d.ts +20 -1
- package/dist/task-routing-hint-registry.d.ts.map +1 -1
- package/dist/task-routing-hint-registry.js +186 -42
- package/dist/template-drift.d.ts.map +1 -1
- package/dist/template-drift.js +30 -9
- package/dist/template-lint.d.ts.map +1 -1
- package/dist/template-lint.js +160 -2
- package/dist/term-query.d.ts +10 -0
- package/dist/term-query.d.ts.map +1 -0
- package/dist/term-query.js +1 -0
- package/dist/test-definitions.d.ts +6 -3
- package/dist/test-definitions.d.ts.map +1 -1
- package/dist/test-runner.d.ts +95 -10
- package/dist/test-runner.d.ts.map +1 -1
- package/dist/test-runner.js +309 -308
- package/dist/tuning-query-tokens.d.ts +29 -0
- package/dist/tuning-query-tokens.d.ts.map +1 -0
- package/dist/tuning-query-tokens.js +51 -0
- package/dist/typecheck-files.d.ts +36 -0
- package/dist/typecheck-files.d.ts.map +1 -0
- package/dist/typecheck-files.js +158 -0
- package/dist/uncertainty.js +1 -1
- package/dist/universal-search.d.ts.map +1 -1
- package/dist/universal-search.js +5 -3
- package/dist/unregistered-exports.d.ts +19 -0
- package/dist/unregistered-exports.d.ts.map +1 -0
- package/dist/unregistered-exports.js +141 -0
- package/dist/unresolvable-reason.d.ts +11 -0
- package/dist/unresolvable-reason.d.ts.map +1 -0
- package/dist/unresolvable-reason.js +11 -0
- package/dist/upgrade-advisor.d.ts.map +1 -1
- package/dist/upgrade-advisor.js +16 -9
- package/dist/validate-contribution-file.d.ts +4 -0
- package/dist/validate-contribution-file.d.ts.map +1 -0
- package/dist/validate-contribution-file.js +228 -0
- package/dist/why-file.d.ts +3 -0
- package/dist/why-file.d.ts.map +1 -1
- package/dist/why-file.js +7 -3
- package/package.json +17 -17
|
@@ -0,0 +1,592 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import * as nodePath from 'node:path';
|
|
3
|
+
import { ruleVerdictRecords, selectorUnitFails, settleVerdict, UnitLivenessState, } from '@shrkcrft/core';
|
|
4
|
+
import { boundaryRuleScope, boundaryScopeCoversUnread, boundaryScopeDecision, boundaryUnitFinding, evaluateBoundaries, isUnreadDirectory, loadTsconfigPaths, nodeBuiltinPackageNames, readScopeCoverage, scanImports, unreadDirectoryContains, UnreadFileReason, } from '@shrkcrft/boundaries';
|
|
5
|
+
import { filterViolationsToChangedScope, resolveChangedFiles, } from "./boundaries-changed-only.js";
|
|
6
|
+
import { boundaryFileLabel, describeBoundaryConfiguration } from "./boundary-configuration-status.js";
|
|
7
|
+
import { resolveBoundaryRuleInvalidation } from "./boundary-rule-sources.js";
|
|
8
|
+
import { boundaryUnitLiveness } from "./boundary-unit-liveness.js";
|
|
9
|
+
/**
|
|
10
|
+
* THE boundary orchestrator (round 11, C#one-boundary-check-authority).
|
|
11
|
+
*
|
|
12
|
+
* `check boundaries`, finish's boundaries gate, `diff-check`, quality and both
|
|
13
|
+
* MCP boundary tools used to hand-assemble scan + evaluate each — and they
|
|
14
|
+
* disagreed: the MCP tools never loaded the tsconfig alias map, so an
|
|
15
|
+
* alias-resolved violation the CLI reported was invisible to an agent. This is
|
|
16
|
+
* now the only place that:
|
|
17
|
+
*
|
|
18
|
+
* - loads tsconfig paths and builds the known-package list;
|
|
19
|
+
* - runs scanImports + evaluateBoundaries;
|
|
20
|
+
* - applies the changed-scope filter WITH rule escalation (a rule edit's
|
|
21
|
+
* violations are never filed as "legacy");
|
|
22
|
+
* - turns load issues into errored rules and stale exceptions into findings;
|
|
23
|
+
* - re-settles every rule over what could not be read (`boundaryUnitLiveness`);
|
|
24
|
+
* - computes the proposed 0/1/2/3 exit and its coverage, and settles it.
|
|
25
|
+
*
|
|
26
|
+
* The CLI builds its gate envelope from `proposedExit` + the coverage records
|
|
27
|
+
* here (and adds its own `--allow-empty` valve). Both sides settle with core's
|
|
28
|
+
* `settleVerdict` — ONE fold, not a copy per layer — and
|
|
29
|
+
* `r75-boundary-parity.test.ts` asserts the envelope's exit equals `exitCode`.
|
|
30
|
+
*/
|
|
31
|
+
export function runBoundaryCheck(inspection, options = {}) {
|
|
32
|
+
const projectRoot = inspection.projectRoot;
|
|
33
|
+
const ruleFile = options.ruleFile;
|
|
34
|
+
const sourceRules = ruleFile ? ruleFile.rules : inspection.boundaryRegistry.list();
|
|
35
|
+
const loadIssues = ruleFile
|
|
36
|
+
? [...(ruleFile.loadIssues ?? [])]
|
|
37
|
+
: [...(inspection.boundaryLoadIssues ?? [])];
|
|
38
|
+
const configuration = ruleFile ? undefined : describeBoundaryConfiguration(inspection);
|
|
39
|
+
const ruleSource = ruleFile
|
|
40
|
+
? { kind: 'rule-file', path: ruleFile.path }
|
|
41
|
+
: { kind: 'registry' };
|
|
42
|
+
if (options.onlyRuleId !== undefined && !sourceRules.some((r) => r.id === options.onlyRuleId)) {
|
|
43
|
+
// A typo'd `--rule` used to narrow the run to zero rules and report a
|
|
44
|
+
// confident pass over nothing. The request itself is malformed: 3.
|
|
45
|
+
const scan = { filesScanned: 0, edges: [], warnings: [], files: [], manifestFiles: [] };
|
|
46
|
+
const runCoverage = {
|
|
47
|
+
unit: 'rules',
|
|
48
|
+
expected: 0,
|
|
49
|
+
examined: 0,
|
|
50
|
+
reason: `no boundary rule "${options.onlyRuleId}"`,
|
|
51
|
+
root: projectRoot,
|
|
52
|
+
};
|
|
53
|
+
return {
|
|
54
|
+
schema: 'sharkcraft.boundary-check/v1',
|
|
55
|
+
projectRoot,
|
|
56
|
+
ruleSource,
|
|
57
|
+
rulesConfigured: sourceRules.length,
|
|
58
|
+
selectedRuleIds: [],
|
|
59
|
+
scan,
|
|
60
|
+
evaluation: evaluateBoundaries(scan, []),
|
|
61
|
+
rules: [],
|
|
62
|
+
violations: [],
|
|
63
|
+
counts: { error: 0, warning: 0, info: 0 },
|
|
64
|
+
suppressed: [],
|
|
65
|
+
staleExceptions: [],
|
|
66
|
+
deadUnits: [],
|
|
67
|
+
intendedEmpty: [],
|
|
68
|
+
wentLive: [],
|
|
69
|
+
failingUnits: [],
|
|
70
|
+
loadIssues,
|
|
71
|
+
...(configuration ? { configuration } : {}),
|
|
72
|
+
runCoverage,
|
|
73
|
+
proposedExit: 3,
|
|
74
|
+
exitCode: 3,
|
|
75
|
+
verdict: 'usage-error',
|
|
76
|
+
shortfalls: [],
|
|
77
|
+
accepted: [],
|
|
78
|
+
unknownRuleId: options.onlyRuleId,
|
|
79
|
+
availableRuleIds: sourceRules.map((r) => r.id),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const rules = options.onlyRuleId ? sourceRules.filter((r) => r.id === options.onlyRuleId) : [...sourceRules];
|
|
83
|
+
const scan = options.scan ?? scanImports({ projectRoot, includeComments: options.includeComments === true });
|
|
84
|
+
const evaluation = evaluateBoundaries(scan, rules, evaluateOptionsFor(projectRoot, scan));
|
|
85
|
+
const detailById = new Map(evaluation.coverage.map((c) => [c.ruleId, c]));
|
|
86
|
+
const sourceFileOf = (ruleId) => {
|
|
87
|
+
if (ruleFile)
|
|
88
|
+
return boundaryFileLabel(projectRoot, ruleFile.path);
|
|
89
|
+
const src = inspection.boundarySources.get(ruleId);
|
|
90
|
+
return src?.file ? boundaryFileLabel(projectRoot, src.file) : '(unknown rule source)';
|
|
91
|
+
};
|
|
92
|
+
const staleAll = evaluation.staleExceptions.map((s) => ({
|
|
93
|
+
...s,
|
|
94
|
+
file: sourceFileOf(s.ruleId),
|
|
95
|
+
}));
|
|
96
|
+
let selected = rules;
|
|
97
|
+
let reported = evaluation.violations;
|
|
98
|
+
let reportedStale = staleAll;
|
|
99
|
+
let escalatedIds = new Set();
|
|
100
|
+
let changed;
|
|
101
|
+
let suppressedEscalation = [];
|
|
102
|
+
let inReportedScope = (_file, _ruleId) => true;
|
|
103
|
+
// The files the scan READ, and the ones it matched but could not read. An
|
|
104
|
+
// unread file is in front of every rule whose scope it is in — it is never
|
|
105
|
+
// narrowing, and never "matched nothing".
|
|
106
|
+
const scanned = new Set(scan.files ?? scan.edges.map((e) => e.from));
|
|
107
|
+
const unreadAll = scan.unread ?? [];
|
|
108
|
+
const unreadPaths = new Set(unreadAll.map((u) => u.path));
|
|
109
|
+
// A directory the scan could not LIST hides every file beneath it: a path
|
|
110
|
+
// under one was never read either (round 11 review R12-GAP-1).
|
|
111
|
+
const unlistedDirs = unreadAll.filter(isUnreadDirectory);
|
|
112
|
+
const beneathUnlisted = (f) => unlistedDirs.some((d) => unreadDirectoryContains(d, f));
|
|
113
|
+
if (options.changedScope || options.changed) {
|
|
114
|
+
const resolved = options.changed ?? resolveChangedFiles(options.changedScope);
|
|
115
|
+
const changedFiles = resolved.files.map((f) => f.split(/[\\/]/).join('/').replace(/^\.\//, ''));
|
|
116
|
+
const changedSet = new Set(changedFiles);
|
|
117
|
+
const ids = rules.map((r) => r.id);
|
|
118
|
+
const invalidation = ruleFile
|
|
119
|
+
? {
|
|
120
|
+
escalatedRuleIds: ids,
|
|
121
|
+
reasons: [{ file: boundaryFileLabel(projectRoot, ruleFile.path), kind: 'rule-file', ruleIds: ids }],
|
|
122
|
+
}
|
|
123
|
+
: resolveBoundaryRuleInvalidation(changedFiles, inspection, ids);
|
|
124
|
+
if (options.escalate === false)
|
|
125
|
+
suppressedEscalation = [...invalidation.escalatedRuleIds];
|
|
126
|
+
else
|
|
127
|
+
escalatedIds = new Set(invalidation.escalatedRuleIds);
|
|
128
|
+
// A rule is accountable to this changeset when it GOVERNS a changed source
|
|
129
|
+
// file — one the scan read, or one it matched and could NOT read (a loud
|
|
130
|
+
// skip, never narrowing). A deleted file, or a doc, put nothing in front of
|
|
131
|
+
// any rule, exactly as the policy plane narrows a pure delete.
|
|
132
|
+
const governedFiles = new Set();
|
|
133
|
+
const governing = new Set();
|
|
134
|
+
for (const rule of rules) {
|
|
135
|
+
const scope = boundaryRuleScope(rule);
|
|
136
|
+
for (const f of changedFiles) {
|
|
137
|
+
if ((scanned.has(f) || unreadPaths.has(f) || beneathUnlisted(f)) && boundaryScopeDecision(scope, f) === 'in') {
|
|
138
|
+
governedFiles.add(f);
|
|
139
|
+
governing.add(rule.id);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const filtered = filterViolationsToChangedScope(evaluation.violations, options.changedScope ?? { projectRoot }, { resolved: { mode: resolved.mode, files: changedFiles }, escalatedRuleIds: escalatedIds });
|
|
144
|
+
reported = [...filtered.includedViolations];
|
|
145
|
+
for (const v of reported)
|
|
146
|
+
governing.add(v.ruleId);
|
|
147
|
+
reportedStale = staleAll.filter((s) => escalatedIds.has(s.ruleId) || changedSet.has(s.file));
|
|
148
|
+
for (const s of reportedStale)
|
|
149
|
+
governing.add(s.ruleId);
|
|
150
|
+
selected = rules.filter((r) => governing.has(r.id) || escalatedIds.has(r.id));
|
|
151
|
+
inReportedScope = (file, ruleId) => escalatedIds.has(ruleId) || changedSet.has(file);
|
|
152
|
+
changed = {
|
|
153
|
+
mode: resolved.mode,
|
|
154
|
+
changedFiles,
|
|
155
|
+
governedFiles: [...governedFiles].sort(),
|
|
156
|
+
ignoredLegacyCount: filtered.ignoredLegacyCount,
|
|
157
|
+
ignoredLegacyByRule: filtered.ignoredLegacyByRule,
|
|
158
|
+
escalation: invalidation,
|
|
159
|
+
escalatedRuleIds: [...escalatedIds],
|
|
160
|
+
escalationSuppressed: suppressedEscalation,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
const selectedIds = new Set(selected.map((r) => r.id));
|
|
164
|
+
const changedSet = changed ? new Set(changed.changedFiles) : undefined;
|
|
165
|
+
// The changeset's unread files: each one the scan could not read, and each
|
|
166
|
+
// changed path beneath a directory it could not list — named by file, since
|
|
167
|
+
// the changeset is the scope.
|
|
168
|
+
const changedUnread = changed
|
|
169
|
+
? changed.changedFiles.flatMap((f) => {
|
|
170
|
+
const own = unreadAll.find((u) => !isUnreadDirectory(u) && u.path === f);
|
|
171
|
+
if (own)
|
|
172
|
+
return [own];
|
|
173
|
+
return !scanned.has(f) && beneathUnlisted(f) ? [{ path: f, reason: UnreadFileReason.Unreadable }] : [];
|
|
174
|
+
})
|
|
175
|
+
: [];
|
|
176
|
+
const ruleChecks = selected.map((rule) => {
|
|
177
|
+
const engineDetail = detailById.get(rule.id);
|
|
178
|
+
const violations = reported.filter((v) => v.ruleId === rule.id);
|
|
179
|
+
const staleExceptions = reportedStale.filter((s) => s.ruleId === rule.id);
|
|
180
|
+
const scope = boundaryRuleScope(rule);
|
|
181
|
+
// The rule's READ scope over its REPORTED scope: the whole tree, or — for a
|
|
182
|
+
// changed-only run the rule was not escalated in — the changeset (deliberate
|
|
183
|
+
// narrowing: an unread file outside it would not be reported anyway).
|
|
184
|
+
const wholeTree = changedSet === undefined || escalatedIds.has(rule.id);
|
|
185
|
+
const unread = wholeTree
|
|
186
|
+
? unreadAll.filter((u) => boundaryScopeCoversUnread(scope, u))
|
|
187
|
+
: changedUnread.filter((u) => boundaryScopeDecision(scope, u.path) === 'in');
|
|
188
|
+
const readGap = unread.length > 0;
|
|
189
|
+
const read = wholeTree
|
|
190
|
+
? engineDetail.filesInScope
|
|
191
|
+
: changed.changedFiles.filter((f) => scanned.has(f) && boundaryScopeDecision(scope, f) === 'in').length;
|
|
192
|
+
// A dead-unit / does-not-exist claim is a whole-tree claim made from what
|
|
193
|
+
// was READ. THE unread re-settle (round 13) withdraws every claim an unread
|
|
194
|
+
// file could refute and re-settles the rule: such a unit reads Unproven —
|
|
195
|
+
// never a dead line, never an acceptance, never silently dropped.
|
|
196
|
+
const detail = boundaryUnitLiveness(engineDetail, rule, {
|
|
197
|
+
unread: readGap ? [...unreadAll, ...unread] : unreadAll,
|
|
198
|
+
readGap,
|
|
199
|
+
filesScanned: evaluation.filesScanned,
|
|
200
|
+
fileUniverse: evaluation.fileUniverse,
|
|
201
|
+
});
|
|
202
|
+
// The engine skipped the rule because it READ no governed file. When a
|
|
203
|
+
// governed file went unread, that zero is not "matched nothing": the rule
|
|
204
|
+
// is PARTIAL (its coverage says so below), never a failOnEmpty failure.
|
|
205
|
+
const engineSkipped = detail.status === 'skipped' && !readGap;
|
|
206
|
+
// A stale exception fails its rule: the exception list rotted. A rule that
|
|
207
|
+
// checked nothing and fails on empty is `failed` (keeping its skipReason) —
|
|
208
|
+
// the wiring plane's mapping, so `gate.failed` counts the rule that failed
|
|
209
|
+
// the run in every plane. Whether it EXAMINED anything stays the engine's
|
|
210
|
+
// `detail.status`; that, not this, is what "evaluated" counts.
|
|
211
|
+
const status = engineSkipped
|
|
212
|
+
? detail.failedOnEmpty
|
|
213
|
+
? 'failed'
|
|
214
|
+
: 'skipped'
|
|
215
|
+
: violations.length > 0 || staleExceptions.length > 0
|
|
216
|
+
? 'failed'
|
|
217
|
+
: 'passed';
|
|
218
|
+
return {
|
|
219
|
+
ruleId: rule.id,
|
|
220
|
+
title: rule.title,
|
|
221
|
+
severity: detail.severity,
|
|
222
|
+
status,
|
|
223
|
+
...(engineSkipped && detail.skipReason ? { skipReason: detail.skipReason } : {}),
|
|
224
|
+
...(engineSkipped && detail.failedOnEmpty ? { failedOnEmpty: true } : {}),
|
|
225
|
+
...(escalatedIds.has(rule.id) ? { escalated: true } : {}),
|
|
226
|
+
// THE unread-file rule (`readScopeCoverage`): examined `read` of the
|
|
227
|
+
// `read + unread` governed files, each unread path named.
|
|
228
|
+
coverage: readScopeCoverage(detail.coverage, readGap ? { read, unread } : undefined),
|
|
229
|
+
...(readGap ? { unread } : {}),
|
|
230
|
+
detail,
|
|
231
|
+
violations,
|
|
232
|
+
staleExceptions,
|
|
233
|
+
};
|
|
234
|
+
});
|
|
235
|
+
// Each selected rule's settled lists — read, never re-derived.
|
|
236
|
+
const deadUnits = ruleChecks.flatMap((r) => r.detail.deadUnits);
|
|
237
|
+
const unitsIn = (state) => ruleChecks.flatMap((r) => (r.detail.unitLiveness ?? []).filter((u) => u.state === state).map((u) => boundaryUnitFinding(r.ruleId, u)));
|
|
238
|
+
const intendedEmpty = unitsIn(UnitLivenessState.IntendedEmpty);
|
|
239
|
+
const wentLive = unitsIn(UnitLivenessState.WentLive);
|
|
240
|
+
// THE `--fail-on-dead-units` / `--strict` predicate (core `selectorUnitFails`):
|
|
241
|
+
// an unmarked dead unit under the flag, a LOCAL went-live marker under the
|
|
242
|
+
// flag or `--strict` (on this verb `--strict` already promotes warnings); a
|
|
243
|
+
// pack marker that went live never — the consumer cannot edit it.
|
|
244
|
+
const unitFlags = {
|
|
245
|
+
failOnDeadUnits: options.failOnDeadUnits === true,
|
|
246
|
+
strict: options.strict === true,
|
|
247
|
+
strictPromotesWarnings: true,
|
|
248
|
+
};
|
|
249
|
+
const failingUnits = ruleChecks.flatMap((r) => (r.detail.unitLiveness ?? []).filter((u) => selectorUnitFails(u, unitFlags)).map((u) => boundaryUnitFinding(r.ruleId, u)));
|
|
250
|
+
const suppressed = evaluation.suppressed.filter((s) => selectedIds.has(s.violation.ruleId) && inReportedScope(s.violation.file, s.violation.ruleId));
|
|
251
|
+
const counts = { error: 0, warning: 0, info: 0 };
|
|
252
|
+
for (const v of reported)
|
|
253
|
+
counts[v.severity] += 1;
|
|
254
|
+
// ── run coverage: rules examined of rules this run is accountable for ──
|
|
255
|
+
// "Checked nothing" is the ENGINE's word — a failOnEmpty rule is `failed`
|
|
256
|
+
// above yet examined nothing, so it is unexamined here all the same. A rule
|
|
257
|
+
// whose only governed files went unread is partial through its own coverage.
|
|
258
|
+
const skippedSel = ruleChecks.filter(boundaryRuleCheckedNothing);
|
|
259
|
+
const unexamined = [...skippedSel.map((r) => r.ruleId), ...suppressedEscalation];
|
|
260
|
+
const expected = selected.length + suppressedEscalation.length;
|
|
261
|
+
const gapReasons = [];
|
|
262
|
+
if (skippedSel.length > 0)
|
|
263
|
+
gapReasons.push('checked nothing (their from globs reached no governed file)');
|
|
264
|
+
if (suppressedEscalation.length > 0) {
|
|
265
|
+
gapReasons.push('are defined in a changed rule source, but --no-rule-escalation kept them out — changed-only cannot see a rule edit');
|
|
266
|
+
}
|
|
267
|
+
const emptyReason = expected > 0
|
|
268
|
+
? undefined
|
|
269
|
+
: rules.length === 0
|
|
270
|
+
? (configuration?.diagnostics[0] ?? 'the rule file defines no rules')
|
|
271
|
+
: changed
|
|
272
|
+
? `no changed source file is governed by a boundary rule (${changed.changedFiles.length} changed file(s))`
|
|
273
|
+
: 'no rule selected';
|
|
274
|
+
const runCoverage = {
|
|
275
|
+
unit: 'rules',
|
|
276
|
+
expected,
|
|
277
|
+
examined: expected - unexamined.length,
|
|
278
|
+
...(unexamined.length > 0
|
|
279
|
+
? { unexamined: unexamined.slice(0, 20), unexaminedTotal: unexamined.length, reason: gapReasons.join('; ') }
|
|
280
|
+
: {}),
|
|
281
|
+
...(emptyReason ? { reason: emptyReason } : {}),
|
|
282
|
+
root: projectRoot,
|
|
283
|
+
};
|
|
284
|
+
// ── the proposed exit ──────────────────────────────────────────────────
|
|
285
|
+
// 1 an errored rule (load issue), a stale exception, an error violation
|
|
286
|
+
// (warnings too under --strict), a failOnEmpty skip, or a selector unit
|
|
287
|
+
// `selectorUnitFails` fails (a dead unit under --fail-on-dead-units, a
|
|
288
|
+
// local went-live marker under it or --strict);
|
|
289
|
+
// 2 a selected rule checked nothing;
|
|
290
|
+
// 0 otherwise — including an EMPTY selection, which the run coverage
|
|
291
|
+
// (expected 0) settles to 2 unless the caller accepts it.
|
|
292
|
+
const failedOnEmpty = skippedSel.filter((r) => r.failedOnEmpty);
|
|
293
|
+
const fails = loadIssues.length > 0 ||
|
|
294
|
+
reportedStale.length > 0 ||
|
|
295
|
+
counts.error > 0 ||
|
|
296
|
+
(options.strict === true && counts.warning > 0) ||
|
|
297
|
+
failedOnEmpty.length > 0 ||
|
|
298
|
+
failingUnits.length > 0;
|
|
299
|
+
const proposedExit = fails ? 1 : skippedSel.length > 0 ? 2 : 0;
|
|
300
|
+
// Core's settleVerdict — the SAME fold the CLI's gate envelope runs, so the
|
|
301
|
+
// MCP tools, finish and quality cannot settle this coverage differently.
|
|
302
|
+
const settled = settleVerdict(proposedExit, boundaryCheckCoverage({ runCoverage, rules: ruleChecks, loadIssues }));
|
|
303
|
+
return {
|
|
304
|
+
schema: 'sharkcraft.boundary-check/v1',
|
|
305
|
+
projectRoot,
|
|
306
|
+
ruleSource,
|
|
307
|
+
rulesConfigured: sourceRules.length,
|
|
308
|
+
selectedRuleIds: selected.map((r) => r.id),
|
|
309
|
+
scan,
|
|
310
|
+
evaluation,
|
|
311
|
+
rules: ruleChecks,
|
|
312
|
+
violations: reported,
|
|
313
|
+
counts,
|
|
314
|
+
suppressed,
|
|
315
|
+
staleExceptions: reportedStale,
|
|
316
|
+
deadUnits,
|
|
317
|
+
intendedEmpty,
|
|
318
|
+
wentLive,
|
|
319
|
+
failingUnits,
|
|
320
|
+
loadIssues,
|
|
321
|
+
...(configuration ? { configuration } : {}),
|
|
322
|
+
...(changed ? { changed } : {}),
|
|
323
|
+
runCoverage,
|
|
324
|
+
proposedExit,
|
|
325
|
+
exitCode: settled.exit,
|
|
326
|
+
verdict: settled.verdict,
|
|
327
|
+
shortfalls: settled.shortfalls,
|
|
328
|
+
accepted: settled.accepted,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* THE "did this selected rule check nothing?" predicate: the engine read no
|
|
333
|
+
* governed file for it AND no governed file went unread. A rule whose governed
|
|
334
|
+
* files could not be read matched real files it could not examine — PARTIAL
|
|
335
|
+
* through its coverage, never listed as "checked nothing" and never a
|
|
336
|
+
* failOnEmpty failure. Every boundary renderer reads this, not `detail.status`.
|
|
337
|
+
*/
|
|
338
|
+
export function boundaryRuleCheckedNothing(r) {
|
|
339
|
+
return r.detail.status === 'skipped' && (r.unread?.length ?? 0) === 0;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* THE coverage records a boundary run settles on: the run coverage, each
|
|
343
|
+
* selected rule's coverage (subject = the rule id) followed by its
|
|
344
|
+
* `expectEmpty` acceptance (round 13 — folded through core's
|
|
345
|
+
* `ruleVerdictRecords`, once when the two are the same record), and one record
|
|
346
|
+
* per errored rule. `runBoundaryCheck` settles with exactly this list, and every
|
|
347
|
+
* surface that folds a boundary run into its own verdict (drift, `architecture
|
|
348
|
+
* violations`, the validation loop) reads it too — never a re-derivation.
|
|
349
|
+
*/
|
|
350
|
+
export function boundaryCheckCoverage(result) {
|
|
351
|
+
return [
|
|
352
|
+
result.runCoverage,
|
|
353
|
+
...result.rules.flatMap((r) => ruleVerdictRecords(r.coverage, r.detail.unitAcceptance).map((c) => ({ ...c, subject: c.subject ?? r.ruleId }))),
|
|
354
|
+
...result.loadIssues.map((i) => boundaryLoadIssueCoverage(i)),
|
|
355
|
+
];
|
|
356
|
+
}
|
|
357
|
+
/** The selected rules of a run that checked nothing — {@link boundaryRuleCheckedNothing}, over the whole result. */
|
|
358
|
+
export function boundaryRulesCheckedNothing(result) {
|
|
359
|
+
return result.rules.filter(boundaryRuleCheckedNothing);
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* THE "accepted as intended-empty" predicate (round 13, K6): the rule settled
|
|
363
|
+
* IntendedEmpty — every `from` inclusion marked `expectEmpty`, no file matched,
|
|
364
|
+
* so it examined 0 files and its coverage IS the acceptance. Read from the
|
|
365
|
+
* engine's settle (`acceptedAsIntendedEmpty`), never re-derived from a coverage
|
|
366
|
+
* shape.
|
|
367
|
+
*/
|
|
368
|
+
export function boundaryRuleAcceptedEmpty(r) {
|
|
369
|
+
return r.detail.acceptedAsIntendedEmpty === true;
|
|
370
|
+
}
|
|
371
|
+
/** The selected rules accepted as intended-empty — {@link boundaryRuleAcceptedEmpty}, over the whole result. */
|
|
372
|
+
export function boundaryRulesAcceptedEmpty(result) {
|
|
373
|
+
return result.rules.filter(boundaryRuleAcceptedEmpty);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* THE "rules evaluated" count every boundary surface reports: the selected
|
|
377
|
+
* rules minus the ones that checked nothing and minus the ones accepted as
|
|
378
|
+
* intended-empty (round 13 — each examined 0 files; a renderer prints them
|
|
379
|
+
* apart: `N evaluated, M accepted as intended-empty`, M from
|
|
380
|
+
* {@link boundaryRulesAcceptedEmpty}). A rule whose governed files went unread
|
|
381
|
+
* is counted (it is PARTIAL through its coverage, not "checked nothing"); a
|
|
382
|
+
* failOnEmpty rule that examined nothing is not. `check boundaries --json`,
|
|
383
|
+
* `diff-check` (CLI + MCP) and MCP `check_boundaries` all read it, so no
|
|
384
|
+
* surface can re-derive it from `detail.status` and disagree.
|
|
385
|
+
*/
|
|
386
|
+
export function boundaryRulesEvaluated(result) {
|
|
387
|
+
return (result.rules.length - boundaryRulesCheckedNothing(result).length - boundaryRulesAcceptedEmpty(result).length);
|
|
388
|
+
}
|
|
389
|
+
/** The `skipped[]` rows of a boundary JSON payload — one shape for the CLI and MCP. */
|
|
390
|
+
export function boundarySkippedRuleRows(result) {
|
|
391
|
+
return boundaryRulesCheckedNothing(result).map((r) => ({
|
|
392
|
+
ruleId: r.ruleId,
|
|
393
|
+
reason: r.skipReason ?? 'checked nothing',
|
|
394
|
+
failed: r.failedOnEmpty === true,
|
|
395
|
+
}));
|
|
396
|
+
}
|
|
397
|
+
/** A label for a load issue — the rule id when known, else `<file>#<index>` / the file. */
|
|
398
|
+
export function boundaryLoadIssueLabel(issue) {
|
|
399
|
+
if (issue.ruleId)
|
|
400
|
+
return issue.ruleId;
|
|
401
|
+
return issue.index !== undefined ? `${issue.file}#${issue.index}` : issue.file;
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* The coverage an errored boundary rule carries: one rule asked for, none
|
|
405
|
+
* examined. Shared by the orchestrator's settle and the CLI envelope's rows.
|
|
406
|
+
*/
|
|
407
|
+
export function boundaryLoadIssueCoverage(issue) {
|
|
408
|
+
return {
|
|
409
|
+
unit: 'rules',
|
|
410
|
+
expected: 1,
|
|
411
|
+
examined: 0,
|
|
412
|
+
subject: boundaryLoadIssueLabel(issue),
|
|
413
|
+
reason: issue.kind === 'missing-file'
|
|
414
|
+
? 'the listed rule file does not exist'
|
|
415
|
+
: issue.kind === 'load-error'
|
|
416
|
+
? 'the rule file failed to load'
|
|
417
|
+
: 'failed validation — NOT evaluated',
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Package names the workspace knows: node builtins, the root manifest's
|
|
422
|
+
* dependency sections, and the name + dependencies of every package.json the
|
|
423
|
+
* scan walked. A forbidden pattern naming one is resolvable even when nothing
|
|
424
|
+
* imports it today (a "never adopt X" guard is legitimate).
|
|
425
|
+
*/
|
|
426
|
+
export function collectKnownPackages(projectRoot, scan) {
|
|
427
|
+
// THE builtin list (`nodeBuiltinPackageNames`) — the load-time marker refusal
|
|
428
|
+
// reads the same one, so a builtin-named marker is refused exactly when this
|
|
429
|
+
// judge could never call it dead.
|
|
430
|
+
const out = new Set(nodeBuiltinPackageNames());
|
|
431
|
+
for (const rel of new Set(['package.json', ...(scan.manifestFiles ?? [])])) {
|
|
432
|
+
const abs = nodePath.join(projectRoot, rel);
|
|
433
|
+
if (!existsSync(abs))
|
|
434
|
+
continue;
|
|
435
|
+
try {
|
|
436
|
+
const json = JSON.parse(readFileSync(abs, 'utf8'));
|
|
437
|
+
if (typeof json['name'] === 'string')
|
|
438
|
+
out.add(json['name']);
|
|
439
|
+
for (const key of ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']) {
|
|
440
|
+
const deps = json[key];
|
|
441
|
+
if (deps && typeof deps === 'object')
|
|
442
|
+
for (const d of Object.keys(deps))
|
|
443
|
+
out.add(d);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
catch {
|
|
447
|
+
// An unreadable manifest only means its names stay unknown — a pattern
|
|
448
|
+
// naming them may be reported as a dead unit (a warning), never a pass.
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
return [...out];
|
|
452
|
+
}
|
|
453
|
+
function evaluateOptionsFor(projectRoot, scan) {
|
|
454
|
+
const tsconfigPaths = loadTsconfigPaths(projectRoot);
|
|
455
|
+
return {
|
|
456
|
+
...(tsconfigPaths.aliases.size > 0 ? { tsconfigPaths } : {}),
|
|
457
|
+
knownPackages: collectKnownPackages(projectRoot, scan),
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* `check boundaries --diff-against <file>`: what the candidate rule set would
|
|
462
|
+
* flag, relative to the active one — evaluated by the SAME engine as the gate,
|
|
463
|
+
* against ONE scan.
|
|
464
|
+
*
|
|
465
|
+
* The proposed set is an id overlay: active rules whose id the candidate does
|
|
466
|
+
* not define, plus every candidate rule (a same id REPLACES, a new id ADDS).
|
|
467
|
+
* `onlyRuleId` narrows both sides.
|
|
468
|
+
*
|
|
469
|
+
* Round 13 (P2): each candidate rule's record goes through the SAME unread
|
|
470
|
+
* re-settle as `check boundaries` (`boundaryUnitLiveness`) and the same read
|
|
471
|
+
* scope (`readScopeCoverage`) — an unreadable governed file is never a pass
|
|
472
|
+
* here either, and a dead unit it could refute is Unproven, not reported.
|
|
473
|
+
*/
|
|
474
|
+
export function diffBoundaryRuleSets(inspection, candidate, options = {}) {
|
|
475
|
+
const projectRoot = inspection.projectRoot;
|
|
476
|
+
const active = inspection.boundaryRegistry.list();
|
|
477
|
+
const activeIds = new Set(active.map((r) => r.id));
|
|
478
|
+
const candidateIds = new Set(candidate.rules.map((r) => r.id));
|
|
479
|
+
const proposed = [...active.filter((r) => !candidateIds.has(r.id)), ...candidate.rules];
|
|
480
|
+
const loadIssues = [...(candidate.loadIssues ?? [])];
|
|
481
|
+
const base = {
|
|
482
|
+
schema: 'sharkcraft.boundary-rule-diff/v1',
|
|
483
|
+
candidateFile: boundaryFileLabel(projectRoot, candidate.path),
|
|
484
|
+
rulesAdded: candidate.rules.filter((r) => !activeIds.has(r.id)).map((r) => r.id),
|
|
485
|
+
rulesReplaced: candidate.rules.filter((r) => activeIds.has(r.id)).map((r) => r.id),
|
|
486
|
+
loadIssues,
|
|
487
|
+
};
|
|
488
|
+
const only = options.onlyRuleId;
|
|
489
|
+
if (only !== undefined && !activeIds.has(only) && !candidateIds.has(only)) {
|
|
490
|
+
const zero = { error: 0, warning: 0, info: 0 };
|
|
491
|
+
return {
|
|
492
|
+
...base,
|
|
493
|
+
added: [],
|
|
494
|
+
removed: [],
|
|
495
|
+
unchanged: 0,
|
|
496
|
+
perRule: [],
|
|
497
|
+
edgeLevel: { newlyFlagged: [], noLongerFlagged: [] },
|
|
498
|
+
before: { rules: 0, counts: zero },
|
|
499
|
+
after: { rules: 0, counts: zero },
|
|
500
|
+
candidateCoverage: [],
|
|
501
|
+
intendedEmpty: [],
|
|
502
|
+
wentLive: [],
|
|
503
|
+
failingUnits: [],
|
|
504
|
+
proposedExit: 3,
|
|
505
|
+
unknownRuleId: only,
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
const narrow = (rs) => only !== undefined ? rs.filter((r) => r.id === only) : [...rs];
|
|
509
|
+
const scan = scanImports({ projectRoot, includeComments: options.includeComments === true });
|
|
510
|
+
const evalOptions = evaluateOptionsFor(projectRoot, scan);
|
|
511
|
+
const before = evaluateBoundaries(scan, narrow(active), evalOptions);
|
|
512
|
+
const after = evaluateBoundaries(scan, narrow(proposed), evalOptions);
|
|
513
|
+
const key = (v) => `${v.ruleId}|${v.file}|${v.line}|${v.importSpecifier}`;
|
|
514
|
+
const beforeKeys = new Set(before.violations.map(key));
|
|
515
|
+
const afterKeys = new Set(after.violations.map(key));
|
|
516
|
+
const added = after.violations.filter((v) => !beforeKeys.has(key(v)));
|
|
517
|
+
const removed = before.violations.filter((v) => !afterKeys.has(key(v)));
|
|
518
|
+
const unchanged = after.violations.filter((v) => beforeKeys.has(key(v))).length;
|
|
519
|
+
const ruleIds = [...new Set([...narrow(active), ...narrow(proposed)].map((r) => r.id))];
|
|
520
|
+
const perRule = ruleIds.map((ruleId) => ({
|
|
521
|
+
ruleId,
|
|
522
|
+
added: added.filter((v) => v.ruleId === ruleId).length,
|
|
523
|
+
removed: removed.filter((v) => v.ruleId === ruleId).length,
|
|
524
|
+
unchanged: after.violations.filter((v) => v.ruleId === ruleId && beforeKeys.has(key(v))).length,
|
|
525
|
+
}));
|
|
526
|
+
const edgeKey = (v) => `${v.file}|${v.line}|${v.importSpecifier}`;
|
|
527
|
+
const edgesOf = (vs) => new Map(vs.map((v) => [edgeKey(v), v]));
|
|
528
|
+
const beforeEdges = edgesOf(before.violations);
|
|
529
|
+
const afterEdges = edgesOf(after.violations);
|
|
530
|
+
const edge = (v) => ({
|
|
531
|
+
file: v.file,
|
|
532
|
+
line: v.line,
|
|
533
|
+
importSpecifier: v.importSpecifier,
|
|
534
|
+
});
|
|
535
|
+
const newlyFlagged = [...afterEdges].filter(([k]) => !beforeEdges.has(k)).map(([, v]) => edge(v));
|
|
536
|
+
const noLongerFlagged = [...beforeEdges].filter(([k]) => !afterEdges.has(k)).map(([, v]) => edge(v));
|
|
537
|
+
// The candidate rules' records through THE unread re-settle and read scope
|
|
538
|
+
// `check boundaries` uses — one answer to "is this unit dead?" on both paths.
|
|
539
|
+
const unreadAll = scan.unread ?? [];
|
|
540
|
+
const proposedById = new Map(narrow(proposed).map((r) => [r.id, r]));
|
|
541
|
+
const candidateCoverage = after.coverage
|
|
542
|
+
.filter((c) => candidateIds.has(c.ruleId))
|
|
543
|
+
.map((c) => {
|
|
544
|
+
const rule = proposedById.get(c.ruleId);
|
|
545
|
+
if (rule === undefined)
|
|
546
|
+
return c;
|
|
547
|
+
const unread = unreadAll.filter((u) => boundaryScopeCoversUnread(boundaryRuleScope(rule), u));
|
|
548
|
+
const readGap = unread.length > 0;
|
|
549
|
+
const detail = boundaryUnitLiveness(c, rule, {
|
|
550
|
+
unread: unreadAll,
|
|
551
|
+
readGap,
|
|
552
|
+
filesScanned: after.filesScanned,
|
|
553
|
+
fileUniverse: after.fileUniverse,
|
|
554
|
+
});
|
|
555
|
+
return readGap
|
|
556
|
+
? { ...detail, coverage: readScopeCoverage(detail.coverage, { read: detail.filesInScope, unread }) }
|
|
557
|
+
: detail;
|
|
558
|
+
});
|
|
559
|
+
const unitsIn = (state) => candidateCoverage.flatMap((c) => (c.unitLiveness ?? []).filter((u) => u.state === state).map((u) => boundaryUnitFinding(c.ruleId, u)));
|
|
560
|
+
// THE `--fail-on-dead-units` predicate, as on the gate. `--strict` promotes
|
|
561
|
+
// nothing on this path (the delta counts error violations only), so it
|
|
562
|
+
// fails no went-live marker here.
|
|
563
|
+
const unitFlags = {
|
|
564
|
+
failOnDeadUnits: options.failOnDeadUnits === true,
|
|
565
|
+
strict: false,
|
|
566
|
+
strictPromotesWarnings: false,
|
|
567
|
+
};
|
|
568
|
+
const failingUnits = candidateCoverage.flatMap((c) => (c.unitLiveness ?? []).filter((u) => selectorUnitFails(u, unitFlags)).map((u) => boundaryUnitFinding(c.ruleId, u)));
|
|
569
|
+
// A candidate that checked nothing and fails on empty WOULD fail the gate it
|
|
570
|
+
// is headed for — the same `1` the gate itself proposes for it.
|
|
571
|
+
const proposedExit = loadIssues.length > 0 ||
|
|
572
|
+
added.some((v) => v.severity === 'error') ||
|
|
573
|
+
candidateCoverage.some((c) => c.failedOnEmpty === true) ||
|
|
574
|
+
failingUnits.length > 0
|
|
575
|
+
? 1
|
|
576
|
+
: 0;
|
|
577
|
+
return {
|
|
578
|
+
...base,
|
|
579
|
+
added,
|
|
580
|
+
removed,
|
|
581
|
+
unchanged,
|
|
582
|
+
perRule,
|
|
583
|
+
edgeLevel: { newlyFlagged, noLongerFlagged },
|
|
584
|
+
before: { rules: before.rulesConfigured, counts: before.counts },
|
|
585
|
+
after: { rules: after.rulesConfigured, counts: after.counts },
|
|
586
|
+
candidateCoverage,
|
|
587
|
+
intendedEmpty: unitsIn(UnitLivenessState.IntendedEmpty),
|
|
588
|
+
wentLive: unitsIn(UnitLivenessState.WentLive),
|
|
589
|
+
failingUnits,
|
|
590
|
+
proposedExit,
|
|
591
|
+
};
|
|
592
|
+
}
|
package/dist/safety-audit.js
CHANGED
|
@@ -113,7 +113,7 @@ export function buildSafetyAudit(input) {
|
|
|
113
113
|
recommendations.push(`${signedNotVerified} pack(s) are signed but not verified. Run \`shrk packs verify\` with the appropriate secret.`);
|
|
114
114
|
}
|
|
115
115
|
if (unsigned > 0) {
|
|
116
|
-
recommendations.push(`${unsigned} pack(s) are unsigned. Sign packs with \`shrk
|
|
116
|
+
recommendations.push(`${unsigned} pack(s) are unsigned. Sign packs with \`shrk packs sign\` before adopting in production.`);
|
|
117
117
|
}
|
|
118
118
|
if (untrusted.length > 0) {
|
|
119
119
|
recommendations.push(`${untrusted.length} local verification command(s) are not marked trusted. Review before relying on them in \`shrk apply --validate\`.`);
|
|
@@ -109,7 +109,7 @@ function suggestAdditions(missing, taskOrDomain) {
|
|
|
109
109
|
}
|
|
110
110
|
function buildNextCommands(taskOrDomain) {
|
|
111
111
|
return [
|
|
112
|
-
`shrk
|
|
112
|
+
`shrk task "${taskOrDomain}" --explain-ranking`,
|
|
113
113
|
`shrk search "${taskOrDomain}" --explain`,
|
|
114
114
|
`shrk task "${taskOrDomain}" --show-coverage-gaps`,
|
|
115
115
|
`shrk fix preview --template-drift`,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { IVerdictCoverage } from '@shrkcrft/core';
|
|
2
|
+
import type { IScaffoldPatternDoctorReport } from './i-scaffold-pattern-doctor-report.js';
|
|
3
|
+
import type { ISharkcraftInspection } from './sharkcraft-inspector.js';
|
|
4
|
+
/**
|
|
5
|
+
* THE scaffold-pattern doctor (round 13): load (THE rejection channel names
|
|
6
|
+
* every refused pattern), validate the definitions, walk ONCE with THE
|
|
7
|
+
* enumeration `infer templates` attributes candidates with, and settle every
|
|
8
|
+
* `matchPaths` glob and every pattern through THE liveness authority.
|
|
9
|
+
*
|
|
10
|
+
* `shrk scaffolds doctor` and MCP `get_scaffold_pattern_doctor` both read it
|
|
11
|
+
* and propose through `assetDoctorProposedExit` — the MCP tool used to drop
|
|
12
|
+
* the patterns the loader refused and to return no verdict, so it answered
|
|
13
|
+
* "0 errors" where the CLI exited 1.
|
|
14
|
+
*
|
|
15
|
+
* `emptyAcceptance` is the CLI's `--allow-empty` valve for zero patterns (`{}`
|
|
16
|
+
* from MCP: nothing declared is NOT VERIFIED).
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildScaffoldPatternDoctorReport(inspection: ISharkcraftInspection, emptyAcceptance?: Pick<IVerdictCoverage, 'acceptedBy'>): Promise<IScaffoldPatternDoctorReport>;
|
|
19
|
+
//# sourceMappingURL=scaffold-pattern-doctor-report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold-pattern-doctor-report.d.ts","sourceRoot":"","sources":["../src/scaffold-pattern-doctor-report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGvD,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AAQ1F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAIvE;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gCAAgC,CACpD,UAAU,EAAE,qBAAqB,EACjC,eAAe,GAAE,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAM,GACzD,OAAO,CAAC,4BAA4B,CAAC,CAqCvC"}
|