audit-tools 0.42.1 → 0.43.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/dispatch/merge-results.mjs +229 -140
- package/dispatch/validate-result.mjs +98 -40
- package/dist/audit/cli/conceptualDispatch.d.ts.map +1 -1
- package/dist/audit/cli/conceptualDispatch.js +35 -3
- package/dist/audit/cli/conceptualDispatch.js.map +1 -1
- package/dist/audit/cli/dispatch/hostHandoff.d.ts +9 -1
- package/dist/audit/cli/dispatch/hostHandoff.d.ts.map +1 -1
- package/dist/audit/cli/dispatch/hostHandoff.js +94 -38
- package/dist/audit/cli/dispatch/hostHandoff.js.map +1 -1
- package/dist/audit/cli/nextStepCommand.d.ts +64 -0
- package/dist/audit/cli/nextStepCommand.d.ts.map +1 -1
- package/dist/audit/cli/nextStepCommand.js +877 -783
- package/dist/audit/cli/nextStepCommand.js.map +1 -1
- package/dist/audit/cli/nextStepHelpers.d.ts +12 -0
- package/dist/audit/cli/nextStepHelpers.d.ts.map +1 -1
- package/dist/audit/cli/nextStepHelpers.js +34 -1
- package/dist/audit/cli/nextStepHelpers.js.map +1 -1
- package/dist/audit/cli/steps.d.ts +2 -2
- package/dist/audit/extractors/graph.d.ts +28 -2
- package/dist/audit/extractors/graph.d.ts.map +1 -1
- package/dist/audit/extractors/graph.js +122 -11
- package/dist/audit/extractors/graph.js.map +1 -1
- package/dist/audit/extractors/graphRoutes.d.ts +8 -0
- package/dist/audit/extractors/graphRoutes.d.ts.map +1 -1
- package/dist/audit/extractors/graphRoutes.js +71 -4
- package/dist/audit/extractors/graphRoutes.js.map +1 -1
- package/dist/audit/io/artifacts.d.ts +55 -0
- package/dist/audit/io/artifacts.d.ts.map +1 -1
- package/dist/audit/io/artifacts.js +189 -12
- package/dist/audit/io/artifacts.js.map +1 -1
- package/dist/audit/io/toolingManifest.d.ts +11 -0
- package/dist/audit/io/toolingManifest.d.ts.map +1 -1
- package/dist/audit/io/toolingManifest.js +13 -3
- package/dist/audit/io/toolingManifest.js.map +1 -1
- package/dist/audit/orchestrator/advance.d.ts +64 -0
- package/dist/audit/orchestrator/advance.d.ts.map +1 -1
- package/dist/audit/orchestrator/advance.js +191 -57
- package/dist/audit/orchestrator/advance.js.map +1 -1
- package/dist/audit/orchestrator/charterClarificationExecutor.d.ts.map +1 -1
- package/dist/audit/orchestrator/charterClarificationExecutor.js +55 -21
- package/dist/audit/orchestrator/charterClarificationExecutor.js.map +1 -1
- package/dist/audit/orchestrator/flowCoverage.d.ts.map +1 -1
- package/dist/audit/orchestrator/flowCoverage.js +7 -10
- package/dist/audit/orchestrator/flowCoverage.js.map +1 -1
- package/dist/audit/orchestrator/flowPlanning.d.ts +54 -1
- package/dist/audit/orchestrator/flowPlanning.d.ts.map +1 -1
- package/dist/audit/orchestrator/flowPlanning.js +77 -18
- package/dist/audit/orchestrator/flowPlanning.js.map +1 -1
- package/dist/audit/orchestrator/flowRequeue.d.ts.map +1 -1
- package/dist/audit/orchestrator/flowRequeue.js +6 -10
- package/dist/audit/orchestrator/flowRequeue.js.map +1 -1
- package/dist/audit/orchestrator/requeueFold.d.ts.map +1 -1
- package/dist/audit/orchestrator/requeueFold.js +18 -5
- package/dist/audit/orchestrator/requeueFold.js.map +1 -1
- package/dist/audit/orchestrator/staleness.d.ts +24 -1
- package/dist/audit/orchestrator/staleness.d.ts.map +1 -1
- package/dist/audit/orchestrator/staleness.js +147 -16
- package/dist/audit/orchestrator/staleness.js.map +1 -1
- package/dist/audit/orchestrator/syntaxResolutionExecutor.d.ts +26 -0
- package/dist/audit/orchestrator/syntaxResolutionExecutor.d.ts.map +1 -1
- package/dist/audit/orchestrator/syntaxResolutionExecutor.js +97 -12
- package/dist/audit/orchestrator/syntaxResolutionExecutor.js.map +1 -1
- package/dist/audit/orchestrator/taskBuilder.d.ts.map +1 -1
- package/dist/audit/orchestrator/taskBuilder.js +111 -21
- package/dist/audit/orchestrator/taskBuilder.js.map +1 -1
- package/dist/audit/orchestrator/trivialAudit.d.ts +17 -1
- package/dist/audit/orchestrator/trivialAudit.d.ts.map +1 -1
- package/dist/audit/orchestrator/trivialAudit.js +31 -4
- package/dist/audit/orchestrator/trivialAudit.js.map +1 -1
- package/dist/audit/types/analyzerCapability.d.ts +6 -6
- package/dist/audit/types/charterRegister.d.ts +30 -12
- package/dist/audit/types/charterRegister.d.ts.map +1 -1
- package/dist/audit/types/charterRegister.js +22 -9
- package/dist/audit/types/charterRegister.js.map +1 -1
- package/dist/audit/validation/anchorGrounding.d.ts.map +1 -1
- package/dist/audit/validation/anchorGrounding.js +17 -0
- package/dist/audit/validation/anchorGrounding.js.map +1 -1
- package/dist/audit/validation/auditResults.d.ts +17 -0
- package/dist/audit/validation/auditResults.d.ts.map +1 -1
- package/dist/audit/validation/auditResults.js +50 -17
- package/dist/audit/validation/auditResults.js.map +1 -1
- package/dist/remediate/contractPipeline/cyclicSeamResolution.d.ts +48 -0
- package/dist/remediate/contractPipeline/cyclicSeamResolution.d.ts.map +1 -1
- package/dist/remediate/contractPipeline/cyclicSeamResolution.js +128 -0
- package/dist/remediate/contractPipeline/cyclicSeamResolution.js.map +1 -1
- package/dist/remediate/contractPipeline/derive.d.ts +8 -5
- package/dist/remediate/contractPipeline/derive.d.ts.map +1 -1
- package/dist/remediate/contractPipeline/derive.js +8 -16
- package/dist/remediate/contractPipeline/derive.js.map +1 -1
- package/dist/remediate/index.d.ts.map +1 -1
- package/dist/remediate/index.js +43 -2
- package/dist/remediate/index.js.map +1 -1
- package/dist/remediate/intent/intentOrdering.d.ts +13 -5
- package/dist/remediate/intent/intentOrdering.d.ts.map +1 -1
- package/dist/remediate/intent/intentOrdering.js +56 -25
- package/dist/remediate/intent/intentOrdering.js.map +1 -1
- package/dist/remediate/phases/close.d.ts +57 -2
- package/dist/remediate/phases/close.d.ts.map +1 -1
- package/dist/remediate/phases/close.js +260 -36
- package/dist/remediate/phases/close.js.map +1 -1
- package/dist/remediate/state/disposition.d.ts +26 -4
- package/dist/remediate/state/disposition.d.ts.map +1 -1
- package/dist/remediate/state/itemStatus.d.ts +33 -6
- package/dist/remediate/state/itemStatus.d.ts.map +1 -1
- package/dist/remediate/state/itemStatus.js +154 -39
- package/dist/remediate/state/itemStatus.js.map +1 -1
- package/dist/remediate/state/types.d.ts +41 -2
- package/dist/remediate/state/types.d.ts.map +1 -1
- package/dist/remediate/state/types.js.map +1 -1
- package/dist/remediate/steps/contractPipeline.d.ts +287 -15
- package/dist/remediate/steps/contractPipeline.d.ts.map +1 -1
- package/dist/remediate/steps/contractPipeline.js +1655 -981
- package/dist/remediate/steps/contractPipeline.js.map +1 -1
- package/dist/remediate/steps/dispatch/hostHandoff.d.ts +137 -2
- package/dist/remediate/steps/dispatch/hostHandoff.d.ts.map +1 -1
- package/dist/remediate/steps/dispatch/hostHandoff.js +713 -59
- package/dist/remediate/steps/dispatch/hostHandoff.js.map +1 -1
- package/dist/remediate/steps/finalGate.d.ts +136 -37
- package/dist/remediate/steps/finalGate.d.ts.map +1 -1
- package/dist/remediate/steps/finalGate.js +120 -86
- package/dist/remediate/steps/finalGate.js.map +1 -1
- package/dist/remediate/steps/gateCommands.d.ts +8 -0
- package/dist/remediate/steps/gateCommands.d.ts.map +1 -1
- package/dist/remediate/steps/gateCommands.js +40 -11
- package/dist/remediate/steps/gateCommands.js.map +1 -1
- package/dist/remediate/steps/nextStep.d.ts +96 -5
- package/dist/remediate/steps/nextStep.d.ts.map +1 -1
- package/dist/remediate/steps/nextStep.js +668 -147
- package/dist/remediate/steps/nextStep.js.map +1 -1
- package/dist/remediate/steps/types.d.ts +4 -1
- package/dist/remediate/steps/types.d.ts.map +1 -1
- package/dist/remediate/steps/types.js +10 -0
- package/dist/remediate/steps/types.js.map +1 -1
- package/dist/remediate/validation/artifacts.d.ts +20 -0
- package/dist/remediate/validation/artifacts.d.ts.map +1 -1
- package/dist/remediate/validation/artifacts.js +239 -13
- package/dist/remediate/validation/artifacts.js.map +1 -1
- package/dist/remediate/validation/contractPipelineGates.d.ts +58 -0
- package/dist/remediate/validation/contractPipelineGates.d.ts.map +1 -1
- package/dist/remediate/validation/contractPipelineGates.js +143 -27
- package/dist/remediate/validation/contractPipelineGates.js.map +1 -1
- package/dist/shared/analyzers/acquisitionEngine.d.ts +72 -25
- package/dist/shared/analyzers/acquisitionEngine.d.ts.map +1 -1
- package/dist/shared/analyzers/acquisitionEngine.js +149 -15
- package/dist/shared/analyzers/acquisitionEngine.js.map +1 -1
- package/dist/shared/analyzers/binaryAcquisition.d.ts +27 -2
- package/dist/shared/analyzers/binaryAcquisition.d.ts.map +1 -1
- package/dist/shared/analyzers/binaryAcquisition.js +149 -43
- package/dist/shared/analyzers/binaryAcquisition.js.map +1 -1
- package/dist/shared/analyzers/candidates.d.ts +9 -8
- package/dist/shared/analyzers/candidates.d.ts.map +1 -1
- package/dist/shared/analyzers/candidates.js +96 -64
- package/dist/shared/analyzers/candidates.js.map +1 -1
- package/dist/shared/analyzers/normalizeExternal.d.ts +40 -12
- package/dist/shared/analyzers/normalizeExternal.d.ts.map +1 -1
- package/dist/shared/analyzers/normalizeExternal.js +74 -18
- package/dist/shared/analyzers/normalizeExternal.js.map +1 -1
- package/dist/shared/analyzers/rubocop.d.ts +14 -13
- package/dist/shared/analyzers/rubocop.d.ts.map +1 -1
- package/dist/shared/analyzers/rubocop.js +29 -6
- package/dist/shared/analyzers/rubocop.js.map +1 -1
- package/dist/shared/analyzers/types.d.ts +196 -13
- package/dist/shared/analyzers/types.d.ts.map +1 -1
- package/dist/shared/analyzers/types.js +122 -9
- package/dist/shared/analyzers/types.js.map +1 -1
- package/dist/shared/decompose/charterClarification.d.ts +12 -1
- package/dist/shared/decompose/charterClarification.d.ts.map +1 -1
- package/dist/shared/decompose/charterClarification.js +11 -4
- package/dist/shared/decompose/charterClarification.js.map +1 -1
- package/dist/shared/decompose/charterExtraction.d.ts +20 -10
- package/dist/shared/decompose/charterExtraction.d.ts.map +1 -1
- package/dist/shared/decompose/charterExtraction.js +52 -23
- package/dist/shared/decompose/charterExtraction.js.map +1 -1
- package/dist/shared/intent/freeFormIntentInterpreter.d.ts +12 -2
- package/dist/shared/intent/freeFormIntentInterpreter.d.ts.map +1 -1
- package/dist/shared/intent/freeFormIntentInterpreter.js +27 -22
- package/dist/shared/intent/freeFormIntentInterpreter.js.map +1 -1
- package/dist/shared/intent/pathScope.d.ts +12 -1
- package/dist/shared/intent/pathScope.d.ts.map +1 -1
- package/dist/shared/intent/pathScope.js +56 -19
- package/dist/shared/intent/pathScope.js.map +1 -1
- package/dist/shared/intent/sharedIntentData.d.ts +19 -1
- package/dist/shared/intent/sharedIntentData.d.ts.map +1 -1
- package/dist/shared/intent/sharedIntentData.js +33 -8
- package/dist/shared/intent/sharedIntentData.js.map +1 -1
- package/dist/shared/io/fileLock.d.ts +12 -0
- package/dist/shared/io/fileLock.d.ts.map +1 -1
- package/dist/shared/io/fileLock.js +48 -5
- package/dist/shared/io/fileLock.js.map +1 -1
- package/dist/shared/io/json.d.ts +13 -0
- package/dist/shared/io/json.d.ts.map +1 -1
- package/dist/shared/io/json.js +19 -1
- package/dist/shared/io/json.js.map +1 -1
- package/dist/shared/steps/stepEmissionScaffold.d.ts +69 -0
- package/dist/shared/steps/stepEmissionScaffold.d.ts.map +1 -0
- package/dist/shared/steps/stepEmissionScaffold.js +83 -0
- package/dist/shared/steps/stepEmissionScaffold.js.map +1 -0
- package/dist/shared/submission/handRecovery.d.ts.map +1 -1
- package/dist/shared/submission/handRecovery.js +69 -4
- package/dist/shared/submission/handRecovery.js.map +1 -1
- package/dist/shared/submission/submissionIdentity.d.ts +10 -1
- package/dist/shared/submission/submissionIdentity.d.ts.map +1 -1
- package/dist/shared/submission/submissionIdentity.js +12 -3
- package/dist/shared/submission/submissionIdentity.js.map +1 -1
- package/dist/shared/submission/submissionLedger.d.ts +43 -2
- package/dist/shared/submission/submissionLedger.d.ts.map +1 -1
- package/dist/shared/submission/submissionLedger.js +50 -7
- package/dist/shared/submission/submissionLedger.js.map +1 -1
- package/dist/shared/tooling/allowlistedExec.d.ts +9 -0
- package/dist/shared/tooling/allowlistedExec.d.ts.map +1 -1
- package/dist/shared/tooling/allowlistedExec.js +19 -2
- package/dist/shared/tooling/allowlistedExec.js.map +1 -1
- package/dist/shared/types/charter.d.ts +24 -0
- package/dist/shared/types/charter.d.ts.map +1 -1
- package/dist/shared/types/charter.js +9 -0
- package/dist/shared/types/charter.js.map +1 -1
- package/dist/shared/types/remediationOutcome.d.ts +282 -9
- package/dist/shared/types/remediationOutcome.d.ts.map +1 -1
- package/dist/shared/types/remediationOutcome.js +174 -1
- package/dist/shared/types/remediationOutcome.js.map +1 -1
- package/package.json +2 -1
- package/remediate-code.mjs +15 -0
- package/wrapper/remediate-code-wrapper-install-hosts.mjs +45 -4
- package/wrapper/remediate-code-wrapper-install-renderers.mjs +12 -2
|
@@ -2,6 +2,7 @@ import { existsSync, readFileSync, rmSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { runTracked } from "../tooling/exec.js";
|
|
4
4
|
import { normalizeGenericExternalResults, normalizeGenericExternalEdges, } from "./normalizeExternal.js";
|
|
5
|
+
import { readParseOutcome, } from "./types.js";
|
|
5
6
|
import { resolveBinary, } from "./binaryAcquisition.js";
|
|
6
7
|
/**
|
|
7
8
|
* F5 — external analyzer acquisition engine.
|
|
@@ -94,24 +95,77 @@ function runnerPrefix(runner, spec) {
|
|
|
94
95
|
case "binary": return [];
|
|
95
96
|
}
|
|
96
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* The denial vocabulary. An operator refusal and a tool nobody has decided on are
|
|
100
|
+
* DIFFERENT causes and must be distinguishable in the persisted status record — a
|
|
101
|
+
* single conflated string cannot tell an operator that their own decline was the
|
|
102
|
+
* reason. Every CONSENT-channel reason names "consent"; `setting_skip` deliberately
|
|
103
|
+
* does not, because it comes from the settings channel (`analyzers.<id> = "skip"`)
|
|
104
|
+
* and is not a consent decision at all.
|
|
105
|
+
*/
|
|
106
|
+
export const ANALYZER_DENIAL_REASONS = {
|
|
107
|
+
/** `analyzers.<id> = "skip"` — the settings channel, not the consent record. */
|
|
108
|
+
setting_skip: "setting=skip",
|
|
109
|
+
/** A recorded, durable operator refusal. Terminal: no token overrides it. */
|
|
110
|
+
consent_declined: "consent declined by the operator for this analyzer (recorded decision)",
|
|
111
|
+
/** No decision recorded and no token presented — nobody has said yes OR no. */
|
|
112
|
+
consent_not_decided: "consent not recorded for this analyzer (not yet decided; no consent token for this run)",
|
|
113
|
+
/** A token was presented, but it was issued for a different analyzer. */
|
|
114
|
+
consent_token_scope: "consent token was not issued for this analyzer (scoped consent covers other tools only)",
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Does this consent input authorize THIS candidate?
|
|
118
|
+
*
|
|
119
|
+
* A scoped grant authorizes exactly the tools it names — a grant obtained by offering
|
|
120
|
+
* tool A cannot admit tool B. The legacy bare string carries no scope, so it can only
|
|
121
|
+
* be read as run-wide; it is accepted for compatibility with the acquisition entry
|
|
122
|
+
* point that still issues one, and is deliberately reported distinctly here so the
|
|
123
|
+
* unscoped case is visible rather than indistinguishable from a scoped grant.
|
|
124
|
+
*/
|
|
125
|
+
function consentTokenAdmits(consentToken, candidateId) {
|
|
126
|
+
if (consentToken === undefined || consentToken === null)
|
|
127
|
+
return "absent";
|
|
128
|
+
if (typeof consentToken === "string") {
|
|
129
|
+
return consentToken.trim().length > 0 ? "admit" : "absent";
|
|
130
|
+
}
|
|
131
|
+
if (typeof consentToken.value !== "string" || consentToken.value.trim().length === 0) {
|
|
132
|
+
return "absent";
|
|
133
|
+
}
|
|
134
|
+
if (!Array.isArray(consentToken.tools))
|
|
135
|
+
return "out_of_scope";
|
|
136
|
+
return consentToken.tools.includes(candidateId) ? "admit" : "out_of_scope";
|
|
137
|
+
}
|
|
97
138
|
/**
|
|
98
139
|
* Single subprocess-SPAWN admission chokepoint. Returns the reason a spawn is
|
|
99
|
-
* NOT admitted, or `undefined` when admitted.
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
140
|
+
* NOT admitted, or `undefined` when admitted.
|
|
141
|
+
*
|
|
142
|
+
* ORDER IS THE CONTRACT. A recorded `"declined"` is consulted FIRST — before the
|
|
143
|
+
* settings channel, before the DEFAULT-set short-circuit, and before any consent
|
|
144
|
+
* token — so an operator refusal is a veto for EVERY candidate, including a
|
|
145
|
+
* default-set member, and no token can override it. It also outranks
|
|
146
|
+
* `setting=skip`: both refuse, but only one of them is the operator's own decision,
|
|
147
|
+
* and the REASON is what tells them so. Only then: `skip`, then the DEFAULT set
|
|
148
|
+
* runs unprompted, a recorded `"granted"` admits, and finally a consent token
|
|
149
|
+
* admits the candidate it was issued for.
|
|
103
150
|
*/
|
|
104
151
|
export function admitSpawn(candidate, setting, consentToken, recordedDecision) {
|
|
152
|
+
// A recorded refusal is terminal and is read BEFORE anything else — including the
|
|
153
|
+
// settings channel, which would otherwise mask the operator's own decision behind
|
|
154
|
+
// a reason that names a config value instead of their decline.
|
|
155
|
+
if (recordedDecision === "declined")
|
|
156
|
+
return ANALYZER_DENIAL_REASONS.consent_declined;
|
|
105
157
|
if (setting === "skip")
|
|
106
|
-
return
|
|
158
|
+
return ANALYZER_DENIAL_REASONS.setting_skip;
|
|
107
159
|
if (candidate.defaultRun)
|
|
108
160
|
return undefined;
|
|
109
|
-
// Admission: default set ∨ recorded "granted" ∨ per-run token
|
|
110
161
|
if (recordedDecision === "granted")
|
|
111
162
|
return undefined;
|
|
112
|
-
|
|
163
|
+
const tokenVerdict = consentTokenAdmits(consentToken, candidate.id);
|
|
164
|
+
if (tokenVerdict === "admit")
|
|
113
165
|
return undefined;
|
|
114
|
-
|
|
166
|
+
if (tokenVerdict === "out_of_scope")
|
|
167
|
+
return ANALYZER_DENIAL_REASONS.consent_token_scope;
|
|
168
|
+
return ANALYZER_DENIAL_REASONS.consent_not_decided;
|
|
115
169
|
}
|
|
116
170
|
/**
|
|
117
171
|
* The run-safety gate, written once: capability-probe the runner, then (if the
|
|
@@ -260,9 +314,11 @@ export function runExternalAnalyzer(candidate, root, options = {}) {
|
|
|
260
314
|
/* best-effort */
|
|
261
315
|
}
|
|
262
316
|
}
|
|
263
|
-
|
|
317
|
+
const stderrText = typeof result.stderr === "string" ? result.stderr : "";
|
|
318
|
+
const stderrSnippet = stderrText.trim().length > 0 ? { stderr_snippet: stderrText.slice(0, 500) } : {};
|
|
319
|
+
let parsed;
|
|
264
320
|
try {
|
|
265
|
-
|
|
321
|
+
parsed = readParseOutcome(candidate.parse(parseInput));
|
|
266
322
|
}
|
|
267
323
|
catch (error) {
|
|
268
324
|
return {
|
|
@@ -275,13 +331,21 @@ export function runExternalAnalyzer(candidate, root, options = {}) {
|
|
|
275
331
|
exit_code: result.status,
|
|
276
332
|
error: error instanceof Error ? error.message : String(error),
|
|
277
333
|
output_snippet: result.stdout.slice(0, 200),
|
|
334
|
+
...stderrSnippet,
|
|
278
335
|
duration_ms: result.duration_ms,
|
|
279
336
|
},
|
|
280
337
|
};
|
|
281
338
|
}
|
|
282
|
-
|
|
283
|
-
//
|
|
339
|
+
const items = parsed.items;
|
|
340
|
+
// readSource: content-anchored lead provenance (item C). Paths are normalized to
|
|
341
|
+
// repo-relative FIRST (an absolute-path emitter would otherwise make `join(root,
|
|
342
|
+
// path)` name nothing, silently dropping provenance); a read that still fails is
|
|
343
|
+
// COUNTED onto the status, so a broken read seam is distinguishable from an item
|
|
344
|
+
// that legitimately carries no anchor.
|
|
345
|
+
let sourceReadFailures = 0;
|
|
346
|
+
let normalizerDroppedItems = 0;
|
|
284
347
|
const normalized = normalizeGenericExternalResults(candidate.id, items, {
|
|
348
|
+
repoRoot: root,
|
|
285
349
|
readSource: (path) => {
|
|
286
350
|
try {
|
|
287
351
|
return readFileSync(join(root, path), "utf8");
|
|
@@ -290,10 +354,77 @@ export function runExternalAnalyzer(candidate, root, options = {}) {
|
|
|
290
354
|
return undefined;
|
|
291
355
|
}
|
|
292
356
|
},
|
|
357
|
+
onDiagnostics: (diagnostics) => {
|
|
358
|
+
sourceReadFailures = diagnostics.source_read_failures;
|
|
359
|
+
normalizerDroppedItems = diagnostics.dropped_items;
|
|
360
|
+
},
|
|
293
361
|
});
|
|
294
362
|
const edges = normalizeGenericExternalEdges(items);
|
|
295
363
|
if (edges.length > 0)
|
|
296
364
|
normalized.graph_edges = edges;
|
|
365
|
+
// Rows the PARSER could not use plus items the NORMALIZER discarded (missing path
|
|
366
|
+
// or summary) are the same question to a consumer — "how much did this run fail to
|
|
367
|
+
// report?" — so they land on one field. Counting only the parser's half left a run
|
|
368
|
+
// whose every item was dropped at normalization reading as a clean scan.
|
|
369
|
+
const droppedRows = (parsed.dropped_rows ?? 0) + normalizerDroppedItems;
|
|
370
|
+
const degradationFields = {
|
|
371
|
+
exit_code: result.status,
|
|
372
|
+
...(droppedRows > 0 ? { dropped_rows: droppedRows } : {}),
|
|
373
|
+
...(sourceReadFailures > 0 ? { source_read_failures: sourceReadFailures } : {}),
|
|
374
|
+
...stderrSnippet,
|
|
375
|
+
duration_ms: result.duration_ms,
|
|
376
|
+
};
|
|
377
|
+
// AFFIRMATION, never a success-shaped empty. Zero items is only "success" when the
|
|
378
|
+
// run itself was clean: the tool exited 0, said nothing on stderr it did not also
|
|
379
|
+
// say on stdout, parsed, and dropped nothing. Every other zero-item outcome names
|
|
380
|
+
// its cause — the exit code and stderr are in hand right here, which is exactly
|
|
381
|
+
// why leaving them unconsulted made a broken analyzer read as a clean repo.
|
|
382
|
+
if (normalized.results.length === 0) {
|
|
383
|
+
// A NULL exit status means the child never exited on its own — it was killed by a
|
|
384
|
+
// signal (SIGKILL/OOM). `RunTrackedResult` carries no signal field, so null is the
|
|
385
|
+
// only trace of it, and it is emphatically not "exited cleanly". Treating it as
|
|
386
|
+
// clean also made the classification OS-divergent: win32 surfaces the same kill as
|
|
387
|
+
// a non-zero status, so the identical event would have been failed there and
|
|
388
|
+
// success on POSIX.
|
|
389
|
+
const exitMissing = result.status === null || result.status === undefined;
|
|
390
|
+
const exitedNonZero = exitMissing || result.status !== 0;
|
|
391
|
+
const stderrOnly = !exitedNonZero && stderrText.trim().length > 0 && parseInput.trim().length === 0;
|
|
392
|
+
if (exitedNonZero || stderrOnly) {
|
|
393
|
+
return {
|
|
394
|
+
results: emptyResults(candidate.id),
|
|
395
|
+
status: {
|
|
396
|
+
tool: candidate.id,
|
|
397
|
+
command,
|
|
398
|
+
resolved: true,
|
|
399
|
+
status: "failed",
|
|
400
|
+
error: exitMissing
|
|
401
|
+
? "analyzer terminated without an exit status (killed by a signal) and produced no parsable findings"
|
|
402
|
+
: exitedNonZero
|
|
403
|
+
? `analyzer exited ${result.status} with no parsable findings`
|
|
404
|
+
: "analyzer produced no output other than stderr",
|
|
405
|
+
output_snippet: result.stdout.slice(0, 200),
|
|
406
|
+
...degradationFields,
|
|
407
|
+
},
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
if (parsed.parse_failed || droppedRows > 0) {
|
|
411
|
+
return {
|
|
412
|
+
results: emptyResults(candidate.id),
|
|
413
|
+
status: {
|
|
414
|
+
tool: candidate.id,
|
|
415
|
+
command,
|
|
416
|
+
resolved: true,
|
|
417
|
+
status: "parse_error",
|
|
418
|
+
error: parsed.note ??
|
|
419
|
+
(parsed.parse_failed
|
|
420
|
+
? "analyzer output could not be parsed"
|
|
421
|
+
: `analyzer output parsed with ${droppedRows} unusable row(s)`),
|
|
422
|
+
output_snippet: parseInput.slice(0, 200),
|
|
423
|
+
...degradationFields,
|
|
424
|
+
},
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
}
|
|
297
428
|
return {
|
|
298
429
|
results: normalized,
|
|
299
430
|
status: {
|
|
@@ -301,8 +432,8 @@ export function runExternalAnalyzer(candidate, root, options = {}) {
|
|
|
301
432
|
command,
|
|
302
433
|
resolved: true,
|
|
303
434
|
status: normalized.results.length > 0 ? "findings" : "success",
|
|
304
|
-
|
|
305
|
-
|
|
435
|
+
...(parsed.note !== undefined ? { error: parsed.note } : {}),
|
|
436
|
+
...degradationFields,
|
|
306
437
|
},
|
|
307
438
|
};
|
|
308
439
|
}
|
|
@@ -361,10 +492,13 @@ export async function resolveBinaryCandidates(candidates, root, options = {}) {
|
|
|
361
492
|
resolvedBinaries[candidate.id] = resolution.command;
|
|
362
493
|
}
|
|
363
494
|
else {
|
|
495
|
+
// A supply-chain event gets its OWN status member: "the release asset did not
|
|
496
|
+
// match the pinned checksums" must never be flattened into the same record as
|
|
497
|
+
// "this machine is offline", which is all a shared `not_resolved` could say.
|
|
364
498
|
unresolvedStatuses.push({
|
|
365
499
|
tool: candidate.id,
|
|
366
500
|
resolved: false,
|
|
367
|
-
status: "not_resolved",
|
|
501
|
+
status: resolution.reason === "checksum_mismatch" ? "checksum_mismatch" : "not_resolved",
|
|
368
502
|
error: resolution.note ?? "binary unavailable",
|
|
369
503
|
});
|
|
370
504
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acquisitionEngine.js","sourceRoot":"","sources":["../../../src/shared/analyzers/acquisitionEngine.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"acquisitionEngine.js","sourceRoot":"","sources":["../../../src/shared/analyzers/acquisitionEngine.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,7 +15,24 @@ import { type RunTrackedResult } from "../tooling/exec.js";
|
|
|
15
15
|
* is SHA256-verified against the official release checksums BEFORE it is extracted
|
|
16
16
|
* or executed; the fetcher is injected so the engine is testable without network
|
|
17
17
|
* and an absent network degrades cleanly. A checksum mismatch is fatal-to-this-tool
|
|
18
|
-
* (returns `unavailable`), never executed.
|
|
18
|
+
* (returns `unavailable` with reason `checksum_mismatch`), never executed.
|
|
19
|
+
*
|
|
20
|
+
* The cache branch is held to the SAME bar as the download branch, on EVERY
|
|
21
|
+
* resolution, in two layers that only work together:
|
|
22
|
+
* - LOCATION. The default cache root is per-user (`<homedir>/.audit-tools/bincache`,
|
|
23
|
+
* created 0o700 where modes are honoured), never the shared temp dir. The path is
|
|
24
|
+
* fully derivable from public pinned constants, so "a file exists there" is only
|
|
25
|
+
* meaningful when the directory is not writable by other local processes.
|
|
26
|
+
* - INTEGRITY. Each successful download records the executable's digest in a cache
|
|
27
|
+
* manifest beside it, and a cache hit is only a hit when the bytes still hash to
|
|
28
|
+
* that recorded digest. Anything else — no manifest, an unreadable manifest, a
|
|
29
|
+
* digest mismatch, or a version dir left behind by a failed extraction — is PURGED
|
|
30
|
+
* and re-acquired rather than executed.
|
|
31
|
+
*
|
|
32
|
+
* The manifest alone is NOT provenance: anyone who can write the cache dir can write a
|
|
33
|
+
* self-consistent binary+manifest pair. It detects drift and partial writes; the
|
|
34
|
+
* location layer is what makes writing the pair privileged in the first place. A
|
|
35
|
+
* caller passing its own `cacheDir` owns that directory's permissions.
|
|
19
36
|
*/
|
|
20
37
|
/** Injected network fetch: returns the URL's bytes, or `null` when unavailable. */
|
|
21
38
|
export interface BinaryFetcher {
|
|
@@ -57,15 +74,23 @@ export interface BinarySpec {
|
|
|
57
74
|
export interface BinaryResolveOptions {
|
|
58
75
|
fetch?: BinaryFetcher;
|
|
59
76
|
run?: BinaryCommandRunner;
|
|
60
|
-
/** Root cache dir for downloaded binaries; default `<
|
|
77
|
+
/** Root cache dir for downloaded binaries; default `<homedir>/.audit-tools/bincache`. */
|
|
61
78
|
cacheDir?: string;
|
|
62
79
|
platform?: NodeJS.Platform;
|
|
63
80
|
arch?: string;
|
|
64
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* WHY a binary could not be resolved, as a machine-readable member rather than a
|
|
84
|
+
* free-text note. `checksum_mismatch` is a supply-chain event and must never be
|
|
85
|
+
* indistinguishable from `offline` in the persisted record.
|
|
86
|
+
*/
|
|
87
|
+
export type BinaryUnavailableReason = "offline" | "no_asset_for_platform" | "download_failed" | "download_empty" | "no_checksum_for_asset" | "checksum_mismatch" | "extract_failed" | "not_found_in_archive" | "write_failed";
|
|
65
88
|
export interface BinaryResolution {
|
|
66
89
|
status: "path" | "cached" | "downloaded" | "unavailable";
|
|
67
90
|
/** Resolved executable (PATH name or absolute cached path); null when unavailable. */
|
|
68
91
|
command: string | null;
|
|
92
|
+
/** Discriminated cause when `status === "unavailable"`. */
|
|
93
|
+
reason?: BinaryUnavailableReason;
|
|
69
94
|
note?: string;
|
|
70
95
|
}
|
|
71
96
|
/** Parse a `<sha256>␠␠<asset>` checksums file for one asset's expected digest. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binaryAcquisition.d.ts","sourceRoot":"","sources":["../../../src/shared/analyzers/binaryAcquisition.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"binaryAcquisition.d.ts","sourceRoot":"","sources":["../../../src/shared/analyzers/binaryAcquisition.ts"],"names":[],"mappings":"AAcA,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,mFAAmF;AACnF,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;CAC3C;AAED,0FAA0F;AAC1F,MAAM,WAAW,mBAAmB;IAClC,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAAC;CACjD;AAED,0EAA0E;AAC1E,MAAM,WAAW,UAAU;IACzB,sEAAsE;IACtE,UAAU,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACjE;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,GAAG,CAAC,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IACzD,gFAAgF;IAChF,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9C;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,GAAG,CAAC,EAAE,mBAAmB,CAAC;IAC1B,yFAAyF;IACzF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,GAC/B,SAAS,GACT,uBAAuB,GACvB,iBAAiB,GACjB,gBAAgB,GAChB,uBAAuB,GACvB,mBAAmB,GACnB,gBAAgB,GAChB,sBAAsB,GACtB,cAAc,CAAC;AAEnB,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,YAAY,GAAG,aAAa,CAAC;IACzD,sFAAsF;IACtF,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA+ID,kFAAkF;AAClF,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAMf;AAMD;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,gBAAgB,CAAC,CAiJ3B"}
|
|
@@ -1,14 +1,122 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { chmodSync, existsSync, mkdirSync, readdirSync, rmSync, statSync, writeFileSync, } from "node:fs";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
import {
|
|
2
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync, } from "node:fs";
|
|
3
|
+
import { isAbsolute, join, relative } from "node:path";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import { AUDIT_TOOLS_DIRNAME } from "../io/auditToolsPaths.js";
|
|
5
6
|
import { runTracked } from "../tooling/exec.js";
|
|
7
|
+
/**
|
|
8
|
+
* Per-USER cache root, deliberately NOT the system temp dir. Defaults to
|
|
9
|
+
* `~/.audit-tools/bincache`; `AUDIT_TOOLS_BINARY_CACHE` overrides it so a run can be
|
|
10
|
+
* pinned to an isolated cache — the same override shape as
|
|
11
|
+
* {@link analyzerCacheRoot}'s `AUDIT_TOOLS_ANALYZER_CACHE`, and what lets a test
|
|
12
|
+
* exercise the DEFAULT path without ever writing to the real home directory.
|
|
13
|
+
*
|
|
14
|
+
* The digest manifest beside a cached binary proves the bytes match what the manifest
|
|
15
|
+
* says — but an attacker who can write the cache dir writes BOTH, so a self-consistent
|
|
16
|
+
* pair inside a world-writable location proves nothing. The manifest only has meaning
|
|
17
|
+
* when the directory it lives in is not attacker-writable, which is what moving the
|
|
18
|
+
* default root under the user's home buys. `cacheDir` remains overridable per call for
|
|
19
|
+
* a caller that has its own private location.
|
|
20
|
+
*
|
|
21
|
+
* Consequence, deliberate: caches warmed under the old `<tmpdir>/audit-tools-bincache`
|
|
22
|
+
* are simply never consulted again — the first resolution under the new root
|
|
23
|
+
* re-downloads, or degrades to `unavailable` offline.
|
|
24
|
+
*/
|
|
6
25
|
function defaultCacheDir() {
|
|
7
|
-
|
|
26
|
+
const override = process.env.AUDIT_TOOLS_BINARY_CACHE;
|
|
27
|
+
if (override && override.trim().length > 0)
|
|
28
|
+
return override;
|
|
29
|
+
return join(homedir(), AUDIT_TOOLS_DIRNAME, "bincache");
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create the cache root restricted to its owner where the platform honours modes.
|
|
33
|
+
* On win32 the mode is ignored (ACLs govern), and the per-user home root is the
|
|
34
|
+
* protection there.
|
|
35
|
+
*
|
|
36
|
+
* ⚠ The mode applies AT CREATION ONLY. An existing directory keeps whatever mode it
|
|
37
|
+
* already has — `mkdirSync` does not chmod one it did not create — so a root that was
|
|
38
|
+
* created loosely by something else is not repaired here.
|
|
39
|
+
*/
|
|
40
|
+
function ensureCacheRoot(cacheDir) {
|
|
41
|
+
try {
|
|
42
|
+
mkdirSync(cacheDir, { recursive: true, mode: 0o700 });
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
/* a later mkdir of the version dir surfaces any real failure */
|
|
46
|
+
}
|
|
8
47
|
}
|
|
9
48
|
function exeName(binaryName, platform) {
|
|
10
49
|
return platform === "win32" ? `${binaryName}.exe` : binaryName;
|
|
11
50
|
}
|
|
51
|
+
/** `unavailable` with its cause carried in BOTH forms — machine member + human note. */
|
|
52
|
+
function unavailable(reason, note) {
|
|
53
|
+
return { status: "unavailable", command: null, reason, note };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Cache manifest filename. Written beside the cached executable at download time and
|
|
57
|
+
* the ONLY evidence that these bytes came from a checksum-verified acquisition.
|
|
58
|
+
*/
|
|
59
|
+
const CACHE_MANIFEST_FILENAME = ".audit-tools-binary.json";
|
|
60
|
+
/** Remove a cache version dir wholesale; best-effort, never throws. */
|
|
61
|
+
function purgeVersionDir(versionDir) {
|
|
62
|
+
try {
|
|
63
|
+
rmSync(versionDir, { recursive: true, force: true });
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
/* best-effort — a later resolution re-verifies regardless */
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function writeCacheManifest(versionDir, spec, executablePath) {
|
|
70
|
+
try {
|
|
71
|
+
const manifest = {
|
|
72
|
+
binaryName: spec.binaryName,
|
|
73
|
+
version: spec.version,
|
|
74
|
+
executable_relative_path: relative(versionDir, executablePath).replace(/\\/g, "/"),
|
|
75
|
+
executable_sha256: sha256(readFileSync(executablePath)),
|
|
76
|
+
};
|
|
77
|
+
writeFileSync(join(versionDir, CACHE_MANIFEST_FILENAME), `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
/* An unwritable manifest simply means the next resolution re-downloads. */
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The cached executable's path — but ONLY when its bytes still hash to the digest
|
|
85
|
+
* recorded when it was acquired. A missing, unreadable, or mismatched manifest, an
|
|
86
|
+
* escaping relative path, or drifted bytes all return null and the caller purges:
|
|
87
|
+
* filename existence is never sufficient to execute.
|
|
88
|
+
*/
|
|
89
|
+
function verifiedCachedExecutable(versionDir, spec) {
|
|
90
|
+
let manifest;
|
|
91
|
+
try {
|
|
92
|
+
manifest = JSON.parse(readFileSync(join(versionDir, CACHE_MANIFEST_FILENAME), "utf8"));
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
if (!manifest ||
|
|
98
|
+
manifest.binaryName !== spec.binaryName ||
|
|
99
|
+
manifest.version !== spec.version ||
|
|
100
|
+
typeof manifest.executable_relative_path !== "string" ||
|
|
101
|
+
manifest.executable_relative_path.length === 0 ||
|
|
102
|
+
typeof manifest.executable_sha256 !== "string" ||
|
|
103
|
+
manifest.executable_sha256.length !== 64) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
const executablePath = join(versionDir, manifest.executable_relative_path);
|
|
107
|
+
const containment = relative(versionDir, executablePath);
|
|
108
|
+
if (containment.startsWith("..") || isAbsolute(containment))
|
|
109
|
+
return null;
|
|
110
|
+
try {
|
|
111
|
+
if (sha256(readFileSync(executablePath)) !== manifest.executable_sha256.toLowerCase()) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
return executablePath;
|
|
119
|
+
}
|
|
12
120
|
/** Parse a `<sha256>␠␠<asset>` checksums file for one asset's expected digest. */
|
|
13
121
|
export function expectedSha256For(checksumsText, assetName) {
|
|
14
122
|
for (const line of checksumsText.split(/\r?\n/)) {
|
|
@@ -31,29 +139,34 @@ export async function resolveBinary(spec, options = {}) {
|
|
|
31
139
|
const arch = options.arch ?? process.arch;
|
|
32
140
|
const run = options.run ?? ((argv, cwd) => runTracked(argv, { cwd }));
|
|
33
141
|
const cacheDir = options.cacheDir ?? defaultCacheDir();
|
|
34
|
-
// 1. PATH — already installed.
|
|
142
|
+
// 1. PATH — already installed. Nothing below this point runs, so a tool the machine
|
|
143
|
+
// already has must not cause a cache directory to be created as a side effect.
|
|
35
144
|
const probe = run(spec.versionProbeArgs, process.cwd());
|
|
36
145
|
if (!probe.error && probe.status === 0) {
|
|
37
146
|
return { status: "path", command: spec.binaryName };
|
|
38
147
|
}
|
|
39
|
-
// 2. cache — a previously-downloaded pinned binary
|
|
148
|
+
// 2. cache — a previously-downloaded pinned binary, RE-VERIFIED on every
|
|
149
|
+
// resolution. The cache path is derivable from public pinned constants, so a
|
|
150
|
+
// file at the expected name is a claim, not a proof: it is executed only when its
|
|
151
|
+
// bytes still match the digest recorded at acquisition. Anything else — including
|
|
152
|
+
// a version dir a failed extraction left behind — is purged and re-acquired.
|
|
40
153
|
const versionDir = join(cacheDir, `${spec.binaryName}-${spec.version}`);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
154
|
+
if (existsSync(versionDir)) {
|
|
155
|
+
const verified = verifiedCachedExecutable(versionDir, spec);
|
|
156
|
+
if (verified)
|
|
157
|
+
return { status: "cached", command: verified };
|
|
158
|
+
// Unverifiable bytes, or a dir a failed extraction left behind: purge so nothing
|
|
159
|
+
// half-written or pre-planted can become a later "cache hit".
|
|
160
|
+
purgeVersionDir(versionDir);
|
|
44
161
|
}
|
|
45
162
|
// 3. download — pinned release asset, SHA256-verified, then extracted.
|
|
46
163
|
const fetch = options.fetch;
|
|
47
164
|
if (!fetch) {
|
|
48
|
-
return
|
|
165
|
+
return unavailable("offline", "no fetcher configured (offline)");
|
|
49
166
|
}
|
|
50
167
|
const assetName = spec.assetFor(platform, arch);
|
|
51
168
|
if (!assetName) {
|
|
52
|
-
return {
|
|
53
|
-
status: "unavailable",
|
|
54
|
-
command: null,
|
|
55
|
-
note: `no release asset for ${platform}/${arch}`,
|
|
56
|
-
};
|
|
169
|
+
return unavailable("no_asset_for_platform", `no release asset for ${platform}/${arch}`);
|
|
57
170
|
}
|
|
58
171
|
let assetBytes;
|
|
59
172
|
let checksumsBytes;
|
|
@@ -65,27 +178,25 @@ export async function resolveBinary(spec, options = {}) {
|
|
|
65
178
|
assetBytes = await fetch(spec.releaseUrlForAsset(assetName));
|
|
66
179
|
}
|
|
67
180
|
catch (error) {
|
|
68
|
-
return {
|
|
69
|
-
status: "unavailable",
|
|
70
|
-
command: null,
|
|
71
|
-
note: `download failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
72
|
-
};
|
|
181
|
+
return unavailable("download_failed", `download failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
73
182
|
}
|
|
74
183
|
if (!checksumsBytes || !assetBytes) {
|
|
75
|
-
return
|
|
184
|
+
return unavailable("download_empty", "download returned no bytes");
|
|
76
185
|
}
|
|
77
186
|
const expected = expectedSha256For(Buffer.from(checksumsBytes).toString("utf8"), assetName);
|
|
78
187
|
if (!expected) {
|
|
79
|
-
return
|
|
188
|
+
return unavailable("no_checksum_for_asset", `no checksum for ${assetName}`);
|
|
80
189
|
}
|
|
81
190
|
const actual = sha256(assetBytes);
|
|
82
191
|
if (actual !== expected) {
|
|
83
|
-
return {
|
|
84
|
-
status: "unavailable",
|
|
85
|
-
command: null,
|
|
86
|
-
note: `checksum mismatch for ${assetName} (expected ${expected}, got ${actual})`,
|
|
87
|
-
};
|
|
192
|
+
return unavailable("checksum_mismatch", `checksum mismatch for ${assetName} (expected ${expected}, got ${actual})`);
|
|
88
193
|
}
|
|
194
|
+
// Only here — past the PATH probe, past a cache miss, past verification — is
|
|
195
|
+
// anything about to be WRITTEN. Creating the root any earlier would grow an empty
|
|
196
|
+
// cache directory on every resolution that never caches anything: a tool already on
|
|
197
|
+
// PATH, an offline degrade, an unsupported platform. Read paths only ever ask
|
|
198
|
+
// whether the directory exists.
|
|
199
|
+
ensureCacheRoot(cacheDir);
|
|
89
200
|
// Non-archived asset (e.g. osv-scanner): the verified bytes ARE the
|
|
90
201
|
// executable — write directly to the cached path, no `tar` involved.
|
|
91
202
|
if (spec.archived === false) {
|
|
@@ -101,14 +212,12 @@ export async function resolveBinary(spec, options = {}) {
|
|
|
101
212
|
/* best-effort */
|
|
102
213
|
}
|
|
103
214
|
}
|
|
215
|
+
writeCacheManifest(versionDir, spec, resolved);
|
|
104
216
|
return { status: "downloaded", command: resolved };
|
|
105
217
|
}
|
|
106
218
|
catch (error) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
command: null,
|
|
110
|
-
note: `write error: ${error instanceof Error ? error.message : String(error)}`,
|
|
111
|
-
};
|
|
219
|
+
purgeVersionDir(versionDir);
|
|
220
|
+
return unavailable("write_failed", `write error: ${error instanceof Error ? error.message : String(error)}`);
|
|
112
221
|
}
|
|
113
222
|
}
|
|
114
223
|
// Verified — write the archive and extract it with the system `tar` (bsdtar
|
|
@@ -120,24 +229,20 @@ export async function resolveBinary(spec, options = {}) {
|
|
|
120
229
|
const extract = run(["tar", "-xf", archivePath, "-C", versionDir], versionDir);
|
|
121
230
|
rmSync(archivePath, { force: true });
|
|
122
231
|
if (extract.error || extract.status !== 0) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
note: `extract failed: ${extract.error?.message ?? `tar exit ${extract.status}`}`,
|
|
127
|
-
};
|
|
232
|
+
// Whatever tar managed to write before failing must NOT survive as a cache hit.
|
|
233
|
+
purgeVersionDir(versionDir);
|
|
234
|
+
return unavailable("extract_failed", `extract failed: ${extract.error?.message ?? `tar exit ${extract.status}`}`);
|
|
128
235
|
}
|
|
129
236
|
}
|
|
130
237
|
catch (error) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
command: null,
|
|
134
|
-
note: `extract error: ${error instanceof Error ? error.message : String(error)}`,
|
|
135
|
-
};
|
|
238
|
+
purgeVersionDir(versionDir);
|
|
239
|
+
return unavailable("extract_failed", `extract error: ${error instanceof Error ? error.message : String(error)}`);
|
|
136
240
|
}
|
|
137
241
|
// Locate the executable (archives may nest it); chmod +x on POSIX.
|
|
138
242
|
const resolved = findExecutable(versionDir, exeName(spec.binaryName, platform));
|
|
139
243
|
if (!resolved) {
|
|
140
|
-
|
|
244
|
+
purgeVersionDir(versionDir);
|
|
245
|
+
return unavailable("not_found_in_archive", "binary not found in archive");
|
|
141
246
|
}
|
|
142
247
|
if (platform !== "win32") {
|
|
143
248
|
try {
|
|
@@ -147,6 +252,7 @@ export async function resolveBinary(spec, options = {}) {
|
|
|
147
252
|
/* best-effort */
|
|
148
253
|
}
|
|
149
254
|
}
|
|
255
|
+
writeCacheManifest(versionDir, spec, resolved);
|
|
150
256
|
return { status: "downloaded", command: resolved };
|
|
151
257
|
}
|
|
152
258
|
/** Shallow-then-recursive search for `name` under `dir`. */
|