@xenos1996/usa 2.26.2 → 2.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-help.d.ts.map +1 -1
- package/dist/cli-help.js +2 -0
- package/dist/cli-help.js.map +1 -1
- package/dist/cli-intent.d.ts +4 -0
- package/dist/cli-intent.d.ts.map +1 -0
- package/dist/cli-intent.js +108 -0
- package/dist/cli-intent.js.map +1 -0
- package/dist/cli-scan.d.ts +12 -0
- package/dist/cli-scan.d.ts.map +1 -0
- package/dist/cli-scan.js +142 -0
- package/dist/cli-scan.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +4 -0
- package/dist/cli.js.map +1 -1
- package/dist/engine/audit-config.d.ts +66 -0
- package/dist/engine/audit-config.d.ts.map +1 -0
- package/dist/engine/audit-config.js +148 -0
- package/dist/engine/audit-config.js.map +1 -0
- package/dist/engine/audit-types.d.ts +44 -0
- package/dist/engine/audit-types.d.ts.map +1 -0
- package/dist/engine/audit-types.js +2 -0
- package/dist/engine/audit-types.js.map +1 -0
- package/dist/engine/audit-warnings.d.ts +56 -0
- package/dist/engine/audit-warnings.d.ts.map +1 -0
- package/dist/engine/audit-warnings.js +116 -0
- package/dist/engine/audit-warnings.js.map +1 -0
- package/dist/engine/audit.d.ts +14 -38
- package/dist/engine/audit.d.ts.map +1 -1
- package/dist/engine/audit.js +9 -500
- package/dist/engine/audit.js.map +1 -1
- package/dist/engine/evaluate-packs.d.ts +37 -0
- package/dist/engine/evaluate-packs.d.ts.map +1 -0
- package/dist/engine/evaluate-packs.js +144 -0
- package/dist/engine/evaluate-packs.js.map +1 -0
- package/dist/engine/evaluate.d.ts.map +1 -1
- package/dist/engine/evaluate.js +31 -8
- package/dist/engine/evaluate.js.map +1 -1
- package/dist/engine/invariants.d.ts +8 -0
- package/dist/engine/invariants.d.ts.map +1 -1
- package/dist/engine/invariants.js +11 -0
- package/dist/engine/invariants.js.map +1 -1
- package/dist/engine/pack-selection.d.ts +21 -0
- package/dist/engine/pack-selection.d.ts.map +1 -0
- package/dist/engine/pack-selection.js +63 -0
- package/dist/engine/pack-selection.js.map +1 -0
- package/dist/engine/report-build.d.ts +22 -0
- package/dist/engine/report-build.d.ts.map +1 -0
- package/dist/engine/report-build.js +67 -0
- package/dist/engine/report-build.js.map +1 -0
- package/dist/foundation/interview.d.ts.map +1 -1
- package/dist/foundation/interview.js +16 -5
- package/dist/foundation/interview.js.map +1 -1
- package/dist/intent/match.d.ts +38 -0
- package/dist/intent/match.d.ts.map +1 -0
- package/dist/intent/match.js +108 -0
- package/dist/intent/match.js.map +1 -0
- package/dist/intent/otm.d.ts +16 -0
- package/dist/intent/otm.d.ts.map +1 -0
- package/dist/intent/otm.js +144 -0
- package/dist/intent/otm.js.map +1 -0
- package/dist/intent/types.d.ts +111 -0
- package/dist/intent/types.d.ts.map +1 -0
- package/dist/intent/types.js +16 -0
- package/dist/intent/types.js.map +1 -0
- package/dist/scanner/adapters/codeql.d.ts +14 -0
- package/dist/scanner/adapters/codeql.d.ts.map +1 -0
- package/dist/scanner/adapters/codeql.js +134 -0
- package/dist/scanner/adapters/codeql.js.map +1 -0
- package/dist/scanner/adapters/dependency-cruiser.d.ts +3 -0
- package/dist/scanner/adapters/dependency-cruiser.d.ts.map +1 -0
- package/dist/scanner/adapters/dependency-cruiser.js +174 -0
- package/dist/scanner/adapters/dependency-cruiser.js.map +1 -0
- package/dist/scanner/adapters/ort.d.ts +12 -0
- package/dist/scanner/adapters/ort.d.ts.map +1 -0
- package/dist/scanner/adapters/ort.js +259 -0
- package/dist/scanner/adapters/ort.js.map +1 -0
- package/dist/scanner/adapters/scorecard.d.ts +7 -0
- package/dist/scanner/adapters/scorecard.d.ts.map +1 -0
- package/dist/scanner/adapters/scorecard.js +209 -0
- package/dist/scanner/adapters/scorecard.js.map +1 -0
- package/dist/scanner/adapters/semgrep.d.ts +3 -0
- package/dist/scanner/adapters/semgrep.d.ts.map +1 -0
- package/dist/scanner/adapters/semgrep.js +163 -0
- package/dist/scanner/adapters/semgrep.js.map +1 -0
- package/dist/scanner/adapters/trivy.d.ts +3 -0
- package/dist/scanner/adapters/trivy.d.ts.map +1 -0
- package/dist/scanner/adapters/trivy.js +163 -0
- package/dist/scanner/adapters/trivy.js.map +1 -0
- package/dist/scanner/config.d.ts +4 -0
- package/dist/scanner/config.d.ts.map +1 -0
- package/dist/scanner/config.js +15 -0
- package/dist/scanner/config.js.map +1 -0
- package/dist/scanner/identity.d.ts +17 -0
- package/dist/scanner/identity.d.ts.map +1 -0
- package/dist/scanner/identity.js +50 -0
- package/dist/scanner/identity.js.map +1 -0
- package/dist/scanner/normalize.d.ts +40 -0
- package/dist/scanner/normalize.d.ts.map +1 -0
- package/dist/scanner/normalize.js +85 -0
- package/dist/scanner/normalize.js.map +1 -0
- package/dist/scanner/registry.d.ts +19 -0
- package/dist/scanner/registry.d.ts.map +1 -0
- package/dist/scanner/registry.js +43 -0
- package/dist/scanner/registry.js.map +1 -0
- package/dist/scanner/run.d.ts +70 -0
- package/dist/scanner/run.d.ts.map +1 -0
- package/dist/scanner/run.js +419 -0
- package/dist/scanner/run.js.map +1 -0
- package/dist/scanner/sarif.d.ts +21 -0
- package/dist/scanner/sarif.d.ts.map +1 -0
- package/dist/scanner/sarif.js +156 -0
- package/dist/scanner/sarif.js.map +1 -0
- package/dist/scanner/types.d.ts +236 -0
- package/dist/scanner/types.d.ts.map +1 -0
- package/dist/scanner/types.js +11 -0
- package/dist/scanner/types.js.map +1 -0
- package/package.json +9 -8
- package/rules/core/code-quality.yaml +12 -2
- package/rules/core/provenance-attestation.yaml +5 -0
- package/rules/core/testing-assurance.yaml +19 -4
package/dist/cli-help.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-help.d.ts","sourceRoot":"","sources":["../src/cli-help.ts"],"names":[],"mappings":"AAAA,iGAAiG;AAEjG,eAAO,MAAM,gBAAgB,QAOrB,CAAC;AAET,eAAO,MAAM,cAAc,QAcnB,CAAC;AAET,eAAO,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"cli-help.d.ts","sourceRoot":"","sources":["../src/cli-help.ts"],"names":[],"mappings":"AAAA,iGAAiG;AAEjG,eAAO,MAAM,gBAAgB,QAOrB,CAAC;AAET,eAAO,MAAM,cAAc,QAcnB,CAAC;AAET,eAAO,MAAM,IAAI,QAmIT,CAAC;AAET,eAAO,MAAM,iBAAiB,mbAmB7B,CAAC"}
|
package/dist/cli-help.js
CHANGED
|
@@ -44,6 +44,8 @@ usa — Universal Software Auditor
|
|
|
44
44
|
usa foundation show [path] Print the effective intent and asserted facts
|
|
45
45
|
usa live [path] Conversational audit session (deterministic without a provider)
|
|
46
46
|
usa serve [opts] Localhost audit server (loopback only, bearer token)
|
|
47
|
+
usa scan [path] Run scanner adapters, write a run manifest + evidence
|
|
48
|
+
usa intent <model.json> Compare a declared threat model with observed evidence
|
|
47
49
|
usa models --provider ID List models the provider advertises
|
|
48
50
|
|
|
49
51
|
evolve options
|
package/dist/cli-help.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-help.js","sourceRoot":"","sources":["../src/cli-help.ts"],"names":[],"mappings":"AAAA,iGAAiG;AAEjG,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;CAO/B,CAAC,IAAI,EAAE,CAAC;AAET,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;CAc7B,CAAC,IAAI,EAAE,CAAC;AAET,MAAM,CAAC,MAAM,IAAI,GAAG
|
|
1
|
+
{"version":3,"file":"cli-help.js","sourceRoot":"","sources":["../src/cli-help.ts"],"names":[],"mappings":"AAAA,iGAAiG;AAEjG,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;CAO/B,CAAC,IAAI,EAAE,CAAC;AAET,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;CAc7B,CAAC,IAAI,EAAE,CAAC;AAET,MAAM,CAAC,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmInB,CAAC,IAAI,EAAE,CAAC;AAET,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;CAmBhC,CAAC;AAEF,6BAA6B;AAC7B,6EAA6E;AAC7E,8EAA8E;AAC9E,4EAA4E;AAC5E,6EAA6E;AAC7E,2EAA2E"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type Args } from './cli-args.js';
|
|
2
|
+
export declare const INTENT_HELP = "\nusa intent <model.json> Read a declared threat model (OTM / Threat Dragon export)\n\noptions\n --evidence <file> A `usa scan --json` payload to join against the model\n --json Print the report as JSON\n";
|
|
3
|
+
export declare function cmdIntent(args: Args): number;
|
|
4
|
+
//# sourceMappingURL=cli-intent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-intent.d.ts","sourceRoot":"","sources":["../src/cli-intent.ts"],"names":[],"mappings":"AAaA,OAAO,EAAa,KAAK,IAAI,EAAE,MAAM,eAAe,CAAC;AAKrD,eAAO,MAAM,WAAW,iPAMvB,CAAC;AAEF,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAoC5C"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `usa intent` — read a declared threat model and compare it with observed
|
|
3
|
+
* evidence.
|
|
4
|
+
*
|
|
5
|
+
* Two questions, both deterministic:
|
|
6
|
+
* 1. Which declared threats did any scanner actually observe?
|
|
7
|
+
* 2. Which CWEs did the scanners observe that the model never declared?
|
|
8
|
+
*
|
|
9
|
+
* The second is the more useful one: it is the gap between the design the team
|
|
10
|
+
* wrote down and the weaknesses the tools found.
|
|
11
|
+
*/
|
|
12
|
+
import fs from 'node:fs';
|
|
13
|
+
import path from 'node:path';
|
|
14
|
+
import { bool, str } from './cli-args.js';
|
|
15
|
+
import { parseOtm, IntentFormatError } from './intent/otm.js';
|
|
16
|
+
import { evidenceFromScanJson, matchThreats } from './intent/match.js';
|
|
17
|
+
export const INTENT_HELP = `
|
|
18
|
+
usa intent <model.json> Read a declared threat model (OTM / Threat Dragon export)
|
|
19
|
+
|
|
20
|
+
options
|
|
21
|
+
--evidence <file> A \`usa scan --json\` payload to join against the model
|
|
22
|
+
--json Print the report as JSON
|
|
23
|
+
`;
|
|
24
|
+
export function cmdIntent(args) {
|
|
25
|
+
if (bool(args, 'help')) {
|
|
26
|
+
console.log(INTENT_HELP);
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
29
|
+
const file = args._[1] ?? '';
|
|
30
|
+
if (!file) {
|
|
31
|
+
console.error('usage: usa intent <model.json> [--evidence <scan.json>]');
|
|
32
|
+
return 1;
|
|
33
|
+
}
|
|
34
|
+
const modelPath = path.resolve(file);
|
|
35
|
+
if (!fs.existsSync(modelPath)) {
|
|
36
|
+
console.error(`model not found: ${modelPath}`);
|
|
37
|
+
return 1;
|
|
38
|
+
}
|
|
39
|
+
let report;
|
|
40
|
+
try {
|
|
41
|
+
const model = parseOtm(fs.readFileSync(modelPath, 'utf8'));
|
|
42
|
+
const evidencePath = str(args, 'evidence');
|
|
43
|
+
const evidence = evidencePath ? readEvidence(path.resolve(evidencePath)) : [];
|
|
44
|
+
report = matchThreats(model, evidence);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
// A model that cannot be read is a usage error, not a crash.
|
|
48
|
+
console.error(err instanceof IntentFormatError ? `intent: ${err.message}` : `${err.message}`);
|
|
49
|
+
return 1;
|
|
50
|
+
}
|
|
51
|
+
if (bool(args, 'json')) {
|
|
52
|
+
console.log(JSON.stringify(report, null, 2));
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
printReport(report, Boolean(str(args, 'evidence')));
|
|
56
|
+
return 0;
|
|
57
|
+
}
|
|
58
|
+
function readEvidence(file) {
|
|
59
|
+
if (!fs.existsSync(file))
|
|
60
|
+
throw new Error(`evidence not found: ${file}`);
|
|
61
|
+
return evidenceFromScanJson(JSON.parse(fs.readFileSync(file, 'utf8')));
|
|
62
|
+
}
|
|
63
|
+
function printReport(report, joined) {
|
|
64
|
+
printHeader(report);
|
|
65
|
+
if (!joined) {
|
|
66
|
+
console.log('\nNo --evidence given: the model is read but nothing is compared.');
|
|
67
|
+
console.log('Run `usa scan . --json > scan.json` and pass it with --evidence.');
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
printMatches(report);
|
|
71
|
+
printUnmodelled(report);
|
|
72
|
+
}
|
|
73
|
+
function printHeader(report) {
|
|
74
|
+
const { model } = report;
|
|
75
|
+
console.log(`${model.project.name || 'untitled model'} (OTM ${model.version})`);
|
|
76
|
+
console.log(` ${model.assets.length} assets · ${model.components.length} components · ` +
|
|
77
|
+
`${model.dataFlows.length} flows · ${model.trustZones.length} trust zones · ` +
|
|
78
|
+
`${model.threats.length} threats · ${model.mitigations.length} mitigations`);
|
|
79
|
+
if (model.unrecognised.length > 0) {
|
|
80
|
+
console.log(` not modelled: ${model.unrecognised.join(', ')}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function printMatches(report) {
|
|
84
|
+
const { matches } = report;
|
|
85
|
+
const observed = matches.filter((m) => m.verdict === 'OBSERVED');
|
|
86
|
+
const notObserved = matches.filter((m) => m.verdict === 'NOT_OBSERVED');
|
|
87
|
+
const unknown = matches.filter((m) => m.verdict === 'UNKNOWN');
|
|
88
|
+
console.log(`\nThreats: ${observed.length} observed · ${notObserved.length} not observed · ${unknown.length} unknown`);
|
|
89
|
+
for (const m of observed)
|
|
90
|
+
console.log(` ✅ ${m.threat.name} — ${m.reason} [${m.evidenceIds.join(', ')}]`);
|
|
91
|
+
for (const m of notObserved)
|
|
92
|
+
console.log(` ⚠️ ${m.threat.name} — ${m.reason}`);
|
|
93
|
+
for (const m of unknown)
|
|
94
|
+
console.log(` ❓ ${m.threat.name} — ${m.reason}`);
|
|
95
|
+
}
|
|
96
|
+
function printUnmodelled(report) {
|
|
97
|
+
if (report.unmodeled.length > 0) {
|
|
98
|
+
console.log(`\nObserved but not declared in the model (${report.unmodeled.length}):`);
|
|
99
|
+
for (const u of report.unmodeled)
|
|
100
|
+
console.log(` • ${u.cwe} — ${u.evidenceIds.length} evidence item(s)`);
|
|
101
|
+
}
|
|
102
|
+
if (report.emptyTrustZones.length > 0) {
|
|
103
|
+
console.log(`\nDeclared trust zones with no component (${report.emptyTrustZones.length}):`);
|
|
104
|
+
for (const z of report.emptyTrustZones)
|
|
105
|
+
console.log(` • ${z.name || z.id} (${z.type || 'untyped'})`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=cli-intent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-intent.js","sourceRoot":"","sources":["../src/cli-intent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Args } from './cli-args.js';
|
|
2
|
+
import type { ScanResult } from './scanner/types.js';
|
|
3
|
+
export declare const SCAN_HELP = "\nusa scan [path] Run scanner adapters, write a run manifest + evidence\n\noptions\n --out <file> Evidence report path (default .usa/evidence/<id>.md)\n --scanner <id> Run only this adapter (repeatable, or comma list)\n --network Allow adapters that declare they need network\n --allow-build-commands Permit build-requiring scanners (recorded, opt-in)\n --json Print the manifest and evidence as JSON\n";
|
|
4
|
+
export declare function cmdScan(args: Args): number;
|
|
5
|
+
/** `--scanner a,b` and repeated occurrences both work. */
|
|
6
|
+
export declare function parseScanners(args: Args): string[] | undefined;
|
|
7
|
+
export declare function reportToStdout(result: ScanResult, out: string): void;
|
|
8
|
+
/** A markdown artifact a human can read and a rule pack can cite. */
|
|
9
|
+
export declare function writeEvidenceReport(out: string, result: ScanResult): void;
|
|
10
|
+
/** Exported for tests: which adapters a config enables by default. */
|
|
11
|
+
export declare function defaultEnabled(): string[];
|
|
12
|
+
//# sourceMappingURL=cli-scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-scan.d.ts","sourceRoot":"","sources":["../src/cli-scan.ts"],"names":[],"mappings":"AASA,OAAO,EAAiC,KAAK,IAAI,EAAE,MAAM,eAAe,CAAC;AAIzE,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEjE,eAAO,MAAM,SAAS,geASrB,CAAC;AAEF,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CA6C1C;AAED,0DAA0D;AAC1D,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,GAAG,SAAS,CAO9D;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAYpE;AAED,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAyCzE;AAED,sEAAsE;AACtE,wBAAgB,cAAc,IAAI,MAAM,EAAE,CAEzC"}
|
package/dist/cli-scan.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `usa scan` — run the Tier-1 scanner adapters and write evidence artifacts.
|
|
3
|
+
*
|
|
4
|
+
* This command never merges scanner output into AUDIT.md and never changes a
|
|
5
|
+
* rule verdict: it produces a run manifest plus evidence, which a rule consumes
|
|
6
|
+
* later through the existing `oracle` check. `usa audit` semantics are untouched.
|
|
7
|
+
*/
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
import { str, bool, list, dryRunWrites } from './cli-args.js';
|
|
11
|
+
import { ScannerRunner } from './scanner/run.js';
|
|
12
|
+
import { enabledAdapters, scanners } from './scanner/registry.js';
|
|
13
|
+
import { loadScannerConfig } from './scanner/config.js';
|
|
14
|
+
export const SCAN_HELP = `
|
|
15
|
+
usa scan [path] Run scanner adapters, write a run manifest + evidence
|
|
16
|
+
|
|
17
|
+
options
|
|
18
|
+
--out <file> Evidence report path (default .usa/evidence/<id>.md)
|
|
19
|
+
--scanner <id> Run only this adapter (repeatable, or comma list)
|
|
20
|
+
--network Allow adapters that declare they need network
|
|
21
|
+
--allow-build-commands Permit build-requiring scanners (recorded, opt-in)
|
|
22
|
+
--json Print the manifest and evidence as JSON
|
|
23
|
+
`;
|
|
24
|
+
export function cmdScan(args) {
|
|
25
|
+
if (bool(args, 'help')) {
|
|
26
|
+
console.log(SCAN_HELP);
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
29
|
+
// `_` includes the command word itself (scan .), so the path is index 1.
|
|
30
|
+
const positional = args._[1] ?? '.';
|
|
31
|
+
const root = path.resolve(positional);
|
|
32
|
+
if (!fs.existsSync(root)) {
|
|
33
|
+
console.error(`path not found: ${root}`);
|
|
34
|
+
return 1;
|
|
35
|
+
}
|
|
36
|
+
const runner = new ScannerRunner(scanners);
|
|
37
|
+
const only = parseScanners(args);
|
|
38
|
+
let result;
|
|
39
|
+
try {
|
|
40
|
+
result = runner.run({
|
|
41
|
+
target: root,
|
|
42
|
+
adapters: only,
|
|
43
|
+
config: loadScannerConfig(root),
|
|
44
|
+
network: bool(args, 'network'),
|
|
45
|
+
allowBuildCommands: bool(args, 'allow-build-commands'),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
// A bad --scanner id is a usage error: the message names the known ids.
|
|
50
|
+
console.error(`${err.message}`);
|
|
51
|
+
return 1;
|
|
52
|
+
}
|
|
53
|
+
if (bool(args, 'json')) {
|
|
54
|
+
console.log(JSON.stringify(result, null, 2));
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
// Mirrors `usa audit --out`: a relative path resolves against the target the
|
|
58
|
+
// operator named, so the artifact lands inside that project rather than
|
|
59
|
+
// wherever the process happened to start.
|
|
60
|
+
const outArg = str(args, 'out') ?? ['.usa', 'evidence', result.manifest.executionId + '.md'].join('/');
|
|
61
|
+
const out = path.resolve(root, outArg);
|
|
62
|
+
if (!dryRunWrites(args, [out]))
|
|
63
|
+
return 0;
|
|
64
|
+
writeEvidenceReport(out, result);
|
|
65
|
+
reportToStdout(result, out);
|
|
66
|
+
return 0;
|
|
67
|
+
}
|
|
68
|
+
/** `--scanner a,b` and repeated occurrences both work. */
|
|
69
|
+
export function parseScanners(args) {
|
|
70
|
+
const raw = [...list(args, 'scanner'), ...list(args, 'scanners')];
|
|
71
|
+
const ids = raw
|
|
72
|
+
.flatMap((entry) => entry.split(','))
|
|
73
|
+
.map((s) => s.trim())
|
|
74
|
+
.filter(Boolean);
|
|
75
|
+
return ids.length > 0 ? ids : undefined;
|
|
76
|
+
}
|
|
77
|
+
export function reportToStdout(result, out) {
|
|
78
|
+
const { manifest } = result;
|
|
79
|
+
console.log(`scan ${manifest.target} @ ${manifest.repositoryRevision}`);
|
|
80
|
+
for (const a of manifest.adapters) {
|
|
81
|
+
if (a.status === 'ok') {
|
|
82
|
+
console.log(` ✅ ${a.id} ${a.version} → ${a.evidenceCount} evidence item(s)`);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
console.log(` ⚠️ ${a.id} ${a.status}: ${a.reason ?? 'no detail'}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const findings = result.findings.length;
|
|
89
|
+
console.log(`${result.evidence.length} evidence · ${findings} findings → ${out}`);
|
|
90
|
+
}
|
|
91
|
+
/** A markdown artifact a human can read and a rule pack can cite. */
|
|
92
|
+
export function writeEvidenceReport(out, result) {
|
|
93
|
+
const { manifest, evidence, findings } = result;
|
|
94
|
+
const lines = [
|
|
95
|
+
'# Scanner evidence',
|
|
96
|
+
'',
|
|
97
|
+
`- execution: \`${manifest.executionId}\``,
|
|
98
|
+
`- target: \`${manifest.target}\``,
|
|
99
|
+
`- revision: \`${manifest.repositoryRevision}\``,
|
|
100
|
+
`- timestamp: ${manifest.timestamp}`,
|
|
101
|
+
`- sandbox: ${manifest.environment.sandbox} · network ${manifest.environment.network}`,
|
|
102
|
+
'',
|
|
103
|
+
'## Coverage',
|
|
104
|
+
'',
|
|
105
|
+
'| Adapter | Version | Status | Evidence | Time | Source |',
|
|
106
|
+
'| --- | --- | --- | --- | --- | --- |',
|
|
107
|
+
...manifest.adapters.map((a) => `| ${a.id} | ${a.version || '—'} | ${a.status}${a.reason ? ` (${a.reason})` : ''} | ${a.evidenceCount} | ${a.elapsedMs}ms | ${evidenceSource(a)} |`),
|
|
108
|
+
'',
|
|
109
|
+
'## Evidence',
|
|
110
|
+
'',
|
|
111
|
+
];
|
|
112
|
+
for (const e of evidence) {
|
|
113
|
+
const where = e.location
|
|
114
|
+
? `${e.location.file}${e.location.line ? `:${e.location.line}` : ''}`
|
|
115
|
+
: '—';
|
|
116
|
+
lines.push(`- \`${e.id}\` **${e.source.tool}** ${e.severity} · \`${e.source.identifier}\` — ${e.claim} (${where})`);
|
|
117
|
+
}
|
|
118
|
+
if (findings.length > 0) {
|
|
119
|
+
lines.push('', '## Findings', '');
|
|
120
|
+
for (const f of findings) {
|
|
121
|
+
lines.push(`- **${f.severity}** ${f.title} — ${f.remediation} [evidence: ${f.evidenceIds.join(', ')}]`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
fs.mkdirSync(path.dirname(path.resolve(out)), { recursive: true });
|
|
125
|
+
fs.writeFileSync(out, lines.join('\n') + '\n');
|
|
126
|
+
}
|
|
127
|
+
/** Exported for tests: which adapters a config enables by default. */
|
|
128
|
+
export function defaultEnabled() {
|
|
129
|
+
return enabledAdapters({}).map((a) => a.id);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Where an adapter's evidence came from, and whether the process objected.
|
|
133
|
+
*
|
|
134
|
+
* A tool that writes its payload to a file and one that prints it are different
|
|
135
|
+
* enough to be worth saying out loud: the file-based case is the one that used
|
|
136
|
+
* to be parsed from the wrong stream.
|
|
137
|
+
*/
|
|
138
|
+
function evidenceSource(a) {
|
|
139
|
+
const where = a.artifact ? `\`${a.artifact}\`` : 'stdout';
|
|
140
|
+
return a.exitCode ? `${where} (exit ${a.exitCode})` : where;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=cli-scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-scan.js","sourceRoot":"","sources":["../src/cli-scan.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AA2DA,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA2B7D;AAID,+EAA+E;AAE/E,iBAAS,YAAY,CACnB,KAAK,GAAE,MAAM,GAAG,SAA2B,EAC3C,OAAO,GAAE,MAAwB,GAChC,OAAO,CAOT;AAED,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
package/dist/cli.js
CHANGED
|
@@ -12,6 +12,8 @@ import { cmdDiff, cmdVerifyReport } from './cli-reports.js';
|
|
|
12
12
|
import { cmdBootstrap, cmdInit, cmdLearn } from './cli-scaffold.js';
|
|
13
13
|
import { cmdEvolve } from './cli-evolve.js';
|
|
14
14
|
import { cmdServe } from './cli-serve.js';
|
|
15
|
+
import { cmdScan } from './cli-scan.js';
|
|
16
|
+
import { cmdIntent } from './cli-intent.js';
|
|
15
17
|
/** Dispatch only: every command lives in its own cli-*.ts module. */
|
|
16
18
|
/* -------------------------------------------------------------------- main -- */
|
|
17
19
|
const COMMANDS = {
|
|
@@ -32,6 +34,8 @@ const COMMANDS = {
|
|
|
32
34
|
live: cmdLive,
|
|
33
35
|
models: cmdModels,
|
|
34
36
|
serve: cmdServe,
|
|
37
|
+
scan: cmdScan,
|
|
38
|
+
intent: cmdIntent,
|
|
35
39
|
};
|
|
36
40
|
/** Global --help/--version, resolved before dispatch. Returns null to continue. */
|
|
37
41
|
function handleTopLevelFlags(args, cmd) {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAa,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { Depth, Finding, Maturity, Suppression, UsaConfig } from '../types.js';
|
|
2
|
+
import type { SectionDef } from './sections.js';
|
|
3
|
+
import type { AuditOptions } from './audit-types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Option, config, and policy resolution for an audit run.
|
|
6
|
+
*
|
|
7
|
+
* Everything here turns user input (CLI flags, `.usa.yaml`) into validated
|
|
8
|
+
* values, and every invalid value warns and falls back instead of throwing:
|
|
9
|
+
* a typo in a config file must not brick the audit it configures.
|
|
10
|
+
*/
|
|
11
|
+
export declare const DEFAULT_RULES_DIR: string;
|
|
12
|
+
/** Version of this build, read from package.json so it never drifts. */
|
|
13
|
+
export declare const DEFAULT_VERSION: string;
|
|
14
|
+
export declare function normalizeAuditOptions(options: AuditOptions, config: UsaConfig): {
|
|
15
|
+
rulesDir: string;
|
|
16
|
+
depth: Depth;
|
|
17
|
+
profile: Maturity | "auto";
|
|
18
|
+
allowCommands: boolean;
|
|
19
|
+
usaVersion: string;
|
|
20
|
+
target: string;
|
|
21
|
+
config: UsaConfig;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Expired (or undated) waivers fail closed: an `until` date in the past — or
|
|
25
|
+
* one that cannot be parsed — excludes the suppression and raises a warning,
|
|
26
|
+
* so an audit never silently honours dead risk acceptances.
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveSuppressions(suppressions: Suppression[] | undefined, warnings: string[]): Suppression[];
|
|
29
|
+
export declare function isSuppressionExpired(rule: string, until: string, warnings: string[]): boolean;
|
|
30
|
+
export declare const MATURITIES: Maturity[];
|
|
31
|
+
/**
|
|
32
|
+
* CLI --profile wins; otherwise a valid config `maturity` pins the bar;
|
|
33
|
+
* otherwise auto-detection stands. Invalid config values warn and fall back.
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveMaturity(cliProfile: Maturity | 'auto', configMaturity: Maturity | undefined, detected: Maturity, warnings: string[]): Maturity;
|
|
36
|
+
/** Restrict scoring and reporting to the configured sections, if any. */
|
|
37
|
+
export declare function selectSections(all: SectionDef[], wanted: string[] | undefined, warnings: string[]): SectionDef[];
|
|
38
|
+
/**
|
|
39
|
+
* CLI flags win over config file; both are validated with warnings.
|
|
40
|
+
* Invalid values fall back to engine defaults (never zero, never infinite).
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolveLimits(options: AuditOptions, config: UsaConfig, warnings: string[]): {
|
|
43
|
+
maxFiles?: number;
|
|
44
|
+
maxBytes?: number;
|
|
45
|
+
};
|
|
46
|
+
export declare function validatedLimit(v: number | undefined, name: string, warnings: string[]): number | undefined;
|
|
47
|
+
export declare function resolvePackSets(options: AuditOptions, config: UsaConfig): {
|
|
48
|
+
include: Set<string>;
|
|
49
|
+
exclude: Set<string>;
|
|
50
|
+
};
|
|
51
|
+
export type RuleOverride = {
|
|
52
|
+
severity?: Finding['severity'];
|
|
53
|
+
weight?: number;
|
|
54
|
+
};
|
|
55
|
+
export declare function collectRuleSettings(config: UsaConfig, warnings: string[]): {
|
|
56
|
+
disabled: Set<string>;
|
|
57
|
+
overrides: Record<string, RuleOverride>;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Config overrides flow straight into scoring arithmetic — an invalid severity
|
|
61
|
+
* yields NaN totals and a negative weight yields scores outside 0–100.
|
|
62
|
+
* Reject loudly rather than corrupt the report.
|
|
63
|
+
*/
|
|
64
|
+
export declare function validateOverrideSeverity(id: string, v: unknown, warnings: string[]): RuleOverride['severity'];
|
|
65
|
+
export declare function validateOverrideWeight(id: string, v: unknown, warnings: string[]): number | undefined;
|
|
66
|
+
//# sourceMappingURL=audit-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-config.d.ts","sourceRoot":"","sources":["../../src/engine/audit-config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,QAK7B,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,eAAe,QAYxB,CAAC;AAEL,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS;;;;;;;;EAU7E;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,WAAW,EAAE,GAAG,SAAS,EACvC,QAAQ,EAAE,MAAM,EAAE,GACjB,WAAW,EAAE,CAQf;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAa7F;AAED,eAAO,MAAM,UAAU,EAAE,QAAQ,EAAyD,CAAC;AAE3F;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,QAAQ,GAAG,MAAM,EAC7B,cAAc,EAAE,QAAQ,GAAG,SAAS,EACpC,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAAE,GACjB,QAAQ,CAQV;AAED,yEAAyE;AAEzE,wBAAgB,cAAc,CAC5B,GAAG,EAAE,UAAU,EAAE,EACjB,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAC5B,QAAQ,EAAE,MAAM,EAAE,GACjB,UAAU,EAAE,CAOd;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,MAAM,EAAE,GACjB;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAa1C;AAED,wBAAgB,cAAc,CAC5B,CAAC,EAAE,MAAM,GAAG,SAAS,EACrB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAAE,GACjB,MAAM,GAAG,SAAS,CAKpB;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,SAAS,GAChB;IAAE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAE,CAKhD;AAED,MAAM,MAAM,YAAY,GAAG;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,MAAM,EAAE,GACjB;IACD,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACzC,CAYA;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,MAAM,EACV,CAAC,EAAE,OAAO,EACV,QAAQ,EAAE,MAAM,EAAE,GACjB,YAAY,CAAC,UAAU,CAAC,CAO1B;AAED,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,MAAM,EACV,CAAC,EAAE,OAAO,EACV,QAAQ,EAAE,MAAM,EAAE,GACjB,MAAM,GAAG,SAAS,CAOpB"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { SEVERITY_LADDER } from './loader.js';
|
|
5
|
+
/**
|
|
6
|
+
* Option, config, and policy resolution for an audit run.
|
|
7
|
+
*
|
|
8
|
+
* Everything here turns user input (CLI flags, `.usa.yaml`) into validated
|
|
9
|
+
* values, and every invalid value warns and falls back instead of throwing:
|
|
10
|
+
* a typo in a config file must not brick the audit it configures.
|
|
11
|
+
*/
|
|
12
|
+
export const DEFAULT_RULES_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', 'rules');
|
|
13
|
+
/** Version of this build, read from package.json so it never drifts. */
|
|
14
|
+
export const DEFAULT_VERSION = (() => {
|
|
15
|
+
try {
|
|
16
|
+
const pkg = JSON.parse(fs.readFileSync(path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', 'package.json'), 'utf8'));
|
|
17
|
+
return pkg.version ?? '0.0.0';
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return '0.0.0';
|
|
21
|
+
}
|
|
22
|
+
})();
|
|
23
|
+
export function normalizeAuditOptions(options, config) {
|
|
24
|
+
return {
|
|
25
|
+
rulesDir: options.rulesDir ?? DEFAULT_RULES_DIR,
|
|
26
|
+
depth: options.depth ?? 'standard',
|
|
27
|
+
profile: options.profile ?? 'auto',
|
|
28
|
+
allowCommands: options.allowCommands ?? false,
|
|
29
|
+
usaVersion: options.usaVersion ?? DEFAULT_VERSION,
|
|
30
|
+
target: options.target,
|
|
31
|
+
config,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Expired (or undated) waivers fail closed: an `until` date in the past — or
|
|
36
|
+
* one that cannot be parsed — excludes the suppression and raises a warning,
|
|
37
|
+
* so an audit never silently honours dead risk acceptances.
|
|
38
|
+
*/
|
|
39
|
+
export function resolveSuppressions(suppressions, warnings) {
|
|
40
|
+
const active = [];
|
|
41
|
+
for (const s of suppressions ?? []) {
|
|
42
|
+
if (!s.rule)
|
|
43
|
+
continue;
|
|
44
|
+
if (s.until && isSuppressionExpired(s.rule, s.until, warnings))
|
|
45
|
+
continue;
|
|
46
|
+
active.push(s);
|
|
47
|
+
}
|
|
48
|
+
return active;
|
|
49
|
+
}
|
|
50
|
+
export function isSuppressionExpired(rule, until, warnings) {
|
|
51
|
+
const t = Date.parse(until);
|
|
52
|
+
if (Number.isNaN(t)) {
|
|
53
|
+
warnings.push(`suppression for ${rule} has an unparseable "until" date ("${until}") — waiver ignored`);
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
if (t < Date.now()) {
|
|
57
|
+
warnings.push(`suppression for ${rule} expired on ${until} — treating as an active finding`);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
export const MATURITIES = ['prototype', 'mvp', 'beta', 'production', 'legacy'];
|
|
63
|
+
/**
|
|
64
|
+
* CLI --profile wins; otherwise a valid config `maturity` pins the bar;
|
|
65
|
+
* otherwise auto-detection stands. Invalid config values warn and fall back.
|
|
66
|
+
*/
|
|
67
|
+
export function resolveMaturity(cliProfile, configMaturity, detected, warnings) {
|
|
68
|
+
if (cliProfile !== 'auto')
|
|
69
|
+
return cliProfile;
|
|
70
|
+
if (configMaturity === undefined)
|
|
71
|
+
return detected;
|
|
72
|
+
if (MATURITIES.includes(configMaturity))
|
|
73
|
+
return configMaturity;
|
|
74
|
+
warnings.push(`.usa.yaml: invalid maturity "${String(configMaturity)}" — using auto-detected ${detected}`);
|
|
75
|
+
return detected;
|
|
76
|
+
}
|
|
77
|
+
/** Restrict scoring and reporting to the configured sections, if any. */
|
|
78
|
+
export function selectSections(all, wanted, warnings) {
|
|
79
|
+
if (!wanted || wanted.length === 0)
|
|
80
|
+
return all;
|
|
81
|
+
const known = new Set(all.map((s) => s.id));
|
|
82
|
+
for (const id of wanted) {
|
|
83
|
+
if (!known.has(id))
|
|
84
|
+
warnings.push(`.usa.yaml: unknown section "${id}" in sections — ignored`);
|
|
85
|
+
}
|
|
86
|
+
return all.filter((s) => wanted.includes(s.id));
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* CLI flags win over config file; both are validated with warnings.
|
|
90
|
+
* Invalid values fall back to engine defaults (never zero, never infinite).
|
|
91
|
+
*/
|
|
92
|
+
export function resolveLimits(options, config, warnings) {
|
|
93
|
+
return {
|
|
94
|
+
maxFiles: validatedLimit(options.maxFiles ?? config.limits?.max_files, 'limits.max_files / --max-files', warnings),
|
|
95
|
+
maxBytes: validatedLimit(options.maxBytes ?? config.limits?.max_bytes, 'limits.max_bytes / --max-bytes', warnings),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
export function validatedLimit(v, name, warnings) {
|
|
99
|
+
if (v === undefined)
|
|
100
|
+
return undefined;
|
|
101
|
+
if (typeof v === 'number' && Number.isFinite(v) && v > 0)
|
|
102
|
+
return Math.floor(v);
|
|
103
|
+
warnings.push(`invalid ${name} "${String(v)}" (must be a positive number) — using defaults`);
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
export function resolvePackSets(options, config) {
|
|
107
|
+
return {
|
|
108
|
+
include: new Set(options.includePacks ?? config.include ?? []),
|
|
109
|
+
exclude: new Set(options.excludePacks ?? config.exclude ?? []),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
export function collectRuleSettings(config, warnings) {
|
|
113
|
+
const disabled = new Set();
|
|
114
|
+
const overrides = {};
|
|
115
|
+
for (const [id, o] of Object.entries(config.rules ?? {})) {
|
|
116
|
+
if (o.disabled)
|
|
117
|
+
disabled.add(id);
|
|
118
|
+
const severity = validateOverrideSeverity(id, o.severity, warnings);
|
|
119
|
+
const weight = validateOverrideWeight(id, o.weight, warnings);
|
|
120
|
+
if (severity !== undefined || weight !== undefined) {
|
|
121
|
+
overrides[id] = { severity, weight };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return { disabled, overrides };
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Config overrides flow straight into scoring arithmetic — an invalid severity
|
|
128
|
+
* yields NaN totals and a negative weight yields scores outside 0–100.
|
|
129
|
+
* Reject loudly rather than corrupt the report.
|
|
130
|
+
*/
|
|
131
|
+
export function validateOverrideSeverity(id, v, warnings) {
|
|
132
|
+
if (v === undefined)
|
|
133
|
+
return undefined;
|
|
134
|
+
if (SEVERITY_LADDER.includes(String(v))) {
|
|
135
|
+
return String(v);
|
|
136
|
+
}
|
|
137
|
+
warnings.push(`rules.${id}: invalid severity "${String(v)}" — override ignored`);
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
export function validateOverrideWeight(id, v, warnings) {
|
|
141
|
+
if (v === undefined)
|
|
142
|
+
return undefined;
|
|
143
|
+
if (typeof v === 'number' && Number.isFinite(v) && v >= 0)
|
|
144
|
+
return v;
|
|
145
|
+
warnings.push(`rules.${id}: invalid weight "${String(v)}" (must be a finite number ≥ 0) — override ignored`);
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=audit-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-config.js","sourceRoot":"","sources":["../../src/engine/audit-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { AuditReport, Depth, Maturity, RulePack, UsaConfig } from '../types.js';
|
|
2
|
+
import type { MaturityProfile } from './maturity.js';
|
|
3
|
+
/**
|
|
4
|
+
* The public shape of an audit run, in its own module so the audit
|
|
5
|
+
* coordinator and the option/pack/report helpers can all depend on it
|
|
6
|
+
* without importing each other.
|
|
7
|
+
*/
|
|
8
|
+
export interface AuditOptions {
|
|
9
|
+
target: string;
|
|
10
|
+
rulesDir?: string;
|
|
11
|
+
depth?: Depth;
|
|
12
|
+
profile?: Maturity | 'auto';
|
|
13
|
+
config?: UsaConfig;
|
|
14
|
+
allowCommands?: boolean;
|
|
15
|
+
usaVersion?: string;
|
|
16
|
+
/** Force these pack ids on/off regardless of detection. */
|
|
17
|
+
includePacks?: string[];
|
|
18
|
+
excludePacks?: string[];
|
|
19
|
+
/** Indexing caps for bigger-than-comfortable trees (CLI wins over config). */
|
|
20
|
+
maxFiles?: number;
|
|
21
|
+
maxBytes?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Extra rule packs merged into the loaded set for this run only. This is how
|
|
24
|
+
* the evolution layer injects a *released* capability into a re-audit without
|
|
25
|
+
* mutating the on-disk `rules/` registry — the resolved capability set lives
|
|
26
|
+
* in `capabilitySetId`, not in the filesystem. The CLI never passes this, so
|
|
27
|
+
* `usa audit` behaviour is unchanged.
|
|
28
|
+
*/
|
|
29
|
+
extraPacks?: RulePack[];
|
|
30
|
+
/**
|
|
31
|
+
* Include the documentation universe audit (14 categories / 220 artifacts,
|
|
32
|
+
* rules/docs-taxonomy.yaml) in this run: DOCU-* findings join S12. Opt-in
|
|
33
|
+
* (CLI `--docs-universe` or `.usa.yaml` `docs.universe: true`) so existing
|
|
34
|
+
* baselines stay stable; the standalone `usa docs audit` runs the same
|
|
35
|
+
* computation and must agree (AC-8).
|
|
36
|
+
*/
|
|
37
|
+
docsUniverse?: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface AuditOutcome {
|
|
40
|
+
report: AuditReport;
|
|
41
|
+
warnings: string[];
|
|
42
|
+
profile: MaturityProfile;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=audit-types.d.ts.map
|