@vyuhlabs/dxkit 2.4.5 → 2.4.7
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/CHANGELOG.md +1022 -0
- package/README.md +160 -45
- package/dist/analysis-result.d.ts +112 -0
- package/dist/analysis-result.d.ts.map +1 -0
- package/dist/analysis-result.js +52 -0
- package/dist/analysis-result.js.map +1 -0
- package/dist/analyzers/bom/detailed.d.ts.map +1 -1
- package/dist/analyzers/bom/detailed.js +19 -0
- package/dist/analyzers/bom/detailed.js.map +1 -1
- package/dist/analyzers/bom/gather.d.ts +27 -26
- package/dist/analyzers/bom/gather.d.ts.map +1 -1
- package/dist/analyzers/bom/gather.js +26 -87
- package/dist/analyzers/bom/gather.js.map +1 -1
- package/dist/analyzers/bom/index.d.ts +0 -7
- package/dist/analyzers/bom/index.d.ts.map +1 -1
- package/dist/analyzers/bom/index.js +98 -48
- package/dist/analyzers/bom/index.js.map +1 -1
- package/dist/analyzers/bom/types.d.ts +11 -13
- package/dist/analyzers/bom/types.d.ts.map +1 -1
- package/dist/analyzers/cache.d.ts +95 -0
- package/dist/analyzers/cache.d.ts.map +1 -0
- package/dist/analyzers/cache.js +309 -0
- package/dist/analyzers/cache.js.map +1 -0
- package/dist/analyzers/coverage-runner.d.ts +56 -0
- package/dist/analyzers/coverage-runner.d.ts.map +1 -0
- package/dist/analyzers/coverage-runner.js +72 -0
- package/dist/analyzers/coverage-runner.js.map +1 -0
- package/dist/analyzers/dashboard/index.d.ts +24 -0
- package/dist/analyzers/dashboard/index.d.ts.map +1 -0
- package/dist/analyzers/dashboard/index.js +666 -0
- package/dist/analyzers/dashboard/index.js.map +1 -0
- package/dist/analyzers/developer/gather.d.ts.map +1 -1
- package/dist/analyzers/developer/gather.js +205 -37
- package/dist/analyzers/developer/gather.js.map +1 -1
- package/dist/analyzers/developer/index.d.ts +1 -1
- package/dist/analyzers/developer/index.d.ts.map +1 -1
- package/dist/analyzers/developer/index.js +19 -8
- package/dist/analyzers/developer/index.js.map +1 -1
- package/dist/analyzers/dispatcher.d.ts +37 -0
- package/dist/analyzers/dispatcher.d.ts.map +1 -1
- package/dist/analyzers/dispatcher.js +56 -9
- package/dist/analyzers/dispatcher.js.map +1 -1
- package/dist/analyzers/docs/shallow.d.ts +17 -5
- package/dist/analyzers/docs/shallow.d.ts.map +1 -1
- package/dist/analyzers/docs/shallow.js +65 -2
- package/dist/analyzers/docs/shallow.js.map +1 -1
- package/dist/analyzers/dx/shallow.d.ts +17 -5
- package/dist/analyzers/dx/shallow.d.ts.map +1 -1
- package/dist/analyzers/dx/shallow.js +66 -2
- package/dist/analyzers/dx/shallow.js.map +1 -1
- package/dist/analyzers/health/actions.d.ts +1 -1
- package/dist/analyzers/health/actions.d.ts.map +1 -1
- package/dist/analyzers/health/actions.js +27 -9
- package/dist/analyzers/health/actions.js.map +1 -1
- package/dist/analyzers/health/detailed.d.ts +2 -1
- package/dist/analyzers/health/detailed.d.ts.map +1 -1
- package/dist/analyzers/health/detailed.js +11 -7
- package/dist/analyzers/health/detailed.js.map +1 -1
- package/dist/analyzers/health.d.ts +27 -0
- package/dist/analyzers/health.d.ts.map +1 -1
- package/dist/analyzers/health.js +271 -33
- package/dist/analyzers/health.js.map +1 -1
- package/dist/analyzers/licenses/gather.d.ts +35 -8
- package/dist/analyzers/licenses/gather.d.ts.map +1 -1
- package/dist/analyzers/licenses/gather.js +70 -13
- package/dist/analyzers/licenses/gather.js.map +1 -1
- package/dist/analyzers/licenses/index.d.ts +1 -1
- package/dist/analyzers/licenses/index.d.ts.map +1 -1
- package/dist/analyzers/licenses/index.js +52 -11
- package/dist/analyzers/licenses/index.js.map +1 -1
- package/dist/analyzers/licenses/types.d.ts +15 -0
- package/dist/analyzers/licenses/types.d.ts.map +1 -1
- package/dist/analyzers/maintainability/shallow.d.ts +17 -5
- package/dist/analyzers/maintainability/shallow.d.ts.map +1 -1
- package/dist/analyzers/maintainability/shallow.js +80 -2
- package/dist/analyzers/maintainability/shallow.js.map +1 -1
- package/dist/analyzers/quality/detailed.d.ts.map +1 -1
- package/dist/analyzers/quality/detailed.js +4 -6
- package/dist/analyzers/quality/detailed.js.map +1 -1
- package/dist/analyzers/quality/gather.d.ts +1 -14
- package/dist/analyzers/quality/gather.d.ts.map +1 -1
- package/dist/analyzers/quality/gather.js +48 -137
- package/dist/analyzers/quality/gather.js.map +1 -1
- package/dist/analyzers/quality/index.d.ts +9 -2
- package/dist/analyzers/quality/index.d.ts.map +1 -1
- package/dist/analyzers/quality/index.js +189 -117
- package/dist/analyzers/quality/index.js.map +1 -1
- package/dist/analyzers/quality/shallow.d.ts +50 -5
- package/dist/analyzers/quality/shallow.d.ts.map +1 -1
- package/dist/analyzers/quality/shallow.js +155 -2
- package/dist/analyzers/quality/shallow.js.map +1 -1
- package/dist/analyzers/quality/types.d.ts +14 -0
- package/dist/analyzers/quality/types.d.ts.map +1 -1
- package/dist/analyzers/security/actions.d.ts +11 -4
- package/dist/analyzers/security/actions.d.ts.map +1 -1
- package/dist/analyzers/security/actions.js +87 -37
- package/dist/analyzers/security/actions.js.map +1 -1
- package/dist/analyzers/security/aggregator.d.ts +236 -0
- package/dist/analyzers/security/aggregator.d.ts.map +1 -0
- package/dist/analyzers/security/aggregator.js +347 -0
- package/dist/analyzers/security/aggregator.js.map +1 -0
- package/dist/analyzers/security/detailed.d.ts +2 -2
- package/dist/analyzers/security/detailed.d.ts.map +1 -1
- package/dist/analyzers/security/detailed.js +10 -9
- package/dist/analyzers/security/detailed.js.map +1 -1
- package/dist/analyzers/security/gather.d.ts +103 -1
- package/dist/analyzers/security/gather.d.ts.map +1 -1
- package/dist/analyzers/security/gather.js +281 -9
- package/dist/analyzers/security/gather.js.map +1 -1
- package/dist/analyzers/security/index.d.ts +15 -0
- package/dist/analyzers/security/index.d.ts.map +1 -1
- package/dist/analyzers/security/index.js +463 -50
- package/dist/analyzers/security/index.js.map +1 -1
- package/dist/analyzers/security/shallow.d.ts +50 -6
- package/dist/analyzers/security/shallow.d.ts.map +1 -1
- package/dist/analyzers/security/shallow.js +154 -2
- package/dist/analyzers/security/shallow.js.map +1 -1
- package/dist/analyzers/security/types.d.ts +51 -0
- package/dist/analyzers/security/types.d.ts.map +1 -1
- package/dist/analyzers/tests/detailed.d.ts.map +1 -1
- package/dist/analyzers/tests/detailed.js +2 -3
- package/dist/analyzers/tests/detailed.js.map +1 -1
- package/dist/analyzers/tests/gather.d.ts +2 -1
- package/dist/analyzers/tests/gather.d.ts.map +1 -1
- package/dist/analyzers/tests/gather.js +98 -69
- package/dist/analyzers/tests/gather.js.map +1 -1
- package/dist/analyzers/tests/index.d.ts +11 -2
- package/dist/analyzers/tests/index.d.ts.map +1 -1
- package/dist/analyzers/tests/index.js +85 -18
- package/dist/analyzers/tests/index.js.map +1 -1
- package/dist/analyzers/tests/shallow.d.ts +19 -5
- package/dist/analyzers/tests/shallow.d.ts.map +1 -1
- package/dist/analyzers/tests/shallow.js +89 -2
- package/dist/analyzers/tests/shallow.js.map +1 -1
- package/dist/analyzers/tests/types.d.ts +41 -1
- package/dist/analyzers/tests/types.d.ts.map +1 -1
- package/dist/analyzers/tools/autogen-header.d.ts +8 -0
- package/dist/analyzers/tools/autogen-header.d.ts.map +1 -0
- package/dist/analyzers/tools/autogen-header.js +107 -0
- package/dist/analyzers/tools/autogen-header.js.map +1 -0
- package/dist/analyzers/tools/cloc.d.ts.map +1 -1
- package/dist/analyzers/tools/cloc.js +36 -5
- package/dist/analyzers/tools/cloc.js.map +1 -1
- package/dist/analyzers/tools/coverage.d.ts +1 -1
- package/dist/analyzers/tools/coverage.d.ts.map +1 -1
- package/dist/analyzers/tools/coverage.js.map +1 -1
- package/dist/analyzers/tools/debug-statements.d.ts +17 -0
- package/dist/analyzers/tools/debug-statements.d.ts.map +1 -0
- package/dist/analyzers/tools/debug-statements.js +58 -0
- package/dist/analyzers/tools/debug-statements.js.map +1 -0
- package/dist/analyzers/tools/default-exclusions.gitignore +28 -0
- package/dist/analyzers/tools/exclusions.d.ts +33 -6
- package/dist/analyzers/tools/exclusions.d.ts.map +1 -1
- package/dist/analyzers/tools/exclusions.js +95 -26
- package/dist/analyzers/tools/exclusions.js.map +1 -1
- package/dist/analyzers/tools/generic.d.ts +17 -2
- package/dist/analyzers/tools/generic.d.ts.map +1 -1
- package/dist/analyzers/tools/generic.js +206 -109
- package/dist/analyzers/tools/generic.js.map +1 -1
- package/dist/analyzers/tools/gitleaks.d.ts.map +1 -1
- package/dist/analyzers/tools/gitleaks.js +48 -1
- package/dist/analyzers/tools/gitleaks.js.map +1 -1
- package/dist/analyzers/tools/graphify.d.ts +30 -2
- package/dist/analyzers/tools/graphify.d.ts.map +1 -1
- package/dist/analyzers/tools/graphify.js +131 -15
- package/dist/analyzers/tools/graphify.js.map +1 -1
- package/dist/analyzers/tools/jscpd.d.ts +12 -2
- package/dist/analyzers/tools/jscpd.d.ts.map +1 -1
- package/dist/analyzers/tools/jscpd.js +129 -6
- package/dist/analyzers/tools/jscpd.js.map +1 -1
- package/dist/analyzers/tools/minified-detection.d.ts +9 -0
- package/dist/analyzers/tools/minified-detection.d.ts.map +1 -0
- package/dist/analyzers/tools/minified-detection.js +147 -0
- package/dist/analyzers/tools/minified-detection.js.map +1 -0
- package/dist/analyzers/tools/nuget-package-reference.d.ts +131 -0
- package/dist/analyzers/tools/nuget-package-reference.d.ts.map +1 -0
- package/dist/analyzers/tools/nuget-package-reference.js +175 -0
- package/dist/analyzers/tools/nuget-package-reference.js.map +1 -0
- package/dist/analyzers/tools/osv-scanner-deps.d.ts +48 -0
- package/dist/analyzers/tools/osv-scanner-deps.d.ts.map +1 -0
- package/dist/analyzers/tools/{osv-scanner-maven.js → osv-scanner-deps.js} +78 -46
- package/dist/analyzers/tools/osv-scanner-deps.js.map +1 -0
- package/dist/analyzers/tools/osv.d.ts +36 -0
- package/dist/analyzers/tools/osv.d.ts.map +1 -1
- package/dist/analyzers/tools/osv.js +26 -0
- package/dist/analyzers/tools/osv.js.map +1 -1
- package/dist/analyzers/tools/parallel.d.ts +1 -1
- package/dist/analyzers/tools/parallel.d.ts.map +1 -1
- package/dist/analyzers/tools/parallel.js +2 -2
- package/dist/analyzers/tools/parallel.js.map +1 -1
- package/dist/analyzers/tools/risk-score.d.ts +7 -0
- package/dist/analyzers/tools/risk-score.d.ts.map +1 -1
- package/dist/analyzers/tools/risk-score.js +9 -2
- package/dist/analyzers/tools/risk-score.js.map +1 -1
- package/dist/analyzers/tools/run-tests-helper.d.ts +43 -0
- package/dist/analyzers/tools/run-tests-helper.d.ts.map +1 -0
- package/dist/analyzers/tools/run-tests-helper.js +156 -0
- package/dist/analyzers/tools/run-tests-helper.js.map +1 -0
- package/dist/analyzers/tools/runner.d.ts.map +1 -1
- package/dist/analyzers/tools/runner.js +75 -12
- package/dist/analyzers/tools/runner.js.map +1 -1
- package/dist/analyzers/tools/semgrep.d.ts +39 -2
- package/dist/analyzers/tools/semgrep.d.ts.map +1 -1
- package/dist/analyzers/tools/semgrep.js +131 -9
- package/dist/analyzers/tools/semgrep.js.map +1 -1
- package/dist/analyzers/tools/timing.d.ts +17 -3
- package/dist/analyzers/tools/timing.d.ts.map +1 -1
- package/dist/analyzers/tools/timing.js +36 -14
- package/dist/analyzers/tools/timing.js.map +1 -1
- package/dist/analyzers/tools/tool-registry.d.ts +10 -0
- package/dist/analyzers/tools/tool-registry.d.ts.map +1 -1
- package/dist/analyzers/tools/tool-registry.js +120 -1
- package/dist/analyzers/tools/tool-registry.js.map +1 -1
- package/dist/analyzers/tools/tools-unavailable-prose.d.ts +18 -0
- package/dist/analyzers/tools/tools-unavailable-prose.d.ts.map +1 -0
- package/dist/analyzers/tools/tools-unavailable-prose.js +69 -0
- package/dist/analyzers/tools/tools-unavailable-prose.js.map +1 -0
- package/dist/analyzers/tools/upgrade-plan-resolver.d.ts.map +1 -1
- package/dist/analyzers/tools/upgrade-plan-resolver.js +7 -0
- package/dist/analyzers/tools/upgrade-plan-resolver.js.map +1 -1
- package/dist/analyzers/tools/vendored-advisor.d.ts +43 -0
- package/dist/analyzers/tools/vendored-advisor.d.ts.map +1 -0
- package/dist/analyzers/tools/vendored-advisor.js +107 -0
- package/dist/analyzers/tools/vendored-advisor.js.map +1 -0
- package/dist/analyzers/tools/walk-paths.d.ts +78 -0
- package/dist/analyzers/tools/walk-paths.d.ts.map +1 -0
- package/dist/analyzers/tools/walk-paths.js +150 -0
- package/dist/analyzers/tools/walk-paths.js.map +1 -0
- package/dist/analyzers/tools/walk-source-files.d.ts +70 -0
- package/dist/analyzers/tools/walk-source-files.d.ts.map +1 -0
- package/dist/analyzers/tools/walk-source-files.js +369 -0
- package/dist/analyzers/tools/walk-source-files.js.map +1 -0
- package/dist/analyzers/types.d.ts +204 -4
- package/dist/analyzers/types.d.ts.map +1 -1
- package/dist/analyzers/xlsx/bom.d.ts.map +1 -1
- package/dist/analyzers/xlsx/bom.js +8 -1
- package/dist/analyzers/xlsx/bom.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +557 -189
- package/dist/cli.js.map +1 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/detect.d.ts.map +1 -1
- package/dist/detect.js +24 -7
- package/dist/detect.js.map +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +103 -53
- package/dist/doctor.js.map +1 -1
- package/dist/languages/capabilities/provider.d.ts +130 -1
- package/dist/languages/capabilities/provider.d.ts.map +1 -1
- package/dist/languages/capabilities/types.d.ts +68 -7
- package/dist/languages/capabilities/types.d.ts.map +1 -1
- package/dist/languages/csharp.d.ts +15 -1
- package/dist/languages/csharp.d.ts.map +1 -1
- package/dist/languages/csharp.js +624 -146
- package/dist/languages/csharp.js.map +1 -1
- package/dist/languages/go.d.ts.map +1 -1
- package/dist/languages/go.js +89 -11
- package/dist/languages/go.js.map +1 -1
- package/dist/languages/index.d.ts +131 -2
- package/dist/languages/index.d.ts.map +1 -1
- package/dist/languages/index.js +208 -0
- package/dist/languages/index.js.map +1 -1
- package/dist/languages/java.d.ts.map +1 -1
- package/dist/languages/java.js +121 -32
- package/dist/languages/java.js.map +1 -1
- package/dist/languages/kotlin.d.ts.map +1 -1
- package/dist/languages/kotlin.js +140 -32
- package/dist/languages/kotlin.js.map +1 -1
- package/dist/languages/python.d.ts.map +1 -1
- package/dist/languages/python.js +149 -44
- package/dist/languages/python.js.map +1 -1
- package/dist/languages/ruby.d.ts +115 -0
- package/dist/languages/ruby.d.ts.map +1 -0
- package/dist/languages/ruby.js +665 -0
- package/dist/languages/ruby.js.map +1 -0
- package/dist/languages/rust.d.ts.map +1 -1
- package/dist/languages/rust.js +103 -16
- package/dist/languages/rust.js.map +1 -1
- package/dist/languages/types.d.ts +228 -5
- package/dist/languages/types.d.ts.map +1 -1
- package/dist/languages/typescript.d.ts.map +1 -1
- package/dist/languages/typescript.js +201 -14
- package/dist/languages/typescript.js.map +1 -1
- package/dist/scoring/dimensions/documentation.d.ts +53 -0
- package/dist/scoring/dimensions/documentation.d.ts.map +1 -0
- package/dist/scoring/dimensions/documentation.js +106 -0
- package/dist/scoring/dimensions/documentation.js.map +1 -0
- package/dist/scoring/dimensions/dx.d.ts +53 -0
- package/dist/scoring/dimensions/dx.d.ts.map +1 -0
- package/dist/scoring/dimensions/dx.js +105 -0
- package/dist/scoring/dimensions/dx.js.map +1 -0
- package/dist/scoring/dimensions/maintainability.d.ts +53 -0
- package/dist/scoring/dimensions/maintainability.d.ts.map +1 -0
- package/dist/scoring/dimensions/maintainability.js +101 -0
- package/dist/scoring/dimensions/maintainability.js.map +1 -0
- package/dist/scoring/dimensions/quality.d.ts +108 -0
- package/dist/scoring/dimensions/quality.d.ts.map +1 -0
- package/dist/scoring/dimensions/quality.js +174 -0
- package/dist/scoring/dimensions/quality.js.map +1 -0
- package/dist/scoring/dimensions/security.d.ts +84 -0
- package/dist/scoring/dimensions/security.d.ts.map +1 -0
- package/dist/scoring/dimensions/security.js +135 -0
- package/dist/scoring/dimensions/security.js.map +1 -0
- package/dist/scoring/dimensions/testing.d.ts +56 -0
- package/dist/scoring/dimensions/testing.d.ts.map +1 -0
- package/dist/scoring/dimensions/testing.js +98 -0
- package/dist/scoring/dimensions/testing.js.map +1 -0
- package/dist/scoring/evaluator.d.ts +27 -0
- package/dist/scoring/evaluator.d.ts.map +1 -0
- package/dist/scoring/evaluator.js +124 -0
- package/dist/scoring/evaluator.js.map +1 -0
- package/dist/scoring/format.d.ts +34 -0
- package/dist/scoring/format.d.ts.map +1 -0
- package/dist/scoring/format.js +63 -0
- package/dist/scoring/format.js.map +1 -0
- package/dist/scoring/index.d.ts +37 -0
- package/dist/scoring/index.d.ts.map +1 -0
- package/dist/scoring/index.js +57 -0
- package/dist/scoring/index.js.map +1 -0
- package/dist/scoring/overall.d.ts +54 -0
- package/dist/scoring/overall.d.ts.map +1 -0
- package/dist/scoring/overall.js +76 -0
- package/dist/scoring/overall.js.map +1 -0
- package/dist/scoring/result.d.ts +111 -0
- package/dist/scoring/result.d.ts.map +1 -0
- package/dist/scoring/result.js +14 -0
- package/dist/scoring/result.js.map +1 -0
- package/dist/scoring/spec.d.ts +76 -0
- package/dist/scoring/spec.d.ts.map +1 -0
- package/dist/scoring/spec.js +22 -0
- package/dist/scoring/spec.js.map +1 -0
- package/dist/scoring/thresholds.d.ts +56 -0
- package/dist/scoring/thresholds.d.ts.map +1 -0
- package/dist/scoring/thresholds.js +75 -0
- package/dist/scoring/thresholds.js.map +1 -0
- package/dist/tools-cli.d.ts.map +1 -1
- package/dist/tools-cli.js +21 -2
- package/dist/tools-cli.js.map +1 -1
- package/dist/types.d.ts +17 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/templates/.claude/commands/dashboard.md +17 -9
- package/templates/.claude/rules/ruby.md +11 -0
- package/templates/configs/ruby/README.md +6 -0
- package/dist/analyzers/scoring.d.ts +0 -49
- package/dist/analyzers/scoring.d.ts.map +0 -1
- package/dist/analyzers/scoring.js +0 -422
- package/dist/analyzers/scoring.js.map +0 -1
- package/dist/analyzers/security/scoring.d.ts +0 -29
- package/dist/analyzers/security/scoring.d.ts.map +0 -1
- package/dist/analyzers/security/scoring.js +0 -40
- package/dist/analyzers/security/scoring.js.map +0 -1
- package/dist/analyzers/tools/osv-scanner-maven.d.ts +0 -42
- package/dist/analyzers/tools/osv-scanner-maven.d.ts.map +0 -1
- package/dist/analyzers/tools/osv-scanner-maven.js.map +0 -1
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Renderer helpers — turn a `ScoreResult`'s structured provenance
|
|
4
|
+
* into markdown the customer can act on.
|
|
5
|
+
*
|
|
6
|
+
* These functions don't know which dimension they're rendering; they
|
|
7
|
+
* read `topActions[]` + `capsApplied[]` from any spec output and
|
|
8
|
+
* produce consistent prose. Per-dimension renderers (the analyzer
|
|
9
|
+
* subdirs) call into here so the "Top Actions" surface looks the
|
|
10
|
+
* same across every dimension's report.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.formatTopActionLine = formatTopActionLine;
|
|
14
|
+
exports.formatTopActionsBlock = formatTopActionsBlock;
|
|
15
|
+
/** One-line top-action summary, suitable for table cells / CLI grids. */
|
|
16
|
+
function formatTopActionLine(score) {
|
|
17
|
+
const top = score.topActions?.[0];
|
|
18
|
+
if (!top)
|
|
19
|
+
return '';
|
|
20
|
+
const uplift = `+${Math.round(top.upliftIfFixed)}`;
|
|
21
|
+
const transition = top.ratingTransition
|
|
22
|
+
? ` (${top.ratingTransition.from} → ${top.ratingTransition.to})`
|
|
23
|
+
: '';
|
|
24
|
+
return `${top.reason} ${uplift}${transition}`;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Markdown block listing the top N actions for a dimension. Returns
|
|
28
|
+
* an empty array (no lines) when the dimension has no actionable
|
|
29
|
+
* items — caller decides whether to suppress the section header in
|
|
30
|
+
* that case.
|
|
31
|
+
*/
|
|
32
|
+
function formatTopActionsBlock(score, limit = 5) {
|
|
33
|
+
const actions = (score.topActions ?? []).slice(0, limit);
|
|
34
|
+
const lines = [];
|
|
35
|
+
// Severe-debt disclosure (closes D129): when the score floors at 0
|
|
36
|
+
// and the raw penalty went past it, say so. Distinguishes
|
|
37
|
+
// "barely bad" from "catastrophic" in the report itself.
|
|
38
|
+
if (score.score === 0 && typeof score.rawScore === 'number' && score.rawScore < 0) {
|
|
39
|
+
lines.push(`> **Severe:** raw penalty ${Math.round(score.rawScore)} (deductions exceed the floor).`);
|
|
40
|
+
lines.push('');
|
|
41
|
+
}
|
|
42
|
+
// Surface the binding cap separately when one fires — it's the
|
|
43
|
+
// bound on the rating, not just one of many penalties.
|
|
44
|
+
if (score.capsApplied && score.capsApplied.length > 0) {
|
|
45
|
+
const cap = score.capsApplied[0];
|
|
46
|
+
lines.push(`> **Rating cap:** ${cap.reason} — bounded at ${cap.ceiling}/100.`);
|
|
47
|
+
lines.push('');
|
|
48
|
+
}
|
|
49
|
+
if (actions.length === 0)
|
|
50
|
+
return lines;
|
|
51
|
+
lines.push('**Top actions (sorted by score uplift):**');
|
|
52
|
+
lines.push('');
|
|
53
|
+
for (const a of actions) {
|
|
54
|
+
const uplift = `+${Math.round(a.upliftIfFixed)}`;
|
|
55
|
+
const transition = a.ratingTransition
|
|
56
|
+
? ` — would lift rating ${a.ratingTransition.from} → ${a.ratingTransition.to}`
|
|
57
|
+
: '';
|
|
58
|
+
lines.push(`- ${a.reason} \`${uplift}\`${transition}`);
|
|
59
|
+
}
|
|
60
|
+
lines.push('');
|
|
61
|
+
return lines;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/scoring/format.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;AAmBH,kDAQC;AAQD,sDAmCC;AApDD,yEAAyE;AACzE,SAAgB,mBAAmB,CAAC,KAAsB;IACxD,MAAM,GAAG,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;IAClC,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;IACnD,MAAM,UAAU,GAAG,GAAG,CAAC,gBAAgB;QACrC,CAAC,CAAC,KAAK,GAAG,CAAC,gBAAgB,CAAC,IAAI,MAAM,GAAG,CAAC,gBAAgB,CAAC,EAAE,GAAG;QAChE,CAAC,CAAC,EAAE,CAAC;IACP,OAAO,GAAG,GAAG,CAAC,MAAM,IAAI,MAAM,GAAG,UAAU,EAAE,CAAC;AAChD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,qBAAqB,CAAC,KAAsB,EAAE,KAAK,GAAG,CAAC;IACrE,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACzD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,mEAAmE;IACnE,0DAA0D;IAC1D,yDAAyD;IACzD,IAAI,KAAK,CAAC,KAAK,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QAClF,KAAK,CAAC,IAAI,CACR,6BAA6B,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,iCAAiC,CACzF,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,+DAA+D;IAC/D,uDAAuD;IACvD,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtD,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,qBAAqB,GAAG,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC;QAC/E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAEvC,KAAK,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;IACxD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC;QACjD,MAAM,UAAU,GAAG,CAAC,CAAC,gBAAgB;YACnC,CAAC,CAAC,wBAAwB,CAAC,CAAC,gBAAgB,CAAC,IAAI,MAAM,CAAC,CAAC,gBAAgB,CAAC,EAAE,EAAE;YAC9E,CAAC,CAAC,EAAE,CAAC;QACP,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,MAAM,MAAM,KAAK,UAAU,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scoring module public surface.
|
|
3
|
+
*
|
|
4
|
+
* Consumers should import scoring primitives from this barrel rather
|
|
5
|
+
* than reaching into individual files. Per-dimension specs are
|
|
6
|
+
* registered in `dimensions/<name>.ts` (added in subsequent commits;
|
|
7
|
+
* the registry below grows as each dimension migrates).
|
|
8
|
+
*/
|
|
9
|
+
export type { Rating, CapTier, Deduction, CapApplied, TopAction, ScoreResult } from './result';
|
|
10
|
+
export type { PenaltyRule, CapRule, DimensionScoringSpec } from './spec';
|
|
11
|
+
export { RATING_THRESHOLDS, CAP_TIERS, ratingFromScore } from './thresholds';
|
|
12
|
+
export { evaluateSpec } from './evaluator';
|
|
13
|
+
export { formatTopActionLine, formatTopActionsBlock } from './format';
|
|
14
|
+
export type { ScoreResultLike } from './format';
|
|
15
|
+
export { computeOverall, DIMENSION_WEIGHTS, DIMENSION_LABEL } from './overall';
|
|
16
|
+
export type { DimensionId, CrossDimensionAction, OverallResult } from './overall';
|
|
17
|
+
import type { DimensionScoringSpec } from './spec';
|
|
18
|
+
export { SECURITY_SCORING_SPEC } from './dimensions/security';
|
|
19
|
+
export type { SecurityScoreInput } from './dimensions/security';
|
|
20
|
+
export { QUALITY_SCORING_SPEC } from './dimensions/quality';
|
|
21
|
+
export type { QualityScoreInput } from './dimensions/quality';
|
|
22
|
+
export { TESTING_SCORING_SPEC } from './dimensions/testing';
|
|
23
|
+
export type { TestingScoreInput } from './dimensions/testing';
|
|
24
|
+
export { DOCUMENTATION_SCORING_SPEC } from './dimensions/documentation';
|
|
25
|
+
export type { DocumentationScoreInput } from './dimensions/documentation';
|
|
26
|
+
export { MAINTAINABILITY_SCORING_SPEC } from './dimensions/maintainability';
|
|
27
|
+
export type { MaintainabilityScoreInput } from './dimensions/maintainability';
|
|
28
|
+
export { DX_SCORING_SPEC } from './dimensions/dx';
|
|
29
|
+
export type { DxScoreInput } from './dimensions/dx';
|
|
30
|
+
/**
|
|
31
|
+
* Central index of all dimension scoring specs. Each per-dimension
|
|
32
|
+
* spec lands as it migrates from the legacy scorer; consumers
|
|
33
|
+
* iterating over this registry (recipe-playbook test, future
|
|
34
|
+
* cross-dimension renderers) pick up new specs automatically.
|
|
35
|
+
*/
|
|
36
|
+
export declare const SCORING_SPECS: readonly DimensionScoringSpec<unknown>[];
|
|
37
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scoring/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE/F,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAEzE,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACtE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC/E,YAAY,EAAE,WAAW,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAElF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAQnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACxE,YAAY,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AAC5E,YAAY,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,oBAAoB,CAAC,OAAO,CAAC,EAOjE,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Scoring module public surface.
|
|
4
|
+
*
|
|
5
|
+
* Consumers should import scoring primitives from this barrel rather
|
|
6
|
+
* than reaching into individual files. Per-dimension specs are
|
|
7
|
+
* registered in `dimensions/<name>.ts` (added in subsequent commits;
|
|
8
|
+
* the registry below grows as each dimension migrates).
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.SCORING_SPECS = exports.DX_SCORING_SPEC = exports.MAINTAINABILITY_SCORING_SPEC = exports.DOCUMENTATION_SCORING_SPEC = exports.TESTING_SCORING_SPEC = exports.QUALITY_SCORING_SPEC = exports.SECURITY_SCORING_SPEC = exports.DIMENSION_LABEL = exports.DIMENSION_WEIGHTS = exports.computeOverall = exports.formatTopActionsBlock = exports.formatTopActionLine = exports.evaluateSpec = exports.ratingFromScore = exports.CAP_TIERS = exports.RATING_THRESHOLDS = void 0;
|
|
12
|
+
var thresholds_1 = require("./thresholds");
|
|
13
|
+
Object.defineProperty(exports, "RATING_THRESHOLDS", { enumerable: true, get: function () { return thresholds_1.RATING_THRESHOLDS; } });
|
|
14
|
+
Object.defineProperty(exports, "CAP_TIERS", { enumerable: true, get: function () { return thresholds_1.CAP_TIERS; } });
|
|
15
|
+
Object.defineProperty(exports, "ratingFromScore", { enumerable: true, get: function () { return thresholds_1.ratingFromScore; } });
|
|
16
|
+
var evaluator_1 = require("./evaluator");
|
|
17
|
+
Object.defineProperty(exports, "evaluateSpec", { enumerable: true, get: function () { return evaluator_1.evaluateSpec; } });
|
|
18
|
+
var format_1 = require("./format");
|
|
19
|
+
Object.defineProperty(exports, "formatTopActionLine", { enumerable: true, get: function () { return format_1.formatTopActionLine; } });
|
|
20
|
+
Object.defineProperty(exports, "formatTopActionsBlock", { enumerable: true, get: function () { return format_1.formatTopActionsBlock; } });
|
|
21
|
+
var overall_1 = require("./overall");
|
|
22
|
+
Object.defineProperty(exports, "computeOverall", { enumerable: true, get: function () { return overall_1.computeOverall; } });
|
|
23
|
+
Object.defineProperty(exports, "DIMENSION_WEIGHTS", { enumerable: true, get: function () { return overall_1.DIMENSION_WEIGHTS; } });
|
|
24
|
+
Object.defineProperty(exports, "DIMENSION_LABEL", { enumerable: true, get: function () { return overall_1.DIMENSION_LABEL; } });
|
|
25
|
+
const security_1 = require("./dimensions/security");
|
|
26
|
+
const quality_1 = require("./dimensions/quality");
|
|
27
|
+
const testing_1 = require("./dimensions/testing");
|
|
28
|
+
const documentation_1 = require("./dimensions/documentation");
|
|
29
|
+
const maintainability_1 = require("./dimensions/maintainability");
|
|
30
|
+
const dx_1 = require("./dimensions/dx");
|
|
31
|
+
var security_2 = require("./dimensions/security");
|
|
32
|
+
Object.defineProperty(exports, "SECURITY_SCORING_SPEC", { enumerable: true, get: function () { return security_2.SECURITY_SCORING_SPEC; } });
|
|
33
|
+
var quality_2 = require("./dimensions/quality");
|
|
34
|
+
Object.defineProperty(exports, "QUALITY_SCORING_SPEC", { enumerable: true, get: function () { return quality_2.QUALITY_SCORING_SPEC; } });
|
|
35
|
+
var testing_2 = require("./dimensions/testing");
|
|
36
|
+
Object.defineProperty(exports, "TESTING_SCORING_SPEC", { enumerable: true, get: function () { return testing_2.TESTING_SCORING_SPEC; } });
|
|
37
|
+
var documentation_2 = require("./dimensions/documentation");
|
|
38
|
+
Object.defineProperty(exports, "DOCUMENTATION_SCORING_SPEC", { enumerable: true, get: function () { return documentation_2.DOCUMENTATION_SCORING_SPEC; } });
|
|
39
|
+
var maintainability_2 = require("./dimensions/maintainability");
|
|
40
|
+
Object.defineProperty(exports, "MAINTAINABILITY_SCORING_SPEC", { enumerable: true, get: function () { return maintainability_2.MAINTAINABILITY_SCORING_SPEC; } });
|
|
41
|
+
var dx_2 = require("./dimensions/dx");
|
|
42
|
+
Object.defineProperty(exports, "DX_SCORING_SPEC", { enumerable: true, get: function () { return dx_2.DX_SCORING_SPEC; } });
|
|
43
|
+
/**
|
|
44
|
+
* Central index of all dimension scoring specs. Each per-dimension
|
|
45
|
+
* spec lands as it migrates from the legacy scorer; consumers
|
|
46
|
+
* iterating over this registry (recipe-playbook test, future
|
|
47
|
+
* cross-dimension renderers) pick up new specs automatically.
|
|
48
|
+
*/
|
|
49
|
+
exports.SCORING_SPECS = [
|
|
50
|
+
security_1.SECURITY_SCORING_SPEC,
|
|
51
|
+
quality_1.QUALITY_SCORING_SPEC,
|
|
52
|
+
testing_1.TESTING_SCORING_SPEC,
|
|
53
|
+
documentation_1.DOCUMENTATION_SCORING_SPEC,
|
|
54
|
+
maintainability_1.MAINTAINABILITY_SCORING_SPEC,
|
|
55
|
+
dx_1.DX_SCORING_SPEC,
|
|
56
|
+
];
|
|
57
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scoring/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAMH,2CAA6E;AAApE,+GAAA,iBAAiB,OAAA;AAAE,uGAAA,SAAS,OAAA;AAAE,6GAAA,eAAe,OAAA;AACtD,yCAA2C;AAAlC,yGAAA,YAAY,OAAA;AACrB,mCAAsE;AAA7D,6GAAA,mBAAmB,OAAA;AAAE,+GAAA,qBAAqB,OAAA;AAEnD,qCAA+E;AAAtE,yGAAA,cAAc,OAAA;AAAE,4GAAA,iBAAiB,OAAA;AAAE,0GAAA,eAAe,OAAA;AAI3D,oDAA8D;AAC9D,kDAA4D;AAC5D,kDAA4D;AAC5D,8DAAwE;AACxE,kEAA4E;AAC5E,wCAAkD;AAElD,kDAA8D;AAArD,iHAAA,qBAAqB,OAAA;AAE9B,gDAA4D;AAAnD,+GAAA,oBAAoB,OAAA;AAE7B,gDAA4D;AAAnD,+GAAA,oBAAoB,OAAA;AAE7B,4DAAwE;AAA/D,2HAAA,0BAA0B,OAAA;AAEnC,gEAA4E;AAAnE,+HAAA,4BAA4B,OAAA;AAErC,sCAAkD;AAAzC,qGAAA,eAAe,OAAA;AAGxB;;;;;GAKG;AACU,QAAA,aAAa,GAA6C;IACrE,gCAAsD;IACtD,8BAAqD;IACrD,8BAAqD;IACrD,0CAA2D;IAC3D,8CAA6D;IAC7D,oBAAgD;CACjD,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Overall weighted rollup across the six dimension scores.
|
|
3
|
+
*
|
|
4
|
+
* Produces the headline number + letter the customer sees first
|
|
5
|
+
* (dashboard banner, CLI summary line), the rating-tier letter
|
|
6
|
+
* derived from that score via the uniform thresholds in
|
|
7
|
+
* `thresholds.ts`, and a cross-dimension `topActions[]` list
|
|
8
|
+
* sorted by weighted score-impact so the customer sees the
|
|
9
|
+
* single best move across all dimensions.
|
|
10
|
+
*
|
|
11
|
+
* Dimension weights (sum to 1.0):
|
|
12
|
+
* Testing 25%
|
|
13
|
+
* Quality 20%
|
|
14
|
+
* Security 20%
|
|
15
|
+
* Developer Experience 15%
|
|
16
|
+
* Documentation 10%
|
|
17
|
+
* Maintainability 10%
|
|
18
|
+
*
|
|
19
|
+
* Cross-dimension `topActions[]` ranks each dimension's
|
|
20
|
+
* top-action by its weighted contribution to the overall score
|
|
21
|
+
* (`upliftIfFixed * dimensionWeight`). Customers reading the
|
|
22
|
+
* health report's top-of-document recommendation see the single
|
|
23
|
+
* fix that lifts the overall number most — regardless of which
|
|
24
|
+
* dimension it lives in.
|
|
25
|
+
*/
|
|
26
|
+
import type { DimensionScore } from '../analyzers/types';
|
|
27
|
+
import type { Rating, TopAction } from './result';
|
|
28
|
+
export type DimensionId = 'testing' | 'quality' | 'documentation' | 'security' | 'maintainability' | 'developerExperience';
|
|
29
|
+
export declare const DIMENSION_WEIGHTS: Record<DimensionId, number>;
|
|
30
|
+
/** Human-readable label for renderers. */
|
|
31
|
+
export declare const DIMENSION_LABEL: Record<DimensionId, string>;
|
|
32
|
+
/** A top-action lifted across dimensions, retaining which dimension it
|
|
33
|
+
* came from so the renderer can label the source. */
|
|
34
|
+
export interface CrossDimensionAction extends TopAction {
|
|
35
|
+
readonly dimension: DimensionId;
|
|
36
|
+
readonly dimensionLabel: string;
|
|
37
|
+
/** Per-dimension uplift multiplied by the dimension's weight. The
|
|
38
|
+
* cross-dimension list is sorted by this value descending. */
|
|
39
|
+
readonly weightedUplift: number;
|
|
40
|
+
}
|
|
41
|
+
export interface OverallResult {
|
|
42
|
+
readonly overallScore: number;
|
|
43
|
+
readonly rating: Rating;
|
|
44
|
+
/** Cross-dimension top-actions sorted by weighted score-impact. */
|
|
45
|
+
readonly topActions: readonly CrossDimensionAction[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Compute the weighted overall score, rating letter, and cross-
|
|
49
|
+
* dimension top-actions list from the six per-dimension scores.
|
|
50
|
+
*/
|
|
51
|
+
export declare function computeOverall(dimensions: Record<DimensionId, DimensionScore>, options?: {
|
|
52
|
+
topActionsLimit?: number;
|
|
53
|
+
}): OverallResult;
|
|
54
|
+
//# sourceMappingURL=overall.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overall.d.ts","sourceRoot":"","sources":["../../src/scoring/overall.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGlD,MAAM,MAAM,WAAW,GACnB,SAAS,GACT,SAAS,GACT,eAAe,GACf,UAAU,GACV,iBAAiB,GACjB,qBAAqB,CAAC;AAE1B,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAOzD,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAOvD,CAAC;AAEF;sDACsD;AACtD,MAAM,WAAW,oBAAqB,SAAQ,SAAS;IACrD,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC;IAChC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;mEAC+D;IAC/D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,mEAAmE;IACnE,QAAQ,CAAC,UAAU,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACtD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,EAC/C,OAAO,GAAE;IAAE,eAAe,CAAC,EAAE,MAAM,CAAA;CAAO,GACzC,aAAa,CA6Bf"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Overall weighted rollup across the six dimension scores.
|
|
4
|
+
*
|
|
5
|
+
* Produces the headline number + letter the customer sees first
|
|
6
|
+
* (dashboard banner, CLI summary line), the rating-tier letter
|
|
7
|
+
* derived from that score via the uniform thresholds in
|
|
8
|
+
* `thresholds.ts`, and a cross-dimension `topActions[]` list
|
|
9
|
+
* sorted by weighted score-impact so the customer sees the
|
|
10
|
+
* single best move across all dimensions.
|
|
11
|
+
*
|
|
12
|
+
* Dimension weights (sum to 1.0):
|
|
13
|
+
* Testing 25%
|
|
14
|
+
* Quality 20%
|
|
15
|
+
* Security 20%
|
|
16
|
+
* Developer Experience 15%
|
|
17
|
+
* Documentation 10%
|
|
18
|
+
* Maintainability 10%
|
|
19
|
+
*
|
|
20
|
+
* Cross-dimension `topActions[]` ranks each dimension's
|
|
21
|
+
* top-action by its weighted contribution to the overall score
|
|
22
|
+
* (`upliftIfFixed * dimensionWeight`). Customers reading the
|
|
23
|
+
* health report's top-of-document recommendation see the single
|
|
24
|
+
* fix that lifts the overall number most — regardless of which
|
|
25
|
+
* dimension it lives in.
|
|
26
|
+
*/
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
exports.DIMENSION_LABEL = exports.DIMENSION_WEIGHTS = void 0;
|
|
29
|
+
exports.computeOverall = computeOverall;
|
|
30
|
+
const thresholds_1 = require("./thresholds");
|
|
31
|
+
exports.DIMENSION_WEIGHTS = {
|
|
32
|
+
testing: 0.25,
|
|
33
|
+
quality: 0.2,
|
|
34
|
+
security: 0.2,
|
|
35
|
+
developerExperience: 0.15,
|
|
36
|
+
documentation: 0.1,
|
|
37
|
+
maintainability: 0.1,
|
|
38
|
+
};
|
|
39
|
+
/** Human-readable label for renderers. */
|
|
40
|
+
exports.DIMENSION_LABEL = {
|
|
41
|
+
testing: 'Testing',
|
|
42
|
+
quality: 'Code Quality',
|
|
43
|
+
security: 'Security',
|
|
44
|
+
developerExperience: 'Developer Experience',
|
|
45
|
+
documentation: 'Documentation',
|
|
46
|
+
maintainability: 'Maintainability',
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Compute the weighted overall score, rating letter, and cross-
|
|
50
|
+
* dimension top-actions list from the six per-dimension scores.
|
|
51
|
+
*/
|
|
52
|
+
function computeOverall(dimensions, options = {}) {
|
|
53
|
+
const overallScore = Math.round(Object.entries(exports.DIMENSION_WEIGHTS).reduce((sum, [id, w]) => sum + dimensions[id].score * w, 0));
|
|
54
|
+
const crossActions = [];
|
|
55
|
+
for (const id of Object.keys(exports.DIMENSION_WEIGHTS)) {
|
|
56
|
+
const dim = dimensions[id];
|
|
57
|
+
if (!dim.topActions)
|
|
58
|
+
continue;
|
|
59
|
+
for (const action of dim.topActions) {
|
|
60
|
+
crossActions.push({
|
|
61
|
+
...action,
|
|
62
|
+
dimension: id,
|
|
63
|
+
dimensionLabel: exports.DIMENSION_LABEL[id],
|
|
64
|
+
weightedUplift: action.upliftIfFixed * exports.DIMENSION_WEIGHTS[id],
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
crossActions.sort((a, b) => b.weightedUplift - a.weightedUplift);
|
|
69
|
+
const limit = options.topActionsLimit ?? 10;
|
|
70
|
+
return {
|
|
71
|
+
overallScore,
|
|
72
|
+
rating: (0, thresholds_1.ratingFromScore)(overallScore),
|
|
73
|
+
topActions: crossActions.slice(0, limit),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=overall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overall.js","sourceRoot":"","sources":["../../src/scoring/overall.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;;;AAsDH,wCAgCC;AAlFD,6CAA+C;AAUlC,QAAA,iBAAiB,GAAgC;IAC5D,OAAO,EAAE,IAAI;IACb,OAAO,EAAE,GAAG;IACZ,QAAQ,EAAE,GAAG;IACb,mBAAmB,EAAE,IAAI;IACzB,aAAa,EAAE,GAAG;IAClB,eAAe,EAAE,GAAG;CACrB,CAAC;AAEF,0CAA0C;AAC7B,QAAA,eAAe,GAAgC;IAC1D,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,cAAc;IACvB,QAAQ,EAAE,UAAU;IACpB,mBAAmB,EAAE,sBAAsB;IAC3C,aAAa,EAAE,eAAe;IAC9B,eAAe,EAAE,iBAAiB;CACnC,CAAC;AAmBF;;;GAGG;AACH,SAAgB,cAAc,CAC5B,UAA+C,EAC/C,UAAwC,EAAE;IAE1C,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAC5B,MAAM,CAAC,OAAO,CAAC,yBAAiB,CAAkC,CAAC,MAAM,CACxE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,EAChD,CAAC,CACF,CACF,CAAC;IAEF,MAAM,YAAY,GAA2B,EAAE,CAAC;IAChD,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,yBAAiB,CAAkB,EAAE,CAAC;QACjE,MAAM,GAAG,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,UAAU;YAAE,SAAS;QAC9B,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YACpC,YAAY,CAAC,IAAI,CAAC;gBAChB,GAAG,MAAM;gBACT,SAAS,EAAE,EAAE;gBACb,cAAc,EAAE,uBAAe,CAAC,EAAE,CAAC;gBACnC,cAAc,EAAE,MAAM,CAAC,aAAa,GAAG,yBAAiB,CAAC,EAAE,CAAC;aAC7D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC;IAE5C,OAAO;QACL,YAAY;QACZ,MAAM,EAAE,IAAA,4BAAe,EAAC,YAAY,CAAC;QACrC,UAAU,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;KACzC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical score-result envelope produced by `evaluateSpec`.
|
|
3
|
+
*
|
|
4
|
+
* Every dimension's scorer returns this shape. Carries the numeric score,
|
|
5
|
+
* the letter rating, and structured provenance: what was penalized, what
|
|
6
|
+
* caps fired, and the actionable next moves sorted by potential uplift.
|
|
7
|
+
*
|
|
8
|
+
* This shape is the contract between the spec engine and every renderer +
|
|
9
|
+
* agent that consumes scoring output. See STANDARDS.md for methodology
|
|
10
|
+
* citations and `spec.ts` for how dimensions declare penalties and caps.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Uniform rating across all dimensions. Derived from the numeric score
|
|
14
|
+
* via the thresholds in `thresholds.ts` (A≥80, B≥60, C≥40, D≥20, E<20).
|
|
15
|
+
*
|
|
16
|
+
* The numeric 0-100 score is the customer-friendly surface; the letter
|
|
17
|
+
* rating is the industry-anchored claim. Both ship together.
|
|
18
|
+
*/
|
|
19
|
+
export type Rating = 'A' | 'B' | 'C' | 'D' | 'E';
|
|
20
|
+
/**
|
|
21
|
+
* Named cap severity tiers. Each tier maps to a numeric ceiling in
|
|
22
|
+
* `thresholds.ts:CAP_TIERS`. Lower ceiling = more serious disclosure.
|
|
23
|
+
*
|
|
24
|
+
* Tiers express WHAT a cap means, not arbitrary numbers:
|
|
25
|
+
* - `trust-broken`: definite catastrophic failure (committed secrets)
|
|
26
|
+
* - `unmeasured`: no signal at all (testing-null, all quality tools off)
|
|
27
|
+
* - `uncertainty`: key signal source unavailable (dep scanner)
|
|
28
|
+
* - `partial-uncertainty`: some measurement tools didn't run
|
|
29
|
+
* - `fixable-finding`: a concrete bounded finding is open (HIGH+ code)
|
|
30
|
+
*/
|
|
31
|
+
export type CapTier = 'trust-broken' | 'unmeasured' | 'uncertainty' | 'partial-uncertainty' | 'fixable-finding';
|
|
32
|
+
/**
|
|
33
|
+
* A penalty that fired during evaluation. Surfaces the underlying input
|
|
34
|
+
* condition (`reason`), how much the score changed (`delta`), and how
|
|
35
|
+
* much the score WOULD lift if the condition were resolved.
|
|
36
|
+
*
|
|
37
|
+
* `upliftIfFixed` is bounded by any binding cap — when a cap holds the
|
|
38
|
+
* score below the rawScore ceiling, fixing a non-cap deduction yields no
|
|
39
|
+
* actual score change, so this value reads as 0 in that state.
|
|
40
|
+
*/
|
|
41
|
+
export interface Deduction {
|
|
42
|
+
readonly id: string;
|
|
43
|
+
readonly reason: string;
|
|
44
|
+
readonly delta: number;
|
|
45
|
+
readonly upliftIfFixed: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A cap that bound the score below its rawScore. Only the most-aggressive
|
|
49
|
+
* applicable cap binds; non-binding caps (higher ceilings whose conditions
|
|
50
|
+
* are also met) are not surfaced here — they would not constrain the
|
|
51
|
+
* rating until the binding cap clears.
|
|
52
|
+
*
|
|
53
|
+
* `upliftIfRemoved` = how much the score would rise if this cap were
|
|
54
|
+
* lifted. Equals (next-most-aggressive ceiling or unclamped post-penalty
|
|
55
|
+
* score, whichever is lower) minus current score.
|
|
56
|
+
*/
|
|
57
|
+
export interface CapApplied {
|
|
58
|
+
readonly id: string;
|
|
59
|
+
readonly tier: CapTier;
|
|
60
|
+
readonly ceiling: number;
|
|
61
|
+
readonly reason: string;
|
|
62
|
+
readonly upliftIfRemoved: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* One actionable next-move, derived from either a deduction or a cap.
|
|
66
|
+
* Sorted across the result so the highest-uplift item is first.
|
|
67
|
+
*
|
|
68
|
+
* `ratingTransition` is populated when fixing the action would lift the
|
|
69
|
+
* dimension across a rating boundary (e.g., B → A). When undefined, the
|
|
70
|
+
* uplift stays within the current rating band.
|
|
71
|
+
*/
|
|
72
|
+
export interface TopAction {
|
|
73
|
+
readonly source: 'deduction' | 'cap';
|
|
74
|
+
readonly id: string;
|
|
75
|
+
readonly reason: string;
|
|
76
|
+
readonly upliftIfFixed: number;
|
|
77
|
+
readonly ratingTransition?: {
|
|
78
|
+
readonly from: Rating;
|
|
79
|
+
readonly to: Rating;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The full score-result envelope.
|
|
84
|
+
*
|
|
85
|
+
* Field roles:
|
|
86
|
+
* - `score`: the final, post-cap, post-clamp 0-100 number the customer
|
|
87
|
+
* sees on the dimension tile.
|
|
88
|
+
* - `rawScore`: the pre-cap, pre-clamp score. Can be negative if
|
|
89
|
+
* penalties exceeded the baseline. Surfaced so a 0/100 floor reads
|
|
90
|
+
* as "severe — raw -85" rather than indistinguishable from a 0/100
|
|
91
|
+
* where one penalty pushed past the boundary.
|
|
92
|
+
* - `rawPenalty`: the sum of all penalty deltas applied. Equals
|
|
93
|
+
* `rawScore - baseline` for subtractive specs.
|
|
94
|
+
* - `rating`: derived from `score` via uniform thresholds.
|
|
95
|
+
* - `deductions`: every penalty that fired, with structured reason.
|
|
96
|
+
* - `capsApplied`: the binding cap (zero or one entry per result).
|
|
97
|
+
* - `topActions`: union of deductions + caps, sorted by `upliftIfFixed`
|
|
98
|
+
* descending. The renderer reads this for the "what to fix next" UI.
|
|
99
|
+
*/
|
|
100
|
+
export interface ScoreResult {
|
|
101
|
+
readonly dimension: string;
|
|
102
|
+
readonly methodology: string;
|
|
103
|
+
readonly rating: Rating;
|
|
104
|
+
readonly score: number;
|
|
105
|
+
readonly rawScore: number;
|
|
106
|
+
readonly rawPenalty: number;
|
|
107
|
+
readonly deductions: readonly Deduction[];
|
|
108
|
+
readonly capsApplied: readonly CapApplied[];
|
|
109
|
+
readonly topActions: readonly TopAction[];
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../../src/scoring/result.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,MAAM,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEjD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,OAAO,GACf,cAAc,GACd,YAAY,GACZ,aAAa,GACb,qBAAqB,GACrB,iBAAiB,CAAC;AAEtB;;;;;;;;GAQG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,CAAC;IACrC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,CAAC;IAC1C,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;IAC5C,QAAQ,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,CAAC;CAC3C"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Canonical score-result envelope produced by `evaluateSpec`.
|
|
4
|
+
*
|
|
5
|
+
* Every dimension's scorer returns this shape. Carries the numeric score,
|
|
6
|
+
* the letter rating, and structured provenance: what was penalized, what
|
|
7
|
+
* caps fired, and the actionable next moves sorted by potential uplift.
|
|
8
|
+
*
|
|
9
|
+
* This shape is the contract between the spec engine and every renderer +
|
|
10
|
+
* agent that consumes scoring output. See STANDARDS.md for methodology
|
|
11
|
+
* citations and `spec.ts` for how dimensions declare penalties and caps.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
//# sourceMappingURL=result.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result.js","sourceRoot":"","sources":["../../src/scoring/result.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declarative scoring specification — one per dimension.
|
|
3
|
+
*
|
|
4
|
+
* A `DimensionScoringSpec<TInput>` is a self-contained artifact: the
|
|
5
|
+
* baseline score, the list of penalty rules, and the list of cap rules
|
|
6
|
+
* that enforce the dimension's Label Contract. The evaluator
|
|
7
|
+
* (`evaluator.ts`) consumes a spec + input and produces a `ScoreResult`.
|
|
8
|
+
*
|
|
9
|
+
* Specs are values, not functions — each rule is a small object with
|
|
10
|
+
* declarative predicates and reason-builders. This lets us:
|
|
11
|
+
* - register specs in a central index
|
|
12
|
+
* - generate documentation from specs (citations, penalty lists)
|
|
13
|
+
* - test new dimensions by injecting synthetic specs
|
|
14
|
+
* - keep the cross-dimension contract (return shape, rating mapping)
|
|
15
|
+
* uniform regardless of per-dimension methodology
|
|
16
|
+
*
|
|
17
|
+
* Per-dimension specs live in `dimensions/<name>.ts` (one file per
|
|
18
|
+
* dimension, mirroring the LanguageSupport pattern in CLAUDE.md Rule 6).
|
|
19
|
+
*/
|
|
20
|
+
import type { CapTier } from './result';
|
|
21
|
+
/**
|
|
22
|
+
* A single penalty rule. Fires when `applies(input)` returns true; its
|
|
23
|
+
* `delta` (typically negative for subtractive specs, positive for
|
|
24
|
+
* additive specs like Documentation) adjusts the running score.
|
|
25
|
+
*
|
|
26
|
+
* `describe(input)` produces the human-readable reason surfaced in the
|
|
27
|
+
* report ("3 hardcoded secrets detected"). `upliftIfFixed` is optional;
|
|
28
|
+
* when omitted, the evaluator defaults to `Math.abs(delta(input))`.
|
|
29
|
+
* Override when fixing the underlying condition would yield more (or
|
|
30
|
+
* less) than the raw delta — e.g., when fixing a single source also
|
|
31
|
+
* clears a related cap.
|
|
32
|
+
*/
|
|
33
|
+
export interface PenaltyRule<TInput> {
|
|
34
|
+
readonly id: string;
|
|
35
|
+
readonly describe: (input: TInput) => string;
|
|
36
|
+
readonly applies: (input: TInput) => boolean;
|
|
37
|
+
readonly delta: (input: TInput) => number;
|
|
38
|
+
readonly upliftIfFixed?: (input: TInput) => number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A cap rule. Bounds the final score at the tier's ceiling when
|
|
42
|
+
* `applies(input)` returns true. Tier name is the contract; the
|
|
43
|
+
* numeric ceiling comes from `thresholds.ts:CAP_TIERS[tier]`.
|
|
44
|
+
*
|
|
45
|
+
* Caps express the Label Contract: "A grade means no blockers." Each
|
|
46
|
+
* cap names a specific blocker class. The evaluator applies the
|
|
47
|
+
* most-aggressive applicable cap (lowest ceiling); other applicable
|
|
48
|
+
* caps would not bind on the post-cap score and are not surfaced.
|
|
49
|
+
*/
|
|
50
|
+
export interface CapRule<TInput> {
|
|
51
|
+
readonly id: string;
|
|
52
|
+
readonly tier: CapTier;
|
|
53
|
+
readonly describe: (input: TInput) => string;
|
|
54
|
+
readonly applies: (input: TInput) => boolean;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The full dimension scoring specification.
|
|
58
|
+
*
|
|
59
|
+
* `baseline` is the starting score. Subtractive specs (Security,
|
|
60
|
+
* Quality, Maintainability) start at 100; additive checklist specs
|
|
61
|
+
* (Documentation, DevEx) start at 0.
|
|
62
|
+
*
|
|
63
|
+
* `methodology` is a citation key matching an entry in `STANDARDS.md` —
|
|
64
|
+
* e.g., `'iso-iec-5055-severity-dominant'` for the SonarQube-shape
|
|
65
|
+
* Security rating, `'sqale-debt-ratio'` for the Maintainability dim.
|
|
66
|
+
* The renderer surfaces this so customers can trace any score claim to
|
|
67
|
+
* its methodological source.
|
|
68
|
+
*/
|
|
69
|
+
export interface DimensionScoringSpec<TInput> {
|
|
70
|
+
readonly dimension: string;
|
|
71
|
+
readonly methodology: string;
|
|
72
|
+
readonly baseline: number;
|
|
73
|
+
readonly penalties: readonly PenaltyRule<TInput>[];
|
|
74
|
+
readonly caps: readonly CapRule<TInput>[];
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=spec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../src/scoring/spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAExC;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,WAAW,CAAC,MAAM;IACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7C,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1C,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACpD;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,OAAO,CAAC,MAAM;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7C,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;CAC9C;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,oBAAoB,CAAC,MAAM;IAC1C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,SAAS,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;IACnD,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;CAC3C"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Declarative scoring specification — one per dimension.
|
|
4
|
+
*
|
|
5
|
+
* A `DimensionScoringSpec<TInput>` is a self-contained artifact: the
|
|
6
|
+
* baseline score, the list of penalty rules, and the list of cap rules
|
|
7
|
+
* that enforce the dimension's Label Contract. The evaluator
|
|
8
|
+
* (`evaluator.ts`) consumes a spec + input and produces a `ScoreResult`.
|
|
9
|
+
*
|
|
10
|
+
* Specs are values, not functions — each rule is a small object with
|
|
11
|
+
* declarative predicates and reason-builders. This lets us:
|
|
12
|
+
* - register specs in a central index
|
|
13
|
+
* - generate documentation from specs (citations, penalty lists)
|
|
14
|
+
* - test new dimensions by injecting synthetic specs
|
|
15
|
+
* - keep the cross-dimension contract (return shape, rating mapping)
|
|
16
|
+
* uniform regardless of per-dimension methodology
|
|
17
|
+
*
|
|
18
|
+
* Per-dimension specs live in `dimensions/<name>.ts` (one file per
|
|
19
|
+
* dimension, mirroring the LanguageSupport pattern in CLAUDE.md Rule 6).
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
//# sourceMappingURL=spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/scoring/spec.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for rating thresholds and cap ceilings used by
|
|
3
|
+
* every dimension scorer.
|
|
4
|
+
*
|
|
5
|
+
* Uniform 0-100 scale with A/B/C/D/E ratings at 80/60/40/20 boundaries
|
|
6
|
+
* applies to every dimension. The per-dimension methodology determines
|
|
7
|
+
* HOW the numeric score is computed (penalty stacks for some, debt-ratio
|
|
8
|
+
* inversion for others); the score-to-rating mapping is uniform.
|
|
9
|
+
*
|
|
10
|
+
* Cap ceilings encode a severity taxonomy: lower ceiling = more serious
|
|
11
|
+
* disclosure. Each tier name says what it means, not just what it does.
|
|
12
|
+
* See `result.ts:CapTier` for the per-tier semantics.
|
|
13
|
+
*/
|
|
14
|
+
import type { CapTier, Rating } from './result';
|
|
15
|
+
/**
|
|
16
|
+
* Uniform rating thresholds. A repo's letter rating is determined by
|
|
17
|
+
* which band its numeric score falls into.
|
|
18
|
+
*
|
|
19
|
+
* Boundaries chosen so each band spans 20 points (familiar academic
|
|
20
|
+
* grading shape), with the A boundary at 80 matching industry
|
|
21
|
+
* convention for "excellent / no blockers."
|
|
22
|
+
*/
|
|
23
|
+
export declare const RATING_THRESHOLDS: {
|
|
24
|
+
readonly A: 80;
|
|
25
|
+
readonly B: 60;
|
|
26
|
+
readonly C: 40;
|
|
27
|
+
readonly D: 20;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Derive the letter rating for a numeric 0-100 score. Pure function;
|
|
31
|
+
* the same score always maps to the same rating.
|
|
32
|
+
*/
|
|
33
|
+
export declare function ratingFromScore(score: number): Rating;
|
|
34
|
+
/**
|
|
35
|
+
* Cap ceiling per tier. A cap whose condition fires bounds the score at
|
|
36
|
+
* its tier's ceiling, regardless of how clean other signals are.
|
|
37
|
+
*
|
|
38
|
+
* Tier values are derived from the rating boundaries (not picked
|
|
39
|
+
* arbitrarily):
|
|
40
|
+
* - `trust-broken` (40): top of C — a definite catastrophic failure
|
|
41
|
+
* (e.g., committed credentials) cannot leave the dimension above C.
|
|
42
|
+
* - `unmeasured` (35): below C boundary — no signal at all means the
|
|
43
|
+
* dimension can't claim even "Fair."
|
|
44
|
+
* - `uncertainty` (65): middle of B — key signal source unavailable
|
|
45
|
+
* reads as "we can't measure, can't claim A."
|
|
46
|
+
* - `partial-uncertainty` (75): top of B — some tools didn't run;
|
|
47
|
+
* can't claim A but signal exists for what was measured.
|
|
48
|
+
* - `fixable-finding` (79): just-below-A — a concrete bounded finding
|
|
49
|
+
* blocks A specifically. Smallest possible cap claim: "fix the
|
|
50
|
+
* finding and you reach A."
|
|
51
|
+
*
|
|
52
|
+
* Lower number = more serious. The evaluator applies the lowest
|
|
53
|
+
* applicable cap (most aggressive) when multiple conditions hold.
|
|
54
|
+
*/
|
|
55
|
+
export declare const CAP_TIERS: Record<CapTier, number>;
|
|
56
|
+
//# sourceMappingURL=thresholds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thresholds.d.ts","sourceRoot":"","sources":["../../src/scoring/thresholds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEhD;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB;;;;;CAKpB,CAAC;AAEX;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMrD;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAMpC,CAAC"}
|