@clear-capabilities/agentic-security-scanner 0.161.0 → 0.162.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 +20 -0
- package/bin/agentic-security.js +11 -2
- package/dist/4113.index.js +59 -8
- package/dist/5613.index.js +500 -0
- package/dist/6239.index.js +469 -0
- package/dist/7838.index.js +38 -2
- package/dist/8798.index.js +1 -1
- package/dist/9207.index.js +5 -0
- package/dist/9560.index.js +36 -22
- package/dist/{1905.index.js → 9999.index.js} +265 -8
- package/dist/agentic-security.mjs +2 -2
- package/dist/agentic-security.mjs.sha256 +1 -1
- package/package.json +9 -4
- package/src/discovery/CLAUDE.md +9 -0
- package/src/discovery/index.js +28 -0
- package/src/discovery/memory.js +7 -5
- package/src/fix/apply-fix-service.js +33 -3
- package/src/mcp/CLAUDE.md +9 -1
- package/src/mcp/tools.js +17 -4
- package/src/posture/CLAUDE.md +174 -0
- package/src/posture/assurance/baseline-inventory.js +218 -0
- package/src/posture/assurance/baseline.js +322 -0
- package/src/posture/assurance/bounded-io.js +145 -0
- package/src/posture/assurance/config.js +299 -0
- package/src/posture/assurance/contracts.js +315 -0
- package/src/posture/assurance/identity.js +62 -0
- package/src/posture/assurance/migrations.js +259 -0
- package/src/posture/assurance/schema-kit.js +111 -0
- package/src/posture/assurance/verification-record.js +258 -0
- package/src/posture/attestation.js +5 -0
- package/src/posture/autopilot.js +28 -1
- package/src/posture/evidence-bundle.js +93 -7
- package/src/posture/execution-proof.js +11 -1
- package/src/posture/fix-verify-loop.js +20 -6
- package/src/posture/fix-verify.js +37 -2
- package/src/posture/oracles/adapters.js +360 -0
- package/src/posture/oracles/conformance.js +275 -0
- package/src/posture/oracles/oracle.js +433 -0
- package/src/posture/oracles/registry.js +76 -0
- package/src/posture/oracles/scenario-classes.js +223 -0
- package/src/posture/replay/replay.js +249 -0
- package/src/posture/verification/advisory-state.js +71 -0
- package/src/posture/verification/emit.js +257 -0
- package/src/posture/verification/hypothesis-promotion.js +211 -0
- package/src/posture/verification/patch-negative.js +214 -0
- package/src/posture/verification/patch-promotion.js +105 -0
- package/src/posture/verification/projection.js +183 -0
- package/src/posture/verification/repair-records.js +124 -0
- package/src/posture/verifier.js +16 -0
- package/src/report/index.js +49 -0
- package/src/sandbox/CLAUDE.md +41 -0
- package/src/sandbox/backend-namespace.js +7 -0
- package/src/sandbox/backend-userspace.js +68 -29
- package/src/sandbox/control-probes.js +215 -0
- package/src/sandbox/supervise.js +201 -0
- package/src/sandbox/trust-boundary.js +113 -0
- package/src/sandbox/trust-domains.js +171 -0
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,26 @@
|
|
|
9
9
|
> make the history less accurate, not more.
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
## 0.162.0 - first slice of the differentiation programme: versioned evidence contracts, an enforced trust boundary, one verification record, trusted oracles, patch-negative verification, and a conformance gate
|
|
13
|
+
|
|
14
|
+
This is the foundation and verification slice of the Agentic Security Differentiation PRD (CORE-001 to 004, CORE-003 trust boundary, LOOP-001, X-201 to X-208). It is **not** the whole programme: the evaluation work (QA-001 to 008, which holds the accuracy gates), the deployment graph, tenant invariants, capability enforcement, model routing and portfolio assurance are unstarted, and no accuracy number is claimed or changed by this release. The new capabilities that execute anything are off by default.
|
|
15
|
+
|
|
16
|
+
**Evidence contracts (CORE-001, 002).** Versioned schemas, validators, stable identities and legacy migration adapters for verification records, observation bindings, capability decisions, routing labels and release evidence. A model verdict can only ever be an inference: `confirmed` needs trusted runtime proof or independent adjudication, and the six states (not-run, unsupported, inconclusive, error, refuted, confirmed) stay distinct through every round trip. A baseline capture tool (`npm run baseline:capture`) records source and bundle digests, dirty paths and an inventory of 18 existing capabilities, each checked against real paths and symbols; it invalidates only the capabilities whose files changed and never modifies source.
|
|
17
|
+
|
|
18
|
+
**Trust boundary (CORE-003).** Four trust domains (target, worker, verifier, signer) with a default-deny policy. `runInBoundary` runs a target only after active probes prove the controls it needs, and returns `blocked` (target never run) otherwise; target output is untrusted and never sets a status. Process trees are killed on timeout or cancel, with a descendant sweep and an orphan check. Signed evidence bundles now carry an `issuance` block that labels them `self-issued-local-key`, never independently certified. **Compatibility:** bundles signed before this release still verify and report no declared trust basis, but a verifier older than this release rejects newly signed bundles (strict unknown-key rule).
|
|
19
|
+
|
|
20
|
+
**One verification record, oracles, replay (X-201 to X-203).** Every verification surface emits the same record. Seven oracle adapters (injection execution, authorization decision, state transition, side-effect reachability, parser/resource behaviour, replay/idempotency, functional regression) each have positive, negative and inconclusive fixtures; an unavailable prerequisite is `unsupported`, never a pass. Replay manifests pin commit, patch, fixture, toolchain, oracle and budgets and reject any that fail validation.
|
|
21
|
+
|
|
22
|
+
**Patch-negative verification and non-taint classes (X-204, X-205).** A fix reaches `verified-fix` only with an exploit-positive original, an exploit-negative patched revision and a passing functional check; the specific incomplete step is recorded otherwise, and promotion requires receipts bound to the exact diff and revision. Tenant authorization, privileged action, workflow order, replay/idempotency and bounded resource exhaustion have executable oracles; taint absence never refutes them.
|
|
23
|
+
|
|
24
|
+
**Parity, gating and conformance (X-206 to X-208).** CLI JSON, MCP, reports and the autopilot response now share one projection (`verificationView`, additive; previous output fields are pinned by fixtures; migration notes in `docs/guides/verification-schema-migration.md`). Advisory hunt hypotheses cannot touch authoritative scan state and are promoted only with a verified receipt and an explicit policy, never on confidence or model agreement. A conformance suite over all oracle adapters runs as a new release check (`verification-conformance-gate`).
|
|
25
|
+
|
|
26
|
+
**Loop registration (LOOP-001).** `assurance-differentiation` profile for the supervised controller: the unmodified importer parses all 70 requirements, 269 weight and 210 criteria. Preflight on the real profile refuses launch, by design, until the other suites have runnable wrappers. Several limits the PRD names (heartbeat setting, subprocess wall time, network limits, provider envelope) are not enforced by the controller and are listed as unenforced.
|
|
27
|
+
|
|
28
|
+
**Known issue, not fixed here (present since at least 0.161.0).** The taint engine reports a regular expression's `.exec()` called on request data as a high-severity command injection (`child_process.exec`), for example `SEMVER.exec(req.query.v)`. This is a false positive that will appear in ordinary JavaScript. Fixing the sink model touches the corpus and recall gates, so it is left for its own change. The self-scan baseline records the two such findings in this repository as reviewed false positives.
|
|
29
|
+
|
|
30
|
+
**Not verified here.** Everything that executes targets was exercised on macOS only; Linux enforcement is declared unverified in every manifest, and on a host where the boundary cannot run the conformance gate reports execution as not-run, never passed. Receipts are unsigned and valid only within the verifier's process. The patch-negative ledger and the promotion audit record are returned, not persisted.
|
|
31
|
+
|
|
12
32
|
## 0.161.0 - the first honest out-of-sample numbers, a ReDoS in the scanner itself fixed, large Haskell projects now finish, multi-file fixes over MCP, auth-guard order proved structurally, sturdier tests and a sharded CI
|
|
13
33
|
|
|
14
34
|
**Measured, and not flattering.** The unseen shape set the engine had been tuned against (v2) was retired and a fresh one (v3: 13 Haskell and 12 Nix families, 300 cases, written without reading the engine's rules) was measured exactly once, with nothing tuned afterwards. On it: Haskell SAST precision 75.0% / recall 50.0% / F1 60.0% (24 TP, 8 FP, 24 FN); Haskell taint 84.6% / 73.3% / 78.6%; Nix config-SAST 100% / 87.9% / 93.5%; Nix config-taint precision 60.0% (all four false positives are duplicate findings on scripts the new set's author wrote with two sinks each, an authoring artefact, not an engine fault). The previous set had scored the Haskell rows 91.7% and 93.3% after being tuned against. All four generalization rows are now below target and the published support tables say so. The misses are concrete and listed in `docs/language-support.md` (for example session cookies set without Secure, missing ownership checks in Yesod and Servant handlers, `randomIO` as a CSRF token, `printf` logging a secret, some HDBC, Scotty `file` and `Network.HTTP.Req` shapes). Closing them is a tuning round that consumes this set; it was deliberately not done here, so the numbers stand as measured. The retired set is kept as a development set (`shape-dev-2`), which now scores 96% to 100%: that is a tuned-on set and is not a generalization number.
|
package/bin/agentic-security.js
CHANGED
|
@@ -2290,7 +2290,7 @@ async function cmdVerify(args) {
|
|
|
2290
2290
|
process.env.AGENTIC_SECURITY_VERIFY_LIVE = '1';
|
|
2291
2291
|
process.env.AGENTIC_SECURITY_VERIFY_TARGET = targetFlag;
|
|
2292
2292
|
}
|
|
2293
|
-
const { annotateVerifierVerdicts, verifierCoverageSummary, recordVerifierRun } = await import('../src/posture/verifier.js');
|
|
2293
|
+
const { annotateVerifierVerdicts, verifierCoverageSummary, recordVerifierRun, verifierVerificationRecords } = await import('../src/posture/verifier.js');
|
|
2294
2294
|
const filter = args.flags.finding ? findings.filter(f => f.id === args.flags.finding || f.stableId === args.flags.finding) : findings;
|
|
2295
2295
|
if (!filter.length) {
|
|
2296
2296
|
console.error(`No matching findings (use --finding <id>).`);
|
|
@@ -2319,7 +2319,13 @@ async function cmdVerify(args) {
|
|
|
2319
2319
|
// Adversarial premortem Q1: a durable record that a security assessment of
|
|
2320
2320
|
// findings actually happened, so module:verifier has something real to
|
|
2321
2321
|
// point at (see verifier.js's recordVerifierRun header comment).
|
|
2322
|
-
|
|
2322
|
+
// X-201: one version-1 verification record per verified finding, in the durable run record (never on the findings,
|
|
2323
|
+
// which are written back to last-scan.json below).
|
|
2324
|
+
const { headCommit } = await import('../src/posture/verification/emit.js');
|
|
2325
|
+
recordVerifierRun(scanRoot, {
|
|
2326
|
+
findingCount: filter.length, live: liveFlag, target: targetFlag || null, summary: sum,
|
|
2327
|
+
verificationRecords: verifierVerificationRecords(filter, { commit: headCommit(scanRoot) }),
|
|
2328
|
+
});
|
|
2323
2329
|
if (args.flags.verbose || args.flags.finding) {
|
|
2324
2330
|
for (const f of filter) {
|
|
2325
2331
|
console.log(` ${f.file}:${f.line} ${f.vuln}`);
|
|
@@ -3289,6 +3295,9 @@ async function cmdVerifyAttestation(args) {
|
|
|
3289
3295
|
console.log('');
|
|
3290
3296
|
console.log(` proves: ${bundle.proves}`);
|
|
3291
3297
|
console.log(` does NOT prove: ${bundle.doesNotProve}`);
|
|
3298
|
+
// CORE-003.AC03: who vouches. Informational only; the exit code is unchanged.
|
|
3299
|
+
console.log(` trust basis: ${r.trustBasis}${r.issuer ? ` (issuer ${r.issuer.id})` : ''}`);
|
|
3300
|
+
console.log(` ${r.trustNote}`);
|
|
3292
3301
|
return 0;
|
|
3293
3302
|
}
|
|
3294
3303
|
|
package/dist/4113.index.js
CHANGED
|
@@ -531,6 +531,7 @@ __webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependen
|
|
|
531
531
|
/* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(73024);
|
|
532
532
|
/* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(76760);
|
|
533
533
|
/* harmony import */ var _fix_verify_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(27838);
|
|
534
|
+
/* harmony import */ var _verification_emit_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(85578);
|
|
534
535
|
var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_fix_verify_js__WEBPACK_IMPORTED_MODULE_3__]);
|
|
535
536
|
_fix_verify_js__WEBPACK_IMPORTED_MODULE_3__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
|
|
536
537
|
// Closed-loop fix verification (v0.68).
|
|
@@ -559,6 +560,7 @@ _fix_verify_js__WEBPACK_IMPORTED_MODULE_3__ = (__webpack_async_dependencies__.th
|
|
|
559
560
|
|
|
560
561
|
|
|
561
562
|
|
|
563
|
+
|
|
562
564
|
const DEFAULT_TIMEOUT_MS = 120_000;
|
|
563
565
|
|
|
564
566
|
// Test-runner discovery. Each entry: a sentinel-file check + a command +
|
|
@@ -666,20 +668,32 @@ async function verifyFixWithTests({
|
|
|
666
668
|
runTests = true,
|
|
667
669
|
testRunnerOverride,
|
|
668
670
|
testTimeoutMs,
|
|
671
|
+
patchNegative,
|
|
672
|
+
assuranceConfig,
|
|
669
673
|
} = {}) {
|
|
670
|
-
const scanLint = await (0,_fix_verify_js__WEBPACK_IMPORTED_MODULE_3__.verifyFix)({ scanRoot, originalFindingStableId, files, depFileContents });
|
|
674
|
+
const scanLint = await (0,_fix_verify_js__WEBPACK_IMPORTED_MODULE_3__.verifyFix)({ scanRoot, originalFindingStableId, files, depFileContents, patchNegative, assuranceConfig });
|
|
671
675
|
const legs = {
|
|
672
676
|
scan: { ok: scanLint.rescan?.ok ?? scanLint.ok, detail: scanLint.rescan ?? scanLint },
|
|
673
677
|
lint: { ok: scanLint.lint?.ok ?? true, detail: scanLint.lint ?? null },
|
|
674
678
|
tests: { ok: true, detail: null, skipped: true, reason: 'not-run' },
|
|
675
679
|
};
|
|
676
|
-
|
|
677
|
-
|
|
680
|
+
// X-201: the closed loop's own record (additive). It runs the detector, linter and project tests, never an exploit
|
|
681
|
+
// oracle, so it can say `not-run` or `error` and nothing stronger.
|
|
682
|
+
const withRecord = (res) => {
|
|
683
|
+
const e = (0,_verification_emit_js__WEBPACK_IMPORTED_MODULE_4__/* .emitVerification */ .T)('fix-verify-loop', res, { originalFindingStableId, files, scanRoot });
|
|
684
|
+
return { ...res, verificationRecord: e.ok ? e.record : null };
|
|
685
|
+
};
|
|
686
|
+
// X-204: the patch-negative leg is present only when it was requested and its feature is on. A patch the oracle did not verify
|
|
687
|
+
// is never `verified-clean`, whatever the other legs say.
|
|
688
|
+
const pn = scanLint.patchNegative && scanLint.patchNegative.status !== 'disabled' ? scanLint.patchNegative : null;
|
|
689
|
+
if (pn) legs.patchNegative = { ok: pn.verifiedFix === true, detail: { status: pn.status, incompleteStep: pn.incompleteStep, failureCode: pn.failureCode, reason: pn.reason } };
|
|
690
|
+
if (!legs.scan.ok || !legs.lint.ok || (pn && !legs.patchNegative.ok)) {
|
|
691
|
+
return withRecord({
|
|
678
692
|
ok: false,
|
|
679
693
|
verdict: 'verification-failed',
|
|
680
694
|
legs,
|
|
681
695
|
summary: _summarize(legs, 'verification-failed'),
|
|
682
|
-
};
|
|
696
|
+
});
|
|
683
697
|
}
|
|
684
698
|
if (runTests) {
|
|
685
699
|
const tests = runProjectTests(scanRoot, { runnerOverride: testRunnerOverride, timeoutMs: testTimeoutMs });
|
|
@@ -688,8 +702,8 @@ async function verifyFixWithTests({
|
|
|
688
702
|
const allOk = legs.scan.ok && legs.lint.ok && legs.tests.ok;
|
|
689
703
|
const verdict = !allOk
|
|
690
704
|
? 'verification-failed'
|
|
691
|
-
: (legs.tests.skipped ? 'untested-but-passes' : 'verified-clean');
|
|
692
|
-
return { ok: allOk, verdict, legs, summary: _summarize(legs, verdict) };
|
|
705
|
+
: pn ? 'verified-fix' : (legs.tests.skipped ? 'untested-but-passes' : 'verified-clean');
|
|
706
|
+
return withRecord({ ok: allOk, verdict, legs, summary: _summarize(legs, verdict) });
|
|
693
707
|
}
|
|
694
708
|
|
|
695
709
|
function _summarize(legs, verdict) {
|
|
@@ -697,6 +711,7 @@ function _summarize(legs, verdict) {
|
|
|
697
711
|
bits.push(`scan: ${legs.scan.ok ? 'pass' : 'fail'}`);
|
|
698
712
|
bits.push(`lint: ${legs.lint.skipped ? 'skip' : legs.lint.ok ? 'pass' : 'fail'}`);
|
|
699
713
|
bits.push(`tests: ${legs.tests.skipped ? 'skip' : legs.tests.ok ? 'pass' : 'fail'}`);
|
|
714
|
+
if (legs.patchNegative) bits.push(`patch-negative: ${legs.patchNegative.ok ? 'pass' : `fail (${legs.patchNegative.detail.incompleteStep})`}`);
|
|
700
715
|
return `${verdict} (${bits.join(' · ')})`;
|
|
701
716
|
}
|
|
702
717
|
|
|
@@ -722,6 +737,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
722
737
|
/* harmony import */ var _fix_honesty_gate_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(27785);
|
|
723
738
|
/* harmony import */ var _test_runner_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(35136);
|
|
724
739
|
/* harmony import */ var _fix_metrics_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(32238);
|
|
740
|
+
/* harmony import */ var _verification_emit_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(85578);
|
|
725
741
|
var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_engine_js__WEBPACK_IMPORTED_MODULE_3__]);
|
|
726
742
|
_engine_js__WEBPACK_IMPORTED_MODULE_3__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
|
|
727
743
|
// Closed-loop /fix verification (Sentinel-parity FR-L4-4, FR-L4-5).
|
|
@@ -749,6 +765,7 @@ _engine_js__WEBPACK_IMPORTED_MODULE_3__ = (__webpack_async_dependencies__.then ?
|
|
|
749
765
|
|
|
750
766
|
|
|
751
767
|
|
|
768
|
+
|
|
752
769
|
const SEVERITY_RANK = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };
|
|
753
770
|
|
|
754
771
|
// Run a focused re-scan over just the patched file(s) using the in-memory
|
|
@@ -913,6 +930,8 @@ async function verifyFix({
|
|
|
913
930
|
testTimeoutMs,
|
|
914
931
|
recordMetrics = true,
|
|
915
932
|
poc,
|
|
933
|
+
patchNegative,
|
|
934
|
+
assuranceConfig,
|
|
916
935
|
} = {}) {
|
|
917
936
|
// R5 (reporting half) — time each stage as it runs. Measured here rather
|
|
918
937
|
// than inside each stage because only this function knows the boundaries of
|
|
@@ -995,7 +1014,26 @@ async function verifyFix({
|
|
|
995
1014
|
}
|
|
996
1015
|
_lap('honesty');
|
|
997
1016
|
|
|
998
|
-
|
|
1017
|
+
// X-204: patch-negative verification, only when the caller asked for it AND the `patch-negative-verification` feature is
|
|
1018
|
+
// on. `patchNegative` is the requester's exploit scenario and functional cases ({ original, functional, commit?, ... }); the
|
|
1019
|
+
// candidate `files` are the proposed diff. With the flag off, or no request, nothing here runs and every field below is
|
|
1020
|
+
// exactly what it was before.
|
|
1021
|
+
let pn = null;
|
|
1022
|
+
if (patchNegative && typeof patchNegative === 'object') {
|
|
1023
|
+
try {
|
|
1024
|
+
const { verifyPatchNegative } = await Promise.all(/* import() */[__webpack_require__.e(6239), __webpack_require__.e(5613)]).then(__webpack_require__.bind(__webpack_require__, 95613));
|
|
1025
|
+
pn = await verifyPatchNegative({
|
|
1026
|
+
hypothesisId: originalFindingStableId, ...patchNegative, patch: { files },
|
|
1027
|
+
commit: patchNegative.commit ?? (0,_verification_emit_js__WEBPACK_IMPORTED_MODULE_7__.headCommit)(scanRoot),
|
|
1028
|
+
}, { config: assuranceConfig });
|
|
1029
|
+
} catch (e) {
|
|
1030
|
+
pn = { status: 'error', verifiedFix: false, incompleteStep: 'patch-negative', failureCode: 'harness-error', reason: `patch-negative verification failed to run: ${String(e?.message || e).slice(0, 200)}`, summary: '' };
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
const pnActive = pn !== null && pn.status !== 'disabled';
|
|
1034
|
+
_lap('patchNegative');
|
|
1035
|
+
|
|
1036
|
+
const ok = rescan.ok && (lint.ok || lint.skipped) && testsOk && pocOk && (honesty ? honesty.ok : true) && (pnActive ? pn.verifiedFix === true : true);
|
|
999
1037
|
|
|
1000
1038
|
// FR-305 (assurance-hardening PRD): `ok` alone conflates "every leg
|
|
1001
1039
|
// genuinely ran and passed" with "passed, but a required leg was skipped
|
|
@@ -1037,6 +1075,7 @@ async function verifyFix({
|
|
|
1037
1075
|
: pocLeg.status === 'no-longer-proven' ? 'poc: PASS (ran against the patch and no longer demonstrates the vulnerability)'
|
|
1038
1076
|
: `poc: inconclusive — not counted either way (${pocLeg.reason || 'no detail reported'})`,
|
|
1039
1077
|
// FR-305: never let a degraded pass read the same as a full one.
|
|
1078
|
+
pnActive ? `patch-negative: ${pn.verifiedFix ? 'PASS (verified-fix)' : `FAIL - not verified-fix, incomplete step '${pn.incompleteStep}' (${pn.failureCode}): ${pn.reason}`}` : null,
|
|
1040
1079
|
ok && !verifiedFull ? `NOTE: PASSED, but NOT fully verified — ${degradedLegs.join('; ')}` : null,
|
|
1041
1080
|
].filter(Boolean).join('\n');
|
|
1042
1081
|
// Persist the attempt so the distribution can be reported from real runs.
|
|
@@ -1063,7 +1102,19 @@ async function verifyFix({
|
|
|
1063
1102
|
});
|
|
1064
1103
|
}
|
|
1065
1104
|
|
|
1066
|
-
|
|
1105
|
+
// X-201: the one verification record, ADDITIVE. `ok` and every field above stay exactly as they were; the record
|
|
1106
|
+
// says what was actually established (a static re-scan is not an exploit oracle, so without a PoC leg it is
|
|
1107
|
+
// `not-run`, and nothing here can reach `confirmed`/`refuted`: that takes a trusted oracle adapter).
|
|
1108
|
+
const emitted = (0,_verification_emit_js__WEBPACK_IMPORTED_MODULE_7__/* .emitVerification */ .T)('fix-verify', { rescan, lint, tests, poc: pocLeg }, {
|
|
1109
|
+
originalFindingStableId, files, scanRoot, finding: poc?.finding,
|
|
1110
|
+
});
|
|
1111
|
+
const verificationRecord = emitted.ok ? emitted.record : null;
|
|
1112
|
+
|
|
1113
|
+
return {
|
|
1114
|
+
ok, verifiedFull, degradedLegs, rescan, lint, tests, testedPrePatch: _testedPrePatch, honesty, poc: pocLeg, durations, summary, verificationRecord,
|
|
1115
|
+
// additive, present only when patch-negative verification was requested (X-204)
|
|
1116
|
+
...(pn ? { patchNegative: pn, ...(pnActive ? { fixStatus: pn.verifiedFix ? 'verified-fix' : 'not-verified-fix' } : {}) } : {}),
|
|
1117
|
+
};
|
|
1067
1118
|
}
|
|
1068
1119
|
|
|
1069
1120
|
__webpack_async_result__();
|