@clear-capabilities/agentic-security-scanner 0.172.0 → 0.173.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/CHANGELOG.md +29 -0
- package/bin/agentic-security.js +37 -0
- package/dist/119.index.js +197 -0
- package/dist/128.index.js +129 -0
- package/dist/1293.index.js +5689 -0
- package/dist/1336.index.js +101 -101
- package/dist/1351.index.js +133 -0
- package/dist/1387.index.js +271 -0
- package/dist/1437.index.js +23 -0
- package/dist/1445.index.js +110 -0
- package/dist/1505.index.js +151 -0
- package/dist/1557.index.js +293 -0
- package/dist/1621.index.js +311 -0
- package/dist/1751.index.js +160 -0
- package/dist/1765.index.js +727 -0
- package/dist/1861.index.js +690 -0
- package/dist/1898.index.js +116 -0
- package/dist/1906.index.js +433 -0
- package/dist/1920.index.js +1 -291
- package/dist/208.index.js +1631 -0
- package/dist/2199.index.js +0 -239
- package/dist/2223.index.js +159 -0
- package/dist/2530.index.js +152 -0
- package/dist/2565.index.js +116 -0
- package/dist/2574.index.js +127 -0
- package/dist/2620.index.js +345 -0
- package/dist/2773.index.js +98 -0
- package/dist/2775.index.js +32 -0
- package/dist/2966.index.js +171 -0
- package/dist/2972.index.js +87 -0
- package/dist/2991.index.js +131 -0
- package/dist/3063.index.js +833 -0
- package/dist/3075.index.js +227 -0
- package/dist/3121.index.js +297 -0
- package/dist/3314.index.js +263 -0
- package/dist/3480.index.js +1822 -0
- package/dist/3481.index.js +24 -0
- package/dist/3506.index.js +268 -0
- package/dist/3533.index.js +591 -0
- package/dist/3653.index.js +450 -0
- package/dist/3822.index.js +131 -0
- package/dist/3868.index.js +292 -0
- package/dist/3917.index.js +152 -0
- package/dist/3918.index.js +192 -0
- package/dist/4090.index.js +288 -0
- package/dist/4121.index.js +1190 -0
- package/dist/4142.index.js +0 -239
- package/dist/4336.index.js +436 -0
- package/dist/4387.index.js +532 -0
- package/dist/4413.index.js +302 -0
- package/dist/4476.index.js +4510 -0
- package/dist/4491.index.js +133 -0
- package/dist/4538.index.js +185 -0
- package/dist/4684.index.js +319 -0
- package/dist/4740.index.js +165 -0
- package/dist/4780.index.js +209 -0
- package/dist/4802.index.js +225 -0
- package/dist/4812.index.js +379 -0
- package/dist/4835.index.js +126 -0
- package/dist/494.index.js +226 -0
- package/dist/4991.index.js +549 -0
- package/dist/5199.index.js +305 -0
- package/dist/5216.index.js +109 -0
- package/dist/5439.index.js +301 -0
- package/dist/5443.index.js +97 -0
- package/dist/5496.index.js +377 -0
- package/dist/550.index.js +2 -1
- package/dist/5801.index.js +588 -0
- package/dist/5858.index.js +223 -0
- package/dist/5933.index.js +143 -0
- package/dist/601.index.js +23 -0
- package/dist/6173.index.js +273 -0
- package/dist/6291.index.js +1871 -0
- package/dist/6312.index.js +666 -0
- package/dist/634.index.js +16182 -0
- package/dist/644.index.js +87 -0
- package/dist/6508.index.js +283 -0
- package/dist/6560.index.js +645 -0
- package/dist/6576.index.js +422 -0
- package/dist/6579.index.js +271 -0
- package/dist/6745.index.js +305 -0
- package/dist/6818.index.js +21642 -0
- package/dist/6972.index.js +167 -0
- package/dist/6995.index.js +163 -0
- package/dist/7249.index.js +191 -0
- package/dist/7372.index.js +1197 -0
- package/dist/7405.index.js +23 -6
- package/dist/7546.index.js +541 -0
- package/dist/76.index.js +448 -0
- package/dist/7879.index.js +163 -0
- package/dist/8025.index.js +130 -0
- package/dist/8054.index.js +248 -0
- package/dist/8097.index.js +201 -0
- package/dist/8126.index.js +191 -0
- package/dist/8178.index.js +78 -0
- package/dist/818.index.js +212 -0
- package/dist/8382.index.js +93 -0
- package/dist/8408.index.js +261 -0
- package/dist/8540.index.js +174 -0
- package/dist/8635.index.js +802 -0
- package/dist/8688.index.js +410 -0
- package/dist/8699.index.js +779 -0
- package/dist/8891.index.js +457 -0
- package/dist/8916.index.js +885 -0
- package/dist/9146.index.js +170 -0
- package/dist/9168.index.js +841 -0
- package/dist/9292.index.js +369 -0
- package/dist/9382.index.js +338 -48
- package/dist/9422.index.js +866 -0
- package/dist/9440.index.js +453 -0
- package/dist/9479.index.js +152 -0
- package/dist/9481.index.js +220 -0
- package/dist/9539.index.js +100 -0
- package/dist/9547.index.js +103 -0
- package/dist/9560.index.js +41 -61
- package/dist/9692.index.js +90 -0
- package/dist/9800.index.js +213 -1
- package/dist/9899.index.js +138 -0
- package/dist/9981.index.js +206 -0
- package/dist/999.index.js +117 -0
- package/dist/agentic-security.mjs +28 -28
- package/dist/agentic-security.mjs.sha256 +1 -1
- package/package.json +31 -6
- package/src/context-intelligence/CLAUDE.md +4 -0
- package/src/context-intelligence/adapters/haskell-hie.js +28 -1
- package/src/context-intelligence/candidates.js +2 -1
- package/src/context-intelligence/canonical.js +25 -0
- package/src/context-intelligence/capabilities.js +2 -1
- package/src/context-intelligence/cli.js +16 -10
- package/src/context-intelligence/config.js +4 -1
- package/src/context-intelligence/controls.js +108 -10
- package/src/context-intelligence/counterexample.js +200 -0
- package/src/context-intelligence/cross-route.js +111 -0
- package/src/context-intelligence/entrypoints.js +2 -2
- package/src/context-intelligence/evaluation/index.js +11 -4
- package/src/context-intelligence/evaluation/scripted-reader.js +12 -2
- package/src/context-intelligence/findings.js +166 -0
- package/src/context-intelligence/invariants.js +197 -0
- package/src/context-intelligence/queue.js +6 -1
- package/src/context-intelligence/reachability.js +10 -4
- package/src/context-intelligence/review.js +129 -16
- package/src/dataflow/access-paths.js +11 -0
- package/src/dataflow/analysis-limits.js +66 -0
- package/src/dataflow/engine.js +272 -20
- package/src/dataflow/service-edges.js +174 -0
- package/src/dataflow/summaries.js +7 -1
- package/src/discovery/judge.js +2 -1
- package/src/engine.js +82 -14
- package/src/fix/apply-fix-service.js +55 -8
- package/src/fix/batch-journal.js +84 -0
- package/src/fix/exploit-replay.js +51 -0
- package/src/fix/footprint.js +65 -0
- package/src/fix/patch-policy.js +49 -0
- package/src/fix/secret-persistence.js +39 -0
- package/src/fix/test-commands.js +84 -0
- package/src/fix/verification-adapters.js +97 -0
- package/src/fix/verification-record.js +243 -0
- package/src/fix/verify-patch.js +89 -0
- package/src/ir/CLAUDE.md +5 -0
- package/src/ir/callgraph.js +23 -1
- package/src/ir/module-resolver.js +315 -0
- package/src/ir/parser-js.js +21 -2
- package/src/ir/semantic-graph.js +245 -0
- package/src/lineage/build-attested-correlation.js +63 -0
- package/src/lineage/deployment-identity.js +76 -0
- package/src/mcp/tools.js +13 -34
- package/src/pipeline/canonical-output.js +64 -0
- package/src/pipeline/detector-runner.js +7 -0
- package/src/pipeline/scan-health.js +14 -0
- package/src/pipeline/supervised-analyzers.js +125 -0
- package/src/pipeline/supervised-child.js +17 -0
- package/src/pipeline/telemetry.js +79 -0
- package/src/posture/accuracy-scorecard.js +98 -9
- package/src/posture/artifact-registry.js +5 -0
- package/src/posture/assurance/evidence-registry.js +215 -0
- package/src/posture/assurance/release-package-verify.js +135 -0
- package/src/posture/assurance/release-package.js +118 -0
- package/src/posture/assurance/release-verdict.js +94 -0
- package/src/posture/assurance/waiver.js +200 -0
- package/src/posture/compliance-truth.js +100 -0
- package/src/posture/evaluation/scan-child.js +3 -1
- package/src/posture/evaluation/why-missed.js +3 -1
- package/src/posture/exploitability-evidence.js +141 -0
- package/src/posture/fix-verify.js +4 -2
- package/src/posture/fleet/exposure-ranking.js +115 -0
- package/src/posture/fleet/service-chain-graph.js +150 -0
- package/src/posture/graph-reconciliation.js +154 -0
- package/src/posture/provenance/coverage.js +103 -0
- package/src/posture/provenance/git-evidence.js +84 -0
- package/src/posture/provenance/origin-resolver.js +7 -1
- package/src/posture/provenance/predicate-replay.js +14 -4
- package/src/posture/runtime-correlation.js +61 -15
- package/src/posture/runtime-explanation.js +116 -0
- package/src/posture/runtime-trace-ingest.js +194 -0
- package/src/posture/scan-checkpoint.js +38 -10
- package/src/posture/waf-ingest.js +7 -2
- package/src/report/index.js +4 -0
- package/src/report/oscal.js +38 -0
- package/src/report/perspectives.js +150 -0
- package/src/sast/_comment-strip.js +8 -1
- package/src/sast/ruby.js +26 -0
- package/src/util/string-memo.js +38 -0
package/dist/9560.index.js
CHANGED
|
@@ -2931,18 +2931,19 @@ __webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependen
|
|
|
2931
2931
|
/* harmony import */ var _posture_integrity_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(71130);
|
|
2932
2932
|
/* harmony import */ var _posture_state_dir_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(31174);
|
|
2933
2933
|
/* harmony import */ var _posture_cache_economics_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(58752);
|
|
2934
|
-
/* harmony import */ var
|
|
2934
|
+
/* harmony import */ var _redact_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(83468);
|
|
2935
2935
|
/* harmony import */ var _report_index_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(75917);
|
|
2936
2936
|
/* harmony import */ var _posture_verification_projection_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(51864);
|
|
2937
|
-
/* harmony import */ var
|
|
2938
|
-
/* harmony import */ var
|
|
2939
|
-
/* harmony import */ var
|
|
2940
|
-
/* harmony import */ var
|
|
2941
|
-
/* harmony import */ var
|
|
2942
|
-
/* harmony import */ var
|
|
2943
|
-
/* harmony import */ var
|
|
2944
|
-
var
|
|
2945
|
-
|
|
2937
|
+
/* harmony import */ var _fix_verify_patch_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(2046);
|
|
2938
|
+
/* harmony import */ var _lineage_deployment_projection_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(73596);
|
|
2939
|
+
/* harmony import */ var _posture_provenance_schema_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(34594);
|
|
2940
|
+
/* harmony import */ var _dataflow_tools_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(20095);
|
|
2941
|
+
/* harmony import */ var _invariant_tools_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(82407);
|
|
2942
|
+
/* harmony import */ var _portfolio_tools_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(99027);
|
|
2943
|
+
/* harmony import */ var _posture_agents_memory_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(79907);
|
|
2944
|
+
/* harmony import */ var _posture_cve_lookup_js__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(71364);
|
|
2945
|
+
var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_fix_apply_fix_service_js__WEBPACK_IMPORTED_MODULE_5__, _report_index_js__WEBPACK_IMPORTED_MODULE_12__, _fix_verify_patch_js__WEBPACK_IMPORTED_MODULE_14__]);
|
|
2946
|
+
([_fix_apply_fix_service_js__WEBPACK_IMPORTED_MODULE_5__, _report_index_js__WEBPACK_IMPORTED_MODULE_12__, _fix_verify_patch_js__WEBPACK_IMPORTED_MODULE_14__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);
|
|
2946
2947
|
// MCP tool implementations — PRD Feature 2, hardened against the OWASP MCP
|
|
2947
2948
|
// Top 10 (see ./redact.js, ./audit.js, ./server.js for sibling controls).
|
|
2948
2949
|
//
|
|
@@ -2974,6 +2975,7 @@ _report_index_js__WEBPACK_IMPORTED_MODULE_12__ = (__webpack_async_dependencies__
|
|
|
2974
2975
|
// X-206: the one projection of the verification record, shared with the JSON report, the text report and the autopilot response.
|
|
2975
2976
|
|
|
2976
2977
|
|
|
2978
|
+
|
|
2977
2979
|
// Git-origin provenance (Finding Provenance M0/M1). Distinct from
|
|
2978
2980
|
// `finding.provenance` (AI-authorship) and from an SCA entry's `provenance`
|
|
2979
2981
|
// (Sigstore/SLSA attestation) — see report/index.js's import comment.
|
|
@@ -2993,7 +2995,7 @@ async function getRunScan() {
|
|
|
2993
2995
|
}
|
|
2994
2996
|
let _verifyFixCore;
|
|
2995
2997
|
async function getVerifyFixCore() {
|
|
2996
|
-
if (!_verifyFixCore) _verifyFixCore = (await
|
|
2998
|
+
if (!_verifyFixCore) _verifyFixCore = (await Promise.resolve(/* import() */).then(__webpack_require__.bind(__webpack_require__, 27838))).verifyFix;
|
|
2997
2999
|
return _verifyFixCore;
|
|
2998
3000
|
}
|
|
2999
3001
|
|
|
@@ -3388,7 +3390,7 @@ const scan_diff = {
|
|
|
3388
3390
|
// scanning), left as-is rather than silently claimed fixed here.
|
|
3389
3391
|
const findings = (0,_report_index_js__WEBPACK_IMPORTED_MODULE_12__.normalizeFindings)(result.scan)
|
|
3390
3392
|
.filter(f => wantSet.has(String(f.file || '').replace(/\\/g, '/')) && (sevRank[f.severity] ?? 0) >= min)
|
|
3391
|
-
.map(f => (0,
|
|
3393
|
+
.map(f => (0,_redact_js__WEBPACK_IMPORTED_MODULE_20__/* .redactFinding */ .lE)({
|
|
3392
3394
|
id: f.id, severity: f.severity, file: f.file, line: f.line,
|
|
3393
3395
|
title: f.vuln, cwe: f.cwe,
|
|
3394
3396
|
description: f.description, remediation: f.remediation,
|
|
@@ -3451,7 +3453,7 @@ const query_taint = {
|
|
|
3451
3453
|
const hay = [f.description, f.title, f.vuln, f.snippet, JSON.stringify(f.trace || '')].join(' ').toLowerCase();
|
|
3452
3454
|
return hay.includes(srcL) && hay.includes(sinkL);
|
|
3453
3455
|
});
|
|
3454
|
-
const page = all.slice(off, off + lim).map(f => (0,
|
|
3456
|
+
const page = all.slice(off, off + lim).map(f => (0,_redact_js__WEBPACK_IMPORTED_MODULE_20__/* .redactFinding */ .lE)({
|
|
3455
3457
|
id: f.id, severity: f.severity, file: f.file, line: f.line,
|
|
3456
3458
|
title: f.title || f.vuln, description: f.description,
|
|
3457
3459
|
trace: f.trace || null,
|
|
@@ -3489,7 +3491,7 @@ const explain_finding = {
|
|
|
3489
3491
|
if (!scan) throw new Error(`No usable scan state (${status}).`);
|
|
3490
3492
|
const f = _findById(scan, finding_id);
|
|
3491
3493
|
if (!f) throw new Error(`Finding not found: ${finding_id}`);
|
|
3492
|
-
const redacted = (0,
|
|
3494
|
+
const redacted = (0,_redact_js__WEBPACK_IMPORTED_MODULE_20__/* .redactFinding */ .lE)({
|
|
3493
3495
|
id: f.id, severity: f.severity, file: f.file, line: f.line,
|
|
3494
3496
|
title: f.title || f.vuln, cwe: f.cwe,
|
|
3495
3497
|
description: f.description, remediation: f.remediation,
|
|
@@ -3546,7 +3548,7 @@ const explain_finding = {
|
|
|
3546
3548
|
// logins/CODEOWNERS lines) through this MCP surface because this call
|
|
3547
3549
|
// passed no options object at all, silently defeating their policy at
|
|
3548
3550
|
// this one output boundary while report/index.js honoured it.
|
|
3549
|
-
findingProvenance: f.findingProvenance ? (0,
|
|
3551
|
+
findingProvenance: f.findingProvenance ? (0,_posture_provenance_schema_js__WEBPACK_IMPORTED_MODULE_16__/* .redactFindingProvenance */ .As)(f.findingProvenance, {
|
|
3550
3552
|
pseudonymize: process.env.AGENTIC_SECURITY_PSEUDONYMIZE_AUTHORS === '1',
|
|
3551
3553
|
}) : null,
|
|
3552
3554
|
// X-206: the same verification projection the JSON and text reports carry; absent when the finding has no record.
|
|
@@ -3555,7 +3557,7 @@ const explain_finding = {
|
|
|
3555
3557
|
: {}),
|
|
3556
3558
|
// X-307: the same boundary projection the JSON and text reports carry; absent when the finding has no context.
|
|
3557
3559
|
...(f.boundaryContext && typeof f.boundaryContext === 'object'
|
|
3558
|
-
? (0,
|
|
3560
|
+
? (0,_lineage_deployment_projection_js__WEBPACK_IMPORTED_MODULE_15__/* .boundaryFields */ .Q)(f.boundaryContext)
|
|
3559
3561
|
: {}),
|
|
3560
3562
|
};
|
|
3561
3563
|
},
|
|
@@ -3634,7 +3636,7 @@ const _scrubRoot = (sessionRoot, text) => {
|
|
|
3634
3636
|
const roots = new Set([node_path__WEBPACK_IMPORTED_MODULE_2__.resolve(sessionRoot)]);
|
|
3635
3637
|
try { roots.add(node_fs__WEBPACK_IMPORTED_MODULE_0__.realpathSync(node_path__WEBPACK_IMPORTED_MODULE_2__.resolve(sessionRoot))); } catch { /* root vanished: the plain path is still scrubbed */ }
|
|
3636
3638
|
for (const r of roots) out = out.split(r).join('<root>');
|
|
3637
|
-
return (0,
|
|
3639
|
+
return (0,_redact_js__WEBPACK_IMPORTED_MODULE_20__/* .redactString */ .rd)(out);
|
|
3638
3640
|
};
|
|
3639
3641
|
const _gateSummary = (g) => (g ? {
|
|
3640
3642
|
path: g.path ? g.path.ok : undefined, syntax: g.syntax ? g.syntax.ok : undefined,
|
|
@@ -3824,25 +3826,14 @@ const apply_fix = {
|
|
|
3824
3826
|
}
|
|
3825
3827
|
// Inline re-verify — the load-bearing gate. Must pass to write.
|
|
3826
3828
|
let verdict;
|
|
3829
|
+
let fixVerification = null;
|
|
3827
3830
|
try {
|
|
3828
3831
|
const _files = Object.fromEntries(Object.entries(confinedAbs).map(([rel, v]) => [rel, v.content]));
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
const { verifyFixWithTests } = await __webpack_require__.e(/* import() */ 4113).then(__webpack_require__.bind(__webpack_require__, 64113));
|
|
3835
|
-
const t = await verifyFixWithTests({ scanRoot: ctx.sessionRoot, originalFindingStableId: f.stableId, files: _files });
|
|
3836
|
-
verdict = { ok: t.ok, summary: t.summary, rescan: t.legs?.scan?.detail, lint: t.legs?.lint?.detail, tests: t.legs?.tests, testVerdict: t.verdict, verificationRecord: t.verificationRecord ?? null };
|
|
3837
|
-
} else {
|
|
3838
|
-
const verifyFixCore = await getVerifyFixCore();
|
|
3839
|
-
verdict = await verifyFixCore({
|
|
3840
|
-
scanRoot: ctx.sessionRoot,
|
|
3841
|
-
originalFindingStableId: f.stableId,
|
|
3842
|
-
files: _files,
|
|
3843
|
-
fixMeta,
|
|
3844
|
-
});
|
|
3845
|
-
}
|
|
3832
|
+
// One verifier for every route (E3-03). AGENTIC_SECURITY_FIX_RUN_TESTS used to swap in a second test runner here; verifyFix
|
|
3833
|
+
// already carries the test leg, so the flag is now inert.
|
|
3834
|
+
const central = await (0,_fix_verify_patch_js__WEBPACK_IMPORTED_MODULE_14__/* .verifyPatch */ .F)({ scanRoot: ctx.sessionRoot, finding: { id: f.id, stableId: f.stableId }, files: _files, fixMeta, route: 'mcp-apply-fix', mode: dry_run ? 'preview' : 'apply', verify: await getVerifyFixCore() });
|
|
3835
|
+
verdict = central.verdict;
|
|
3836
|
+
fixVerification = central.fixVerification;
|
|
3846
3837
|
} catch (e) {
|
|
3847
3838
|
return { _meta: META, applied: false, reason: `patch verification failed: ${e.message}` };
|
|
3848
3839
|
}
|
|
@@ -3854,6 +3845,7 @@ const apply_fix = {
|
|
|
3854
3845
|
// X-201: the same version-1 verification record every surface emits (additive; null when none could be formed).
|
|
3855
3846
|
verificationRecord: verdict.verificationRecord ?? null,
|
|
3856
3847
|
...(0,_posture_verification_projection_js__WEBPACK_IMPORTED_MODULE_13__/* .verificationFields */ .ze)(verdict.verificationRecord),
|
|
3848
|
+
...(fixVerification ? (0,_fix_verify_patch_js__WEBPACK_IMPORTED_MODULE_14__/* .additiveFields */ .Y)(fixVerification) : {}),
|
|
3857
3849
|
};
|
|
3858
3850
|
}
|
|
3859
3851
|
// FR-307/FR-1002/D-0024: this caller-supplied-patch branch writes via
|
|
@@ -3874,7 +3866,7 @@ const apply_fix = {
|
|
|
3874
3866
|
}
|
|
3875
3867
|
const materialClassification = (0,_posture_material_change_js__WEBPACK_IMPORTED_MODULE_6__/* .classifyFixMaterialRisk */ .kz)(filesForMaterialClassification);
|
|
3876
3868
|
if (dry_run) {
|
|
3877
|
-
return { _meta: META, applied: false, dryRun: true, verified: true, files: Object.keys(confinedAbs), summary: verdict.summary, verificationRecord: verdict.verificationRecord ?? null, ...(0,_posture_verification_projection_js__WEBPACK_IMPORTED_MODULE_13__/* .verificationFields */ .ze)(verdict.verificationRecord), materialClassification };
|
|
3869
|
+
return { _meta: META, applied: false, dryRun: true, verified: true, files: Object.keys(confinedAbs), summary: verdict.summary, verificationRecord: verdict.verificationRecord ?? null, ...(0,_posture_verification_projection_js__WEBPACK_IMPORTED_MODULE_13__/* .verificationFields */ .ze)(verdict.verificationRecord), materialClassification, ...(fixVerification ? (0,_fix_verify_patch_js__WEBPACK_IMPORTED_MODULE_14__/* .additiveFields */ .Y)(fixVerification) : {}) };
|
|
3878
3870
|
}
|
|
3879
3871
|
const approvalRefusal = _highImpactApprovalRefusal(ctx, materialClassification, fixMeta);
|
|
3880
3872
|
if (approvalRefusal) return approvalRefusal;
|
|
@@ -3905,7 +3897,7 @@ const apply_fix = {
|
|
|
3905
3897
|
}
|
|
3906
3898
|
let acceptance = null;
|
|
3907
3899
|
try { acceptance = (0,_posture_fix_history_js__WEBPACK_IMPORTED_MODULE_4__/* .fixAcceptanceRate */ .XR)(ctx.sessionRoot); } catch { /* best-effort */ }
|
|
3908
|
-
return { _meta: META, applied: true, verified: true, patched: written, integrity: status, verify: { summary: verdict.summary, verificationRecord: verdict.verificationRecord ?? null, ...(0,_posture_verification_projection_js__WEBPACK_IMPORTED_MODULE_13__/* .verificationFields */ .ze)(verdict.verificationRecord) }, acceptance, materialClassification };
|
|
3900
|
+
return { _meta: META, applied: true, verified: true, patched: written, integrity: status, verify: { summary: verdict.summary, verificationRecord: verdict.verificationRecord ?? null, ...(0,_posture_verification_projection_js__WEBPACK_IMPORTED_MODULE_13__/* .verificationFields */ .ze)(verdict.verificationRecord) }, acceptance, materialClassification, ...(fixVerification ? (0,_fix_verify_patch_js__WEBPACK_IMPORTED_MODULE_14__/* .additiveFields */ .Y)(fixVerification) : {}) };
|
|
3909
3901
|
}
|
|
3910
3902
|
|
|
3911
3903
|
if (typeof f.fix?.replacement !== 'string') {
|
|
@@ -4063,26 +4055,13 @@ const verify_fix = {
|
|
|
4063
4055
|
// Best-effort: a missing/unsigned/tampered scan just means no PoC is
|
|
4064
4056
|
// available to re-check, not a verify_fix failure — the rescan/lint/
|
|
4065
4057
|
// tests legs below are independent of this and still apply.
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
const { scan: lastScan } = _readLastScanVerified(ctx.sessionRoot, { allowUnsigned: true });
|
|
4069
|
-
const orig = lastScan && (lastScan.findings || []).find(f => f.stableId === stable_id);
|
|
4070
|
-
if (orig && orig.poc && orig.poc.code) poc = { ...orig.poc, finding: orig };
|
|
4071
|
-
} catch { /* best-effort lookup; poc stays null */ }
|
|
4072
|
-
|
|
4073
|
-
const verifyFixCore = await getVerifyFixCore();
|
|
4074
|
-
const r = await verifyFixCore({
|
|
4075
|
-
scanRoot: ctx.sessionRoot,
|
|
4076
|
-
originalFindingStableId: stable_id,
|
|
4077
|
-
files: confined,
|
|
4078
|
-
poc,
|
|
4079
|
-
fixMeta,
|
|
4080
|
-
});
|
|
4058
|
+
const central = await (0,_fix_verify_patch_js__WEBPACK_IMPORTED_MODULE_14__/* .verifyPatch */ .F)({ scanRoot: ctx.sessionRoot, finding: { stableId: stable_id }, files: confined, fixMeta, route: 'mcp-verify-fix', mode: 'verify', verify: await getVerifyFixCore() });
|
|
4059
|
+
const r = central.verdict;
|
|
4081
4060
|
return {
|
|
4082
4061
|
_meta: META,
|
|
4083
4062
|
ok: r.ok,
|
|
4084
4063
|
rescan: { ok: r.rescan.ok, reason: r.rescan.reason, introduced: r.rescan.introduced || [] },
|
|
4085
|
-
lint: { runner: r.lint.runner, ok: r.lint.ok, skipped: r.lint.skipped || false, output: (0,
|
|
4064
|
+
lint: { runner: r.lint.runner, ok: r.lint.ok, skipped: r.lint.skipped || false, output: (0,_redact_js__WEBPACK_IMPORTED_MODULE_20__/* .redactString */ .rd)(r.lint.output || '').slice(0, 1500) },
|
|
4086
4065
|
// verifyFix computes five legs, not two — tests/honesty/poc were
|
|
4087
4066
|
// being silently dropped here, leaving an agent with no structured
|
|
4088
4067
|
// way to see WHY verification failed when the failure was in one
|
|
@@ -4093,12 +4072,13 @@ const verify_fix = {
|
|
|
4093
4072
|
// it can echo proof-harness detail derived from scanned source.
|
|
4094
4073
|
tests: r.tests,
|
|
4095
4074
|
honesty: r.honesty,
|
|
4096
|
-
poc: r.poc ? { ...r.poc, reason: r.poc.reason ? (0,
|
|
4075
|
+
poc: r.poc ? { ...r.poc, reason: r.poc.reason ? (0,_redact_js__WEBPACK_IMPORTED_MODULE_20__/* .redactString */ .rd)(r.poc.reason) : r.poc.reason } : r.poc,
|
|
4097
4076
|
summary: r.summary,
|
|
4098
4077
|
// X-201: the one version-1 verification record (additive). It states what was actually established, e.g.
|
|
4099
4078
|
// `not-run` when no exploit oracle executed against the patch, never a bare pass/fail.
|
|
4100
4079
|
verificationRecord: r.verificationRecord ?? null,
|
|
4101
4080
|
...(0,_posture_verification_projection_js__WEBPACK_IMPORTED_MODULE_13__/* .verificationFields */ .ze)(r.verificationRecord),
|
|
4081
|
+
...(0,_fix_verify_patch_js__WEBPACK_IMPORTED_MODULE_14__/* .additiveFields */ .Y)(central.fixVerification),
|
|
4102
4082
|
};
|
|
4103
4083
|
} catch (e) {
|
|
4104
4084
|
return { _meta: META, ok: false, reason: `verify_fix failed: ${e.message}` };
|
|
@@ -4441,7 +4421,7 @@ const append_agents_memory = {
|
|
|
4441
4421
|
required: ['agent', 'body'],
|
|
4442
4422
|
},
|
|
4443
4423
|
async handler({ agent, body }, ctx) {
|
|
4444
|
-
const r = (0,
|
|
4424
|
+
const r = (0,_posture_agents_memory_js__WEBPACK_IMPORTED_MODULE_21__/* .appendAgentsMemory */ .eu)(ctx.sessionRoot, { agent, body });
|
|
4445
4425
|
return { _meta: META, ...r };
|
|
4446
4426
|
},
|
|
4447
4427
|
};
|
|
@@ -4457,7 +4437,7 @@ const read_agents_memory = {
|
|
|
4457
4437
|
},
|
|
4458
4438
|
},
|
|
4459
4439
|
async handler({ full }, ctx) {
|
|
4460
|
-
const body = (0,
|
|
4440
|
+
const body = (0,_posture_agents_memory_js__WEBPACK_IMPORTED_MODULE_21__/* .readAgentsMemory */ .ox)(ctx.sessionRoot);
|
|
4461
4441
|
if (!body) return { _meta: META, present: false };
|
|
4462
4442
|
if (full) return { _meta: META, present: true, length: body.length, content: body };
|
|
4463
4443
|
// Tail-only — same logic as summarizeForSession but inlined to avoid a
|
|
@@ -4501,7 +4481,7 @@ const query_triage_memory = {
|
|
|
4501
4481
|
// they landed in, rather than hardcoding a field allowlist that could
|
|
4502
4482
|
// miss one.
|
|
4503
4483
|
let results;
|
|
4504
|
-
try { results = JSON.parse((0,
|
|
4484
|
+
try { results = JSON.parse((0,_redact_js__WEBPACK_IMPORTED_MODULE_20__/* .redactString */ .rd)(JSON.stringify(raw))); }
|
|
4505
4485
|
catch { results = raw; }
|
|
4506
4486
|
return {
|
|
4507
4487
|
_meta: META,
|
|
@@ -4537,7 +4517,7 @@ const query_findings_memory = {
|
|
|
4537
4517
|
// whole-structure redactString round-trip is applied rather than a
|
|
4538
4518
|
// per-field allowlist that could miss one of the four shapes.
|
|
4539
4519
|
let body;
|
|
4540
|
-
try { body = JSON.parse((0,
|
|
4520
|
+
try { body = JSON.parse((0,_redact_js__WEBPACK_IMPORTED_MODULE_20__/* .redactString */ .rd)(JSON.stringify(raw))); }
|
|
4541
4521
|
catch { body = raw; }
|
|
4542
4522
|
return { _meta: META, ...body };
|
|
4543
4523
|
},
|
|
@@ -4559,7 +4539,7 @@ const lookup_cve = {
|
|
|
4559
4539
|
required: ['cve'],
|
|
4560
4540
|
},
|
|
4561
4541
|
async handler({ cve }, _ctx) {
|
|
4562
|
-
const r = (0,
|
|
4542
|
+
const r = (0,_posture_cve_lookup_js__WEBPACK_IMPORTED_MODULE_22__/* .lookupCve */ .x)(cve);
|
|
4563
4543
|
return { _meta: META, ...r };
|
|
4564
4544
|
},
|
|
4565
4545
|
};
|
|
@@ -4665,11 +4645,11 @@ const apply_sca_upgrade = {
|
|
|
4665
4645
|
};
|
|
4666
4646
|
|
|
4667
4647
|
// X-407: read-only scenario export; the factory takes this file's confinement so the two modules do not import each other.
|
|
4668
|
-
const { invariant_scenario_export } = (0,
|
|
4648
|
+
const { invariant_scenario_export } = (0,_invariant_tools_js__WEBPACK_IMPORTED_MODULE_18__/* .makeInvariantTools */ ._)({ confine: _confine, META });
|
|
4669
4649
|
// X-707: read-only portfolio progress view, same factory shape.
|
|
4670
|
-
const { portfolio_progress } = (0,
|
|
4650
|
+
const { portfolio_progress } = (0,_portfolio_tools_js__WEBPACK_IMPORTED_MODULE_19__/* .makePortfolioTools */ ._)({ confine: _confine, META });
|
|
4671
4651
|
|
|
4672
|
-
const ALL_TOOLS = [scan_diff, query_taint, explain_finding, apply_fix, verify_fix, synthesize_fix, find_rule_module, append_scratchpad, read_scratchpad, append_agents_memory, read_agents_memory, lookup_cve, synthesize_sca_upgrade, apply_sca_upgrade, query_triage_memory, query_findings_memory, query_cache_telemetry,
|
|
4652
|
+
const ALL_TOOLS = [scan_diff, query_taint, explain_finding, apply_fix, verify_fix, synthesize_fix, find_rule_module, append_scratchpad, read_scratchpad, append_agents_memory, read_agents_memory, lookup_cve, synthesize_sca_upgrade, apply_sca_upgrade, query_triage_memory, query_findings_memory, query_cache_telemetry, _dataflow_tools_js__WEBPACK_IMPORTED_MODULE_17__/* .dataflow_get_graph */ .HX, _dataflow_tools_js__WEBPACK_IMPORTED_MODULE_17__/* .dataflow_get_node */ .HI, _dataflow_tools_js__WEBPACK_IMPORTED_MODULE_17__/* .dataflow_get_edge */ .gC, _dataflow_tools_js__WEBPACK_IMPORTED_MODULE_17__/* .dataflow_get_flow */ .ri, invariant_scenario_export, portfolio_progress];
|
|
4673
4653
|
|
|
4674
4654
|
__webpack_async_result__();
|
|
4675
4655
|
} catch(e) { __webpack_async_result__(e); } });
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export const id = 9692;
|
|
2
|
+
export const ids = [9692];
|
|
3
|
+
export const modules = {
|
|
4
|
+
|
|
5
|
+
/***/ 99692:
|
|
6
|
+
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
|
7
|
+
|
|
8
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
9
|
+
/* harmony export */ extractImagePackages: () => (/* binding */ extractImagePackages)
|
|
10
|
+
/* harmony export */ });
|
|
11
|
+
/* unused harmony exports parseDpkgStatus, parseApkInstalled */
|
|
12
|
+
// R8 (PRD §5) — container-image OS-package inventory.
|
|
13
|
+
//
|
|
14
|
+
// container.js reads the Dockerfile (FROM + apt/apk install lines). This reads
|
|
15
|
+
// the ACTUAL installed-package databases from an extracted image filesystem
|
|
16
|
+
// (or the host), catching packages baked into the base image that the
|
|
17
|
+
// Dockerfile never names. Components flow into the existing OSV pipeline + SBOM.
|
|
18
|
+
//
|
|
19
|
+
// Pure parsers (unit-tested) + a path-matching extractor. No daemon; reads the
|
|
20
|
+
// package-DB files that appear when an image layer/tarball is unpacked.
|
|
21
|
+
|
|
22
|
+
// Debian/Ubuntu: /var/lib/dpkg/status — RFC822-style blocks separated by blank
|
|
23
|
+
// lines. Only "install ok installed" entries count (not removed/config-files).
|
|
24
|
+
function parseDpkgStatus(text) {
|
|
25
|
+
const out = [];
|
|
26
|
+
for (const block of String(text || '').split(/\n\s*\n/)) {
|
|
27
|
+
const name = (block.match(/^Package:\s*(.+)$/m) || [])[1];
|
|
28
|
+
const version = (block.match(/^Version:\s*(.+)$/m) || [])[1];
|
|
29
|
+
const status = (block.match(/^Status:\s*(.+)$/m) || [])[1] || '';
|
|
30
|
+
if (!name || !version) continue;
|
|
31
|
+
if (!/\binstalled\b/.test(status)) continue;
|
|
32
|
+
out.push({ name: name.trim(), version: version.trim(), ecosystem: 'Debian' });
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Alpine: /lib/apk/db/installed — blocks separated by blank lines; P:=name V:=version.
|
|
38
|
+
function parseApkInstalled(text) {
|
|
39
|
+
const out = [];
|
|
40
|
+
for (const block of String(text || '').split(/\n\s*\n/)) {
|
|
41
|
+
const name = (block.match(/^P:(.+)$/m) || [])[1];
|
|
42
|
+
const version = (block.match(/^V:(.+)$/m) || [])[1];
|
|
43
|
+
if (!name || !version) continue;
|
|
44
|
+
out.push({ name: name.trim(), version: version.trim(), ecosystem: 'Alpine' });
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const _PURL = { Debian: (n, v) => `pkg:deb/debian/${n}@${v}`, Alpine: (n, v) => `pkg:apk/alpine/${n}@${v}` };
|
|
50
|
+
|
|
51
|
+
// File-path tells for an unpacked image. Match on path suffix so it works
|
|
52
|
+
// whether the scan root is the rootfs or a subdirectory of it.
|
|
53
|
+
function _dbKind(path) {
|
|
54
|
+
const p = path.replace(/\\/g, '/');
|
|
55
|
+
if (/(?:^|\/)var\/lib\/dpkg\/status$/.test(p)) return 'dpkg';
|
|
56
|
+
if (/(?:^|\/)lib\/apk\/db\/installed$/.test(p)) return 'apk';
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Extract OS-package components from any image package-DBs present in the scanned
|
|
62
|
+
* files. Returns components in the engine's component shape so they ride the
|
|
63
|
+
* existing OSV/SBOM pipeline. De-dups by ecosystem:name:version.
|
|
64
|
+
*/
|
|
65
|
+
function extractImagePackages(fileContents) {
|
|
66
|
+
const comps = [];
|
|
67
|
+
const seen = new Set();
|
|
68
|
+
for (const [file, content] of Object.entries(fileContents || {})) {
|
|
69
|
+
const kind = _dbKind(file);
|
|
70
|
+
if (!kind) continue;
|
|
71
|
+
const pkgs = kind === 'dpkg' ? parseDpkgStatus(content) : parseApkInstalled(content);
|
|
72
|
+
for (const p of pkgs) {
|
|
73
|
+
const key = `${p.ecosystem}:${p.name}:${p.version}`;
|
|
74
|
+
if (seen.has(key)) continue;
|
|
75
|
+
seen.add(key);
|
|
76
|
+
comps.push({
|
|
77
|
+
name: p.name, version: p.version, group: '', ecosystem: p.ecosystem,
|
|
78
|
+
purl: (_PURL[p.ecosystem] || (() => null))(p.name, p.version),
|
|
79
|
+
filePath: file, isUnpinned: false, isTransitive: false, isOsPackage: true,
|
|
80
|
+
scope: 'required', reachable: true,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return comps;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
/***/ })
|
|
89
|
+
|
|
90
|
+
};
|
package/dist/9800.index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const id = 9800;
|
|
2
|
-
export const ids = [9800];
|
|
2
|
+
export const ids = [9800,2199];
|
|
3
3
|
export const modules = {
|
|
4
4
|
|
|
5
5
|
/***/ 59800:
|
|
@@ -136,6 +136,218 @@ function doctor(args) {
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
|
|
139
|
+
/***/ }),
|
|
140
|
+
|
|
141
|
+
/***/ 3740:
|
|
142
|
+
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
|
143
|
+
|
|
144
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
145
|
+
/* harmony export */ kO: () => (/* binding */ proveFinding)
|
|
146
|
+
/* harmony export */ });
|
|
147
|
+
/* unused harmony exports independentVerify, applySeverityPolicy, _newRunId */
|
|
148
|
+
/* harmony import */ var node_crypto__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(77598);
|
|
149
|
+
/* harmony import */ var _states_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(12090);
|
|
150
|
+
/* harmony import */ var _runner_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2998);
|
|
151
|
+
/* harmony import */ var _reproducer_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(37055);
|
|
152
|
+
/* harmony import */ var _proof_tier_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(40216);
|
|
153
|
+
// Proof orchestration: finding + revision + reproducer + policy -> structured evidence.
|
|
154
|
+
//
|
|
155
|
+
// Rules that make this safe to trust:
|
|
156
|
+
// * The model may propose a reproducer and select an oracle. The oracle (oracles.js) judges. Never a model.
|
|
157
|
+
// * An attempt that did not complete (timeout, build failure, blocked, unsupported, error) is NOT a negative and NOT a
|
|
158
|
+
// positive: it is degraded evidence, it never advances the state, and it makes the result INCOMPLETE.
|
|
159
|
+
// * EXPLOIT_CONFIRMED needs `required` successes in `attempts` completed attempts AND a pass from an independent
|
|
160
|
+
// verifier that receives only {revision, reproducer, findingId, oracle} in a fresh environment.
|
|
161
|
+
// * "Not reproduced" is reported as such; it is never reported as safe.
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
const PROOF_POLICY_DEFAULTS = Object.freeze({ attempts: 3, required: 3, independentReplay: true, timeoutMs: 20_000, cpus: 1, memoryMb: 512, network: 'none', requireContainer: false });
|
|
169
|
+
const RESULT_SCHEMA = 'agentic-security/proof-result';
|
|
170
|
+
|
|
171
|
+
function normalizePolicy(p = {}) {
|
|
172
|
+
const x = { ...PROOF_POLICY_DEFAULTS, ...p };
|
|
173
|
+
x.attempts = Math.max(1, Math.min(10, Math.trunc(Number(x.attempts)) || PROOF_POLICY_DEFAULTS.attempts));
|
|
174
|
+
x.required = Math.max(1, Math.min(x.attempts, Math.trunc(Number(x.required)) || x.attempts));
|
|
175
|
+
x.timeoutMs = Math.max(1000, Math.min(120_000, Number(x.timeoutMs) || PROOF_POLICY_DEFAULTS.timeoutMs));
|
|
176
|
+
return x;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const summarize = (a) => ({ status: a.status, fired: a.oracle?.fired === true, inconclusive: a.oracle?.inconclusive === true, reason: a.oracle?.reason ?? a.reasons?.[0] ?? null, durationMs: a.durationMs, degraded: a.degraded });
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Independent verifier. Takes a verifierView ONLY; any extra property (a model's reasoning, prior results) is rejected so
|
|
183
|
+
* the isolation of its inputs is checkable rather than a convention.
|
|
184
|
+
*/
|
|
185
|
+
async function independentVerify(view, opts = {}) {
|
|
186
|
+
const allowed = new Set(['revision', 'reproducer', 'findingId', 'oracle']);
|
|
187
|
+
const extra = Object.keys(view || {}).filter((k) => !allowed.has(k));
|
|
188
|
+
if (extra.length) return { status: 'rejected', reason: `verifier input must be exactly revision, reproducer, findingId, oracle; got extra: ${extra.join(', ')}` };
|
|
189
|
+
const attempt = await (opts.attemptFn ?? _runner_js__WEBPACK_IMPORTED_MODULE_2__/* .runAttempt */ .Tm)(structuredClone(view.reproducer), { ...opts, preferContainer: opts.preferContainer });
|
|
190
|
+
return { status: attempt.status === 'completed' ? (attempt.oracle?.fired ? 'confirmed' : 'not-reproduced') : 'incomplete', attempt: summarize(attempt), environment: attempt.environment ?? null };
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* @param {object} a
|
|
195
|
+
* @param {object} a.finding the finding (id/stableId, severity, proofTier ...)
|
|
196
|
+
* @param {string} [a.revision] commit the proof applies to
|
|
197
|
+
* @param {object} a.reproducer serialized reproducer
|
|
198
|
+
* @param {object} [a.policy]
|
|
199
|
+
* @param {object} [a.deps] test seams: { attemptFn }
|
|
200
|
+
*/
|
|
201
|
+
async function proveFinding({ finding, revision = null, reproducer, policy = {}, signal, deps = {}, sourceState = null, sourceRoot = null, overlay = null } = {}) {
|
|
202
|
+
const started = Date.now();
|
|
203
|
+
const pol = normalizePolicy(policy);
|
|
204
|
+
const attemptFn = deps.attemptFn ?? _runner_js__WEBPACK_IMPORTED_MODULE_2__/* .runAttempt */ .Tm;
|
|
205
|
+
const findingId = finding?.stableId ?? finding?.id ?? reproducer?.findingId ?? 'unknown';
|
|
206
|
+
const degradation = [];
|
|
207
|
+
let state = sourceState ?? (0,_states_js__WEBPACK_IMPORTED_MODULE_1__/* .fromProofTier */ .jn)((0,_proof_tier_js__WEBPACK_IMPORTED_MODULE_4__/* .proofTierOf */ .gx)(finding || {}));
|
|
208
|
+
if (state === 'REPRODUCED') state = 'STATICALLY_CORROBORATED'; // an old single-run marker proof must be re-earned here
|
|
209
|
+
const startState = state;
|
|
210
|
+
|
|
211
|
+
const result = (extra) => ({
|
|
212
|
+
schema: RESULT_SCHEMA, version: 1, findingId, revision, startState, state, staticCorroboration: (0,_states_js__WEBPACK_IMPORTED_MODULE_1__/* .stateRank */ .g3)(startState) >= 1, tier: (0,_states_js__WEBPACK_IMPORTED_MODULE_1__/* .toProofTier */ .KF)(state),
|
|
213
|
+
oracle: reproducer?.oracle?.type ?? null, policy: pol,
|
|
214
|
+
reproducerDigest: reproducer ? safeDigest(reproducer) : null,
|
|
215
|
+
degradation, timing: { proofMs: Date.now() - started }, ...extra,
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
const errs = reproducer ? (0,_reproducer_js__WEBPACK_IMPORTED_MODULE_3__/* .validateReproducer */ .mC)(reproducer) : ['no reproducer supplied'];
|
|
219
|
+
if (errs.length) { degradation.push('invalid-reproducer'); return result({ completeness: 'INCOMPLETE', outcome: 'invalid-reproducer', reasons: errs, attempts: { required: pol.required, run: 0, successes: 0, incomplete: 0 }, independentReplay: { status: 'not-run' } }); }
|
|
220
|
+
|
|
221
|
+
// A valid reproducer is itself the REPRODUCER_GENERATED rung. Static corroboration is recorded, not required: an exploit
|
|
222
|
+
// that reproduces under an independent oracle is deterministic corroboration in its own right, and a pattern-only finding
|
|
223
|
+
// must not be unable to earn proof merely because the taint engine never saw it. The record says which it was.
|
|
224
|
+
const staticCorroboration = (0,_states_js__WEBPACK_IMPORTED_MODULE_1__/* .stateRank */ .g3)(startState) >= (0,_states_js__WEBPACK_IMPORTED_MODULE_1__/* .stateRank */ .g3)('STATICALLY_CORROBORATED');
|
|
225
|
+
if (!staticCorroboration) degradation.push('no-static-corroboration');
|
|
226
|
+
state = 'REPRODUCER_GENERATED';
|
|
227
|
+
|
|
228
|
+
const attempts = [];
|
|
229
|
+
for (let i = 0; i < pol.attempts; i++) {
|
|
230
|
+
if (signal?.aborted) { degradation.push('cancelled'); break; }
|
|
231
|
+
const a = await attemptFn(structuredClone(reproducer), { limits: { timeoutMs: pol.timeoutMs }, signal, requireContainer: pol.requireContainer, preferContainer: pol.preferContainer, force: pol.force, sourceRoot, overlay });
|
|
232
|
+
attempts.push(a);
|
|
233
|
+
// Stop early once the threshold can no longer be met only if every attempt is a decisive negative; incomplete runs continue.
|
|
234
|
+
}
|
|
235
|
+
const completed = attempts.filter((a) => a.status === 'completed' && !a.oracle?.inconclusive);
|
|
236
|
+
const successes = completed.filter((a) => a.oracle?.fired).length;
|
|
237
|
+
const incomplete = attempts.length - completed.length;
|
|
238
|
+
for (const a of attempts) for (const d of a.degraded || []) if (!degradation.includes(d)) degradation.push(d);
|
|
239
|
+
if (incomplete) degradation.push(`incomplete-attempts:${incomplete}`);
|
|
240
|
+
const env = attempts.find((a) => a.environment)?.environment ?? null;
|
|
241
|
+
const base = {
|
|
242
|
+
environment: env && { mode: env.mode, assurance: env.assurance, backend: env.backend ?? null, note: env.note ?? null },
|
|
243
|
+
build: attempts.some((a) => a.status === 'build-failed') ? 'failed' : attempts.length ? 'ok' : 'not-run',
|
|
244
|
+
attempts: { required: pol.required, run: attempts.length, successes, incomplete, detail: attempts.map(summarize) },
|
|
245
|
+
artifactHashes: { reproducer: safeDigest(reproducer), observations: (0,_reproducer_js__WEBPACK_IMPORTED_MODULE_3__/* .sha256 */ .sc)((0,_reproducer_js__WEBPACK_IMPORTED_MODULE_3__/* .canonicalize */ .dw)(attempts.map((a) => a.observation ?? null))) },
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
if (successes > 0) {
|
|
249
|
+
const r = (0,_states_js__WEBPACK_IMPORTED_MODULE_1__/* .advance */ .np)(state, 'REPRODUCED'); if (r.ok) state = r.state;
|
|
250
|
+
}
|
|
251
|
+
if (!attempts.length) return result({ ...base, completeness: 'INCOMPLETE', outcome: 'not-run', independentReplay: { status: 'not-run' } });
|
|
252
|
+
if (successes === 0) {
|
|
253
|
+
const decisive = completed.length === attempts.length;
|
|
254
|
+
return result({ ...base, completeness: decisive ? 'FULL' : 'INCOMPLETE', outcome: decisive ? 'not-reproduced' : 'inconclusive', note: 'not reproduced is not proof of safety', independentReplay: { status: 'not-run' } });
|
|
255
|
+
}
|
|
256
|
+
if (successes < pol.required || incomplete) {
|
|
257
|
+
return result({ ...base, completeness: incomplete ? 'INCOMPLETE' : 'DEGRADED', outcome: 'reproduced-below-threshold', independentReplay: { status: 'not-run' } });
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
let independent = { status: 'skipped' };
|
|
261
|
+
if (pol.independentReplay) {
|
|
262
|
+
independent = await independentVerify((0,_reproducer_js__WEBPACK_IMPORTED_MODULE_3__/* .verifierView */ .IW)({ revision, reproducer, findingId, oracle: reproducer.oracle }), { attemptFn, limits: { timeoutMs: pol.timeoutMs }, signal, requireContainer: pol.requireContainer, force: pol.force, sourceRoot, overlay });
|
|
263
|
+
if (independent.status !== 'confirmed') degradation.push(`independent-replay:${independent.status}`);
|
|
264
|
+
} else degradation.push('independent-replay-disabled');
|
|
265
|
+
if (independent.status === 'confirmed') {
|
|
266
|
+
const r = (0,_states_js__WEBPACK_IMPORTED_MODULE_1__/* .advance */ .np)(state, 'EXPLOIT_CONFIRMED'); if (r.ok) state = r.state;
|
|
267
|
+
}
|
|
268
|
+
const full = state === 'EXPLOIT_CONFIRMED' && base.environment?.assurance !== 'none';
|
|
269
|
+
return result({ ...base, independentReplay: independent, completeness: full ? (base.environment.assurance === 'lower' ? 'DEGRADED' : 'FULL') : 'INCOMPLETE', outcome: full ? 'exploit-confirmed' : 'reproduced-unverified' });
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const safeDigest = (r) => { try { return (0,_reproducer_js__WEBPACK_IMPORTED_MODULE_3__/* .reproducerDigest */ .we)(r); } catch { return null; } };
|
|
273
|
+
|
|
274
|
+
/** Severity policy: optional, never on by default. Returns the finding unchanged unless the policy asks to demote. */
|
|
275
|
+
function applySeverityPolicy(finding, evidenceState, policy) {
|
|
276
|
+
const req = policy?.criticalRequires;
|
|
277
|
+
if (!Array.isArray(req) || !req.length || finding?.severity !== 'critical') return finding;
|
|
278
|
+
const ok = req.some((s) => stateRankOf(evidenceState ?? 'CANDIDATE') >= stateRankOf(s));
|
|
279
|
+
return ok ? finding : { ...finding, severity: 'high', severityPolicy: { demotedFrom: 'critical', reason: `critical requires ${req.join(' or ')}; evidence state is ${evidenceState ?? 'CANDIDATE'}` } };
|
|
280
|
+
}
|
|
281
|
+
const _newRunId = () => randomBytes(6).toString('hex');
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
/***/ }),
|
|
285
|
+
|
|
286
|
+
/***/ 12090:
|
|
287
|
+
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
|
288
|
+
|
|
289
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
290
|
+
/* harmony export */ KF: () => (/* binding */ toProofTier),
|
|
291
|
+
/* harmony export */ g3: () => (/* binding */ stateRank),
|
|
292
|
+
/* harmony export */ jn: () => (/* binding */ fromProofTier),
|
|
293
|
+
/* harmony export */ np: () => (/* binding */ advance)
|
|
294
|
+
/* harmony export */ });
|
|
295
|
+
/* unused harmony exports EVIDENCE_STATES, COMPLETENESS */
|
|
296
|
+
// Evidence state ladder for the Universal Exploit Proof Fabric.
|
|
297
|
+
//
|
|
298
|
+
// Evidence state is SEPARATE from severity and confidence. It extends, never replaces, the vocabulary that already
|
|
299
|
+
// exists: `proof-tier.js` (execution-proven / proof-failed / taint-proven / unproven) and the fix-verify legs
|
|
300
|
+
// (`verifiedFull`, `degradedLegs`). `toProofTier` / `fromProofTier` are the explicit bridges.
|
|
301
|
+
//
|
|
302
|
+
// Transitions are guarded: a state can only be reached from the state directly before it (or by dropping back), so no
|
|
303
|
+
// caller can jump a finding to EXPLOIT_CONFIRMED without passing REPRODUCED, or to FIX_VERIFIED without
|
|
304
|
+
// FIX_REPLAY_BLOCKED. A degraded or incomplete run NEVER advances a state.
|
|
305
|
+
const EVIDENCE_STATES = Object.freeze([
|
|
306
|
+
'CANDIDATE',
|
|
307
|
+
'STATICALLY_CORROBORATED',
|
|
308
|
+
'REPRODUCER_GENERATED',
|
|
309
|
+
'REPRODUCED',
|
|
310
|
+
'EXPLOIT_CONFIRMED',
|
|
311
|
+
'FIX_REPLAY_BLOCKED',
|
|
312
|
+
'FIX_VERIFIED',
|
|
313
|
+
]);
|
|
314
|
+
|
|
315
|
+
const stateRank = (s) => EVIDENCE_STATES.indexOf(s);
|
|
316
|
+
|
|
317
|
+
const REQUIRES_PREDECESSOR = Object.freeze(Object.fromEntries(EVIDENCE_STATES.map((s, i) => [s, i === 0 ? null : EVIDENCE_STATES[i - 1]])));
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Advance `from` to `to`. Returns { ok, state, reason }. Moving up requires `to` to be exactly the next rung; moving
|
|
321
|
+
* down or staying is always allowed (evidence can be lost, never invented). Unknown states are rejected.
|
|
322
|
+
*/
|
|
323
|
+
function advance(from, to) {
|
|
324
|
+
if (!EVIDENCE_STATES.includes(from)) return { ok: false, state: 'CANDIDATE', reason: `unknown current state: ${String(from)}` };
|
|
325
|
+
if (!EVIDENCE_STATES.includes(to)) return { ok: false, state: from, reason: `unknown target state: ${String(to)}` };
|
|
326
|
+
if (stateRank(to) <= stateRank(from)) return { ok: true, state: to, reason: null };
|
|
327
|
+
if (REQUIRES_PREDECESSOR[to] !== from) return { ok: false, state: from, reason: `cannot reach ${to} from ${from}: ${REQUIRES_PREDECESSOR[to]} is required first` };
|
|
328
|
+
return { ok: true, state: to, reason: null };
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Bridges to the older vocabulary so existing consumers keep working.
|
|
332
|
+
function toProofTier(state) {
|
|
333
|
+
const r = stateRank(state);
|
|
334
|
+
if (r >= stateRank('EXPLOIT_CONFIRMED')) return 'execution-proven';
|
|
335
|
+
if (r >= stateRank('STATICALLY_CORROBORATED')) return 'taint-proven';
|
|
336
|
+
return 'unproven';
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
function fromProofTier(tier) {
|
|
340
|
+
if (tier === 'taint-proven') return 'STATICALLY_CORROBORATED';
|
|
341
|
+
// execution-proven under the older single-run marker path is one run, not the 3/3 + independent replay the fabric
|
|
342
|
+
// requires, so it maps to REPRODUCED and never to EXPLOIT_CONFIRMED.
|
|
343
|
+
if (tier === 'execution-proven') return 'REPRODUCED';
|
|
344
|
+
return 'CANDIDATE';
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Completeness vocabulary shared with fix-verify: FULL only when nothing was skipped.
|
|
348
|
+
const COMPLETENESS = Object.freeze(['FULL', 'DEGRADED', 'INCOMPLETE']);
|
|
349
|
+
|
|
350
|
+
|
|
139
351
|
/***/ }),
|
|
140
352
|
|
|
141
353
|
/***/ 62199:
|