@clear-capabilities/agentic-security-scanner 0.172.1 → 0.174.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.
Files changed (201) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/bin/agentic-security.js +37 -0
  3. package/dist/119.index.js +197 -0
  4. package/dist/128.index.js +129 -0
  5. package/dist/1293.index.js +5689 -0
  6. package/dist/1351.index.js +133 -0
  7. package/dist/1387.index.js +271 -0
  8. package/dist/1437.index.js +23 -0
  9. package/dist/1445.index.js +110 -0
  10. package/dist/1505.index.js +151 -0
  11. package/dist/1557.index.js +293 -0
  12. package/dist/1621.index.js +311 -0
  13. package/dist/1751.index.js +160 -0
  14. package/dist/1765.index.js +727 -0
  15. package/dist/1861.index.js +690 -0
  16. package/dist/1898.index.js +116 -0
  17. package/dist/1906.index.js +433 -0
  18. package/dist/1920.index.js +1 -291
  19. package/dist/208.index.js +1631 -0
  20. package/dist/2199.index.js +0 -239
  21. package/dist/2223.index.js +159 -0
  22. package/dist/2530.index.js +152 -0
  23. package/dist/2565.index.js +116 -0
  24. package/dist/2574.index.js +127 -0
  25. package/dist/2620.index.js +345 -0
  26. package/dist/2773.index.js +98 -0
  27. package/dist/2775.index.js +32 -0
  28. package/dist/2966.index.js +171 -0
  29. package/dist/2972.index.js +87 -0
  30. package/dist/2991.index.js +131 -0
  31. package/dist/3063.index.js +833 -0
  32. package/dist/3075.index.js +227 -0
  33. package/dist/3121.index.js +297 -0
  34. package/dist/3314.index.js +263 -0
  35. package/dist/3480.index.js +1822 -0
  36. package/dist/3481.index.js +24 -0
  37. package/dist/3506.index.js +268 -0
  38. package/dist/3533.index.js +591 -0
  39. package/dist/3653.index.js +450 -0
  40. package/dist/3822.index.js +131 -0
  41. package/dist/3868.index.js +292 -0
  42. package/dist/3917.index.js +152 -0
  43. package/dist/3918.index.js +192 -0
  44. package/dist/4090.index.js +288 -0
  45. package/dist/4121.index.js +1190 -0
  46. package/dist/4142.index.js +0 -239
  47. package/dist/4336.index.js +436 -0
  48. package/dist/4387.index.js +532 -0
  49. package/dist/4413.index.js +302 -0
  50. package/dist/4476.index.js +4510 -0
  51. package/dist/4491.index.js +133 -0
  52. package/dist/4538.index.js +185 -0
  53. package/dist/4684.index.js +319 -0
  54. package/dist/4740.index.js +165 -0
  55. package/dist/4780.index.js +209 -0
  56. package/dist/4802.index.js +225 -0
  57. package/dist/4812.index.js +379 -0
  58. package/dist/4835.index.js +126 -0
  59. package/dist/494.index.js +226 -0
  60. package/dist/4991.index.js +549 -0
  61. package/dist/5199.index.js +305 -0
  62. package/dist/5216.index.js +109 -0
  63. package/dist/5439.index.js +301 -0
  64. package/dist/5443.index.js +97 -0
  65. package/dist/5496.index.js +377 -0
  66. package/dist/550.index.js +2 -1
  67. package/dist/5801.index.js +588 -0
  68. package/dist/5858.index.js +223 -0
  69. package/dist/5933.index.js +143 -0
  70. package/dist/601.index.js +23 -0
  71. package/dist/6173.index.js +273 -0
  72. package/dist/6291.index.js +1871 -0
  73. package/dist/6312.index.js +666 -0
  74. package/dist/634.index.js +16182 -0
  75. package/dist/644.index.js +87 -0
  76. package/dist/6508.index.js +283 -0
  77. package/dist/6560.index.js +645 -0
  78. package/dist/6576.index.js +422 -0
  79. package/dist/6579.index.js +271 -0
  80. package/dist/6745.index.js +305 -0
  81. package/dist/6818.index.js +21642 -0
  82. package/dist/6972.index.js +167 -0
  83. package/dist/6995.index.js +163 -0
  84. package/dist/7249.index.js +191 -0
  85. package/dist/7372.index.js +1197 -0
  86. package/dist/7546.index.js +541 -0
  87. package/dist/76.index.js +448 -0
  88. package/dist/7879.index.js +163 -0
  89. package/dist/8025.index.js +130 -0
  90. package/dist/8054.index.js +248 -0
  91. package/dist/8097.index.js +201 -0
  92. package/dist/8126.index.js +191 -0
  93. package/dist/8178.index.js +78 -0
  94. package/dist/818.index.js +212 -0
  95. package/dist/8382.index.js +93 -0
  96. package/dist/8408.index.js +261 -0
  97. package/dist/8540.index.js +174 -0
  98. package/dist/8635.index.js +802 -0
  99. package/dist/8688.index.js +410 -0
  100. package/dist/8699.index.js +779 -0
  101. package/dist/8891.index.js +457 -0
  102. package/dist/8916.index.js +885 -0
  103. package/dist/9146.index.js +170 -0
  104. package/dist/9168.index.js +841 -0
  105. package/dist/9292.index.js +369 -0
  106. package/dist/9382.index.js +135 -11
  107. package/dist/9422.index.js +866 -0
  108. package/dist/9440.index.js +453 -0
  109. package/dist/9479.index.js +152 -0
  110. package/dist/9481.index.js +220 -0
  111. package/dist/9539.index.js +100 -0
  112. package/dist/9547.index.js +103 -0
  113. package/dist/9560.index.js +41 -61
  114. package/dist/9692.index.js +90 -0
  115. package/dist/9800.index.js +213 -1
  116. package/dist/9899.index.js +138 -0
  117. package/dist/9981.index.js +206 -0
  118. package/dist/999.index.js +117 -0
  119. package/dist/agentic-security.mjs +27 -27
  120. package/dist/agentic-security.mjs.sha256 +1 -1
  121. package/package.json +31 -6
  122. package/src/context-intelligence/candidates.js +2 -1
  123. package/src/context-intelligence/capabilities.js +2 -1
  124. package/src/context-intelligence/cli.js +2 -0
  125. package/src/context-intelligence/config.js +3 -1
  126. package/src/context-intelligence/controls.js +49 -1
  127. package/src/context-intelligence/counterexample.js +200 -0
  128. package/src/context-intelligence/cross-route.js +111 -0
  129. package/src/context-intelligence/findings.js +166 -0
  130. package/src/context-intelligence/invariants.js +197 -0
  131. package/src/context-intelligence/queue.js +6 -1
  132. package/src/context-intelligence/reachability.js +2 -2
  133. package/src/context-intelligence/review.js +68 -4
  134. package/src/dataflow/access-paths.js +11 -0
  135. package/src/dataflow/analysis-limits.js +66 -0
  136. package/src/dataflow/engine.js +282 -24
  137. package/src/dataflow/service-edges.js +174 -0
  138. package/src/dataflow/summaries.js +7 -1
  139. package/src/discovery/judge.js +2 -1
  140. package/src/engine.js +82 -14
  141. package/src/fix/apply-fix-service.js +55 -8
  142. package/src/fix/batch-journal.js +84 -0
  143. package/src/fix/exploit-replay.js +51 -0
  144. package/src/fix/footprint.js +65 -0
  145. package/src/fix/patch-policy.js +49 -0
  146. package/src/fix/secret-persistence.js +39 -0
  147. package/src/fix/test-commands.js +84 -0
  148. package/src/fix/verification-adapters.js +97 -0
  149. package/src/fix/verification-record.js +243 -0
  150. package/src/fix/verify-patch.js +89 -0
  151. package/src/ir/CLAUDE.md +5 -0
  152. package/src/ir/callgraph.js +23 -1
  153. package/src/ir/module-resolver.js +315 -0
  154. package/src/ir/parser-js.js +21 -2
  155. package/src/ir/semantic-graph.js +245 -0
  156. package/src/language/haskell-findings.js +2 -0
  157. package/src/language/haskell-guards.js +1 -1
  158. package/src/language/haskell-ir.js +3 -1
  159. package/src/language/haskell-models.js +94 -0
  160. package/src/language/haskell-security-rules.js +20 -0
  161. package/src/language/nixos-hardening.js +72 -0
  162. package/src/lineage/build-attested-correlation.js +63 -0
  163. package/src/lineage/deployment-identity.js +76 -0
  164. package/src/mcp/tools.js +13 -34
  165. package/src/pipeline/canonical-output.js +64 -0
  166. package/src/pipeline/detector-runner.js +7 -0
  167. package/src/pipeline/scan-health.js +14 -0
  168. package/src/pipeline/supervised-analyzers.js +125 -0
  169. package/src/pipeline/supervised-child.js +17 -0
  170. package/src/pipeline/telemetry.js +79 -0
  171. package/src/posture/accuracy-scorecard.js +98 -9
  172. package/src/posture/artifact-registry.js +5 -0
  173. package/src/posture/assurance/evidence-registry.js +215 -0
  174. package/src/posture/assurance/release-package-verify.js +135 -0
  175. package/src/posture/assurance/release-package.js +118 -0
  176. package/src/posture/assurance/release-verdict.js +94 -0
  177. package/src/posture/assurance/waiver.js +200 -0
  178. package/src/posture/compliance-truth.js +100 -0
  179. package/src/posture/evaluation/scan-child.js +3 -1
  180. package/src/posture/evaluation/why-missed.js +3 -1
  181. package/src/posture/exploitability-evidence.js +141 -0
  182. package/src/posture/fix-verify.js +4 -2
  183. package/src/posture/fleet/exposure-ranking.js +115 -0
  184. package/src/posture/fleet/service-chain-graph.js +150 -0
  185. package/src/posture/graph-reconciliation.js +154 -0
  186. package/src/posture/provenance/coverage.js +103 -0
  187. package/src/posture/provenance/git-evidence.js +84 -0
  188. package/src/posture/provenance/origin-resolver.js +7 -1
  189. package/src/posture/provenance/predicate-replay.js +14 -4
  190. package/src/posture/runtime-correlation.js +61 -15
  191. package/src/posture/runtime-explanation.js +116 -0
  192. package/src/posture/runtime-trace-ingest.js +194 -0
  193. package/src/posture/scan-checkpoint.js +38 -10
  194. package/src/posture/waf-ingest.js +7 -2
  195. package/src/report/index.js +4 -0
  196. package/src/report/oscal.js +38 -0
  197. package/src/report/perspectives.js +150 -0
  198. package/src/sast/_comment-strip.js +8 -1
  199. package/src/sast/ruby.js +26 -0
  200. package/src/sast/zip-slip.js +79 -0
  201. package/src/util/string-memo.js +38 -0
@@ -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 _redact_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(83468);
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 _lineage_deployment_projection_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(73596);
2938
- /* harmony import */ var _posture_provenance_schema_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(34594);
2939
- /* harmony import */ var _dataflow_tools_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(20095);
2940
- /* harmony import */ var _invariant_tools_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(82407);
2941
- /* harmony import */ var _portfolio_tools_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(99027);
2942
- /* harmony import */ var _posture_agents_memory_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(79907);
2943
- /* harmony import */ var _posture_cve_lookup_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(71364);
2944
- var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_report_index_js__WEBPACK_IMPORTED_MODULE_12__]);
2945
- _report_index_js__WEBPACK_IMPORTED_MODULE_12__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
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 __webpack_require__.e(/* import() */ 7838).then(__webpack_require__.bind(__webpack_require__, 27838))).verifyFix;
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,_redact_js__WEBPACK_IMPORTED_MODULE_19__/* .redactFinding */ .lE)({
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,_redact_js__WEBPACK_IMPORTED_MODULE_19__/* .redactFinding */ .lE)({
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,_redact_js__WEBPACK_IMPORTED_MODULE_19__/* .redactFinding */ .lE)({
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,_posture_provenance_schema_js__WEBPACK_IMPORTED_MODULE_15__/* .redactFindingProvenance */ .As)(f.findingProvenance, {
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,_lineage_deployment_projection_js__WEBPACK_IMPORTED_MODULE_14__/* .boundaryFields */ .Q)(f.boundaryContext)
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,_redact_js__WEBPACK_IMPORTED_MODULE_19__/* .redactString */ .rd)(out);
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
- if (process.env.AGENTIC_SECURITY_FIX_RUN_TESTS === '1') {
3830
- // Addition #7 — connect the closed-loop verifier: add the project test
3831
- // suite as a fourth verification leg (scan + lint + tests). Opt-in
3832
- // because many repos have no runner and we must not fail-closed by
3833
- // default. Normalized to the scan+lint verdict shape used below.
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
- let poc = null;
4067
- try {
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,_redact_js__WEBPACK_IMPORTED_MODULE_19__/* .redactString */ .rd)(r.lint.output || '').slice(0, 1500) },
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,_redact_js__WEBPACK_IMPORTED_MODULE_19__/* .redactString */ .rd)(r.poc.reason) : r.poc.reason } : r.poc,
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,_posture_agents_memory_js__WEBPACK_IMPORTED_MODULE_20__/* .appendAgentsMemory */ .eu)(ctx.sessionRoot, { agent, body });
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,_posture_agents_memory_js__WEBPACK_IMPORTED_MODULE_20__/* .readAgentsMemory */ .ox)(ctx.sessionRoot);
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,_redact_js__WEBPACK_IMPORTED_MODULE_19__/* .redactString */ .rd)(JSON.stringify(raw))); }
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,_redact_js__WEBPACK_IMPORTED_MODULE_19__/* .redactString */ .rd)(JSON.stringify(raw))); }
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,_posture_cve_lookup_js__WEBPACK_IMPORTED_MODULE_21__/* .lookupCve */ .x)(cve);
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,_invariant_tools_js__WEBPACK_IMPORTED_MODULE_17__/* .makeInvariantTools */ ._)({ confine: _confine, META });
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,_portfolio_tools_js__WEBPACK_IMPORTED_MODULE_18__/* .makePortfolioTools */ ._)({ confine: _confine, META });
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, _dataflow_tools_js__WEBPACK_IMPORTED_MODULE_16__/* .dataflow_get_graph */ .HX, _dataflow_tools_js__WEBPACK_IMPORTED_MODULE_16__/* .dataflow_get_node */ .HI, _dataflow_tools_js__WEBPACK_IMPORTED_MODULE_16__/* .dataflow_get_edge */ .gC, _dataflow_tools_js__WEBPACK_IMPORTED_MODULE_16__/* .dataflow_get_flow */ .ri, invariant_scenario_export, portfolio_progress];
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
+ };
@@ -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: