@clear-capabilities/agentic-security-scanner 0.145.0 → 0.147.5
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 +266 -0
- package/bin/agentic-security.js +3508 -69
- package/dist/1122.index.js +779 -0
- package/dist/{301.index.js → 1301.index.js} +2 -2
- package/dist/1379.index.js +591 -0
- package/dist/{444.index.js → 1444.index.js} +2 -2
- package/dist/{660.index.js → 1660.index.js} +2 -2
- package/dist/{700.index.js → 1700.index.js} +2 -2
- package/dist/{905.index.js → 1905.index.js} +3 -3
- package/dist/{920.index.js → 1920.index.js} +3 -3
- package/dist/{238.index.js → 2238.index.js} +3 -3
- package/dist/{271.index.js → 2271.index.js} +2 -2
- package/dist/{985.index.js → 2376.index.js} +1260 -340
- package/dist/2432.index.js +793 -0
- package/dist/2659.index.js +93 -0
- package/dist/{826.index.js → 2826.index.js} +2 -2
- package/dist/{830.index.js → 2830.index.js} +2 -2
- package/dist/2923.index.js +298 -0
- package/dist/{1.index.js → 3001.index.js} +5 -5
- package/dist/{117.index.js → 3117.index.js} +3 -3
- package/dist/3180.index.js +379 -0
- package/dist/3276.index.js +117 -0
- package/dist/{415.index.js → 3415.index.js} +2 -2
- package/dist/{499.index.js → 3499.index.js} +2 -2
- package/dist/3518.index.js +450 -0
- package/dist/{526.index.js → 3526.index.js} +5 -5
- package/dist/{736.index.js → 3736.index.js} +4 -4
- package/dist/{839.index.js → 3839.index.js} +4 -4
- package/dist/{113.index.js → 4113.index.js} +5 -5
- package/dist/{265.index.js → 4265.index.js} +2 -2
- package/dist/{384.index.js → 4384.index.js} +3 -3
- package/dist/4547.index.js +268 -0
- package/dist/4863.index.js +422 -0
- package/dist/{970.index.js → 4970.index.js} +2 -2
- package/dist/5051.index.js +841 -0
- package/dist/{144.index.js → 5144.index.js} +5 -5
- package/dist/{333.index.js → 5333.index.js} +3 -3
- package/dist/5343.index.js +185 -0
- package/dist/5350.index.js +866 -0
- package/dist/5561.index.js +436 -0
- package/dist/{637.index.js → 5637.index.js} +3 -3
- package/dist/{449.index.js → 5830.index.js} +2 -2
- package/dist/6626.index.js +532 -0
- package/dist/6662.index.js +297 -0
- package/dist/{675.index.js → 6675.index.js} +5 -5
- package/dist/{730.index.js → 6730.index.js} +6 -6
- package/dist/6829.index.js +225 -0
- package/dist/6944.index.js +130 -0
- package/dist/{178.index.js → 7178.index.js} +3 -3
- package/dist/{227.index.js → 7227.index.js} +2 -2
- package/dist/7310.index.js +520 -0
- package/dist/{552.index.js → 7552.index.js} +4 -4
- package/dist/7709.index.js +78 -0
- package/dist/8218.index.js +160 -0
- package/dist/{476.index.js → 8476.index.js} +4 -4
- package/dist/{513.index.js → 8513.index.js} +5 -5
- package/dist/{520.index.js → 8520.index.js} +2 -2
- package/dist/{718.index.js → 8718.index.js} +2 -2
- package/dist/{752.index.js → 8752.index.js} +2 -2
- package/dist/8846.index.js +100 -0
- package/dist/{435.index.js → 9091.index.js} +560 -189
- package/dist/{207.index.js → 9207.index.js} +2 -2
- package/dist/{220.index.js → 9220.index.js} +2 -2
- package/dist/9390.index.js +163 -0
- package/dist/{503.index.js → 9503.index.js} +2 -2
- package/dist/{801.index.js → 9801.index.js} +2 -2
- package/dist/{824.index.js → 9824.index.js} +2 -2
- package/dist/agentic-security.mjs +16 -16
- package/dist/agentic-security.mjs.sha256 +1 -1
- package/dist/compliance-frameworks/hipaa-security-rule.json +3 -2
- package/dist/frontend/index.html +21 -0
- package/dist/frontend/src/app.js +176 -0
- package/dist/frontend/src/components/evidence-inspector.js +141 -0
- package/dist/frontend/src/components/filter-rail.js +119 -0
- package/dist/frontend/src/components/query-bar.js +126 -0
- package/dist/frontend/src/data/flagship-graph.js +1460 -0
- package/dist/frontend/src/export-entry.js +36 -0
- package/dist/frontend/src/lib/api-client.js +92 -0
- package/dist/frontend/src/lib/contrast.js +34 -0
- package/dist/frontend/src/lib/dom.js +24 -0
- package/dist/frontend/src/lib/escape-html.js +16 -0
- package/dist/frontend/src/lib/flow-path.js +40 -0
- package/dist/frontend/src/lib/focus-controls.js +149 -0
- package/dist/frontend/src/lib/protection-visual.js +46 -0
- package/dist/frontend/src/lib/query-language.js +240 -0
- package/dist/frontend/src/lib/row-filters.js +43 -0
- package/dist/frontend/src/lib/state.js +84 -0
- package/dist/frontend/src/main.js +83 -0
- package/dist/frontend/src/shell.js +184 -0
- package/dist/frontend/src/views/architecture-view.js +798 -0
- package/dist/frontend/src/views/inventory-view.js +292 -0
- package/dist/frontend/src/views/privacy-view.js +172 -0
- package/dist/frontend/src/views/trace-view.js +206 -0
- package/dist/frontend/styles/architecture-view.css +93 -0
- package/dist/frontend/styles/filter-rail.css +34 -0
- package/dist/frontend/styles/inspector.css +69 -0
- package/dist/frontend/styles/inventory-view.css +74 -0
- package/dist/frontend/styles/privacy-view.css +86 -0
- package/dist/frontend/styles/query-bar.css +107 -0
- package/dist/frontend/styles/shell.css +155 -0
- package/dist/frontend/styles/tokens.css +128 -0
- package/dist/frontend/styles/trace-view.css +95 -0
- package/package.json +13 -6
- package/src/dataflow/CLAUDE.md +1 -1
- package/src/dataflow/catalog.js +42 -0
- package/src/dataflow/orm-write-catalog.js +175 -0
- package/src/engine.js +92 -1
- package/src/ir/CLAUDE.md +1 -0
- package/src/ir/chrome-probe.mjs +150 -0
- package/src/ir/parser-js.js +94 -7
- package/src/lineage/CLAUDE.md +1203 -0
- package/src/lineage/DESIGN_DESTINATION_RESOLVER.md +156 -0
- package/src/lineage/DESIGN_GRAPH_BUILDER.md +938 -0
- package/src/lineage/DESIGN_HANDLING_ANALYZER.md +355 -0
- package/src/lineage/DESIGN_INTRAPROCEDURAL.md +628 -0
- package/src/lineage/DESIGN_PATH_PROVENANCE.md +3451 -0
- package/src/lineage/DESIGN_QUEUE_DETAIL.md +120 -0
- package/src/lineage/DESIGN_REGISTRIES.md +880 -0
- package/src/lineage/DESIGN_STORE_DETAIL.md +143 -0
- package/src/lineage/DESIGN_TRANSIT_PROTECTION.md +245 -0
- package/src/lineage/classification.js +56 -0
- package/src/lineage/coverage.js +658 -0
- package/src/lineage/cross-repo-link.js +107 -0
- package/src/lineage/dataflow-graph.schema.json +184 -0
- package/src/lineage/decision-story.js +206 -0
- package/src/lineage/drift-policy.js +279 -0
- package/src/lineage/driver.js +135 -0
- package/src/lineage/engine.js +992 -0
- package/src/lineage/export-briefing.js +628 -0
- package/src/lineage/export-csv.js +62 -0
- package/src/lineage/export-json.js +238 -0
- package/src/lineage/export-privacy.js +258 -0
- package/src/lineage/federation-loader.js +111 -0
- package/src/lineage/field-identity.js +78 -0
- package/src/lineage/fixtures/build-flagship-fixture.mjs +272 -0
- package/src/lineage/fixtures/flagship-graph.json +1453 -0
- package/src/lineage/flow-grade.js +221 -0
- package/src/lineage/governance-edit.js +169 -0
- package/src/lineage/graph-builder.js +1114 -0
- package/src/lineage/graph-diff.js +431 -0
- package/src/lineage/graph-snapshot.js +180 -0
- package/src/lineage/handling-analyzer.js +168 -0
- package/src/lineage/ids.js +349 -0
- package/src/lineage/impact-assessment.js +76 -0
- package/src/lineage/impact-engine.js +268 -0
- package/src/lineage/index.js +281 -0
- package/src/lineage/language-coverage-tiers.js +58 -0
- package/src/lineage/obligation-mapping.js +126 -0
- package/src/lineage/obligation-predicates.js +235 -0
- package/src/lineage/observation-adapters.js +282 -0
- package/src/lineage/observation-correlation.js +622 -0
- package/src/lineage/observation-store.js +497 -0
- package/src/lineage/path-query.js +410 -0
- package/src/lineage/path-store.js +400 -0
- package/src/lineage/protection.js +53 -0
- package/src/lineage/recipient-profile.js +192 -0
- package/src/lineage/recipient-registry.js +394 -0
- package/src/lineage/redact-graph.js +224 -0
- package/src/lineage/remediation.js +417 -0
- package/src/lineage/resolve-destination.js +91 -0
- package/src/lineage/runtime-observation.js +464 -0
- package/src/lineage/scenario-diff.js +84 -0
- package/src/lineage/scenario-engine.js +251 -0
- package/src/lineage/scenario.js +101 -0
- package/src/lineage/schema.js +167 -0
- package/src/lineage/sink-registry.js +427 -0
- package/src/lineage/source-registry.js +357 -0
- package/src/lineage/source-seeding.js +212 -0
- package/src/lineage/summaries.js +590 -0
- package/src/lineage/transform-catalog.js +397 -0
- package/src/lineage/transit-protection.js +150 -0
- package/src/lineage/validate.js +285 -0
- package/src/mcp/CLAUDE.md +7 -1
- package/src/mcp/dataflow-tools.js +160 -0
- package/src/mcp/server.js +1 -1
- package/src/mcp/tools.js +2 -1
- package/src/pipeline/scan-health.js +19 -1
- package/src/posture/CLAUDE.md +19 -0
- package/src/posture/artifact-registry.js +52 -0
- package/src/posture/auditor-walkthrough.js +76 -0
- package/src/posture/compliance-frameworks/hipaa-security-rule.json +3 -2
- package/src/posture/obligation-evidence-pack.js +202 -0
- package/src/posture/remediation-ledger.js +337 -0
- package/src/server/CLAUDE.md +47 -0
- package/src/server/graph-loader.js +141 -0
- package/src/server/http-server.js +325 -0
- package/src/server/routes.js +129 -0
- package/src/server/security.js +111 -0
- package/src/server/static-assets.js +144 -0
- package/src/shared/frontend-root.js +52 -0
- package/dist/11.index.js +0 -353
- package/dist/259.index.js +0 -975
- package/dist/317.index.js +0 -300
- package/dist/609.index.js +0 -741
- package/dist/838.index.js +0 -152
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
export const id = 3518;
|
|
2
|
+
export const ids = [3518];
|
|
3
|
+
export const modules = {
|
|
4
|
+
|
|
5
|
+
/***/ 3518:
|
|
6
|
+
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
|
7
|
+
|
|
8
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
9
|
+
/* harmony export */ computeGraphDiff: () => (/* binding */ computeGraphDiff)
|
|
10
|
+
/* harmony export */ });
|
|
11
|
+
/* unused harmony exports WATCHED_FLOW_FIELDS, validateGraphDiff */
|
|
12
|
+
/* harmony import */ var _graph_snapshot_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(373);
|
|
13
|
+
/* harmony import */ var _ids_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5034);
|
|
14
|
+
/* harmony import */ var _dataflow_privacy_governance_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3308);
|
|
15
|
+
// graph-diff.js — M4 deliverable #9 (FR-503 §14, DFG-022), sub-project
|
|
16
|
+
// 8b, Task 1: the GraphDiff extension contract + computeGraphDiff + honest
|
|
17
|
+
// change-cause classification.
|
|
18
|
+
//
|
|
19
|
+
// Mirrors graph-snapshot.js's/obligation-mapping.js's/decision-story.js's
|
|
20
|
+
// own shape exactly: a record is explicitly NOT a DataFlowGraph v1 entity
|
|
21
|
+
// (§10.10 — "associated with, but not required inside, the immutable base
|
|
22
|
+
// graph"), never added to dataflow-graph.schema.json, never routed
|
|
23
|
+
// through validate.js's validateGraph(). See ids.js's diffId() for the id
|
|
24
|
+
// scheme.
|
|
25
|
+
//
|
|
26
|
+
// This module ONLY computes a diff between two already-persisted
|
|
27
|
+
// GraphSnapshot records and classifies why each removed flow disappeared,
|
|
28
|
+
// as far as real, checkable signals allow. It does NOT decide what a
|
|
29
|
+
// caller should DO with a GraphDiff (no CLI, no drift-policy matching —
|
|
30
|
+
// see this sub-project's own task brief: those are Tasks 2/3).
|
|
31
|
+
//
|
|
32
|
+
// ── Design judgment calls made in this file (disclosed, not hidden) ──
|
|
33
|
+
//
|
|
34
|
+
// 1. WATCHED_FLOW_FIELDS includes `governanceRefs`, not just the four
|
|
35
|
+
// scalar fields the task brief names literally
|
|
36
|
+
// (protectionSummary/policyVerdict/handling/coverageStatus). Read
|
|
37
|
+
// directly against dataflow-graph.schema.json's own flow $def (§145 of
|
|
38
|
+
// that file) and graph-builder.js's real flow-construction loop:
|
|
39
|
+
// `flow.governanceRefs` is a real, populated field (coverage.js's
|
|
40
|
+
// `resolveGovernanceRefs` default, keyed by
|
|
41
|
+
// dataflow/privacy-governance.js's own GOVERNANCE_FIELDS —
|
|
42
|
+
// purpose/lawfulBasis/subject/retention/residency/recipient/transfer/
|
|
43
|
+
// minimization/consent/access/deletion), never a fabricated shape. A
|
|
44
|
+
// "retention/deletion or lawful-basis change" — AC-27's own bullet
|
|
45
|
+
// list — can ONLY show up as a governanceRefs difference, since none
|
|
46
|
+
// of the other four watched fields carry that information at all. The
|
|
47
|
+
// diff compares it value-by-value over GOVERNANCE_FIELDS (never a
|
|
48
|
+
// bare object-identity/JSON-string check), emitting one changed-field
|
|
49
|
+
// entry per differing governance field (`governanceRefs.<field>`), so
|
|
50
|
+
// a caller learns WHICH governance fact changed, not just "something
|
|
51
|
+
// in governance changed."
|
|
52
|
+
//
|
|
53
|
+
// 2. Non-flow removed entities (nodes/edges/dataElements) always get
|
|
54
|
+
// causeClassification: 'application_change'. The task brief's Global
|
|
55
|
+
// Constraint says the coverage-regression check applies "per removed
|
|
56
|
+
// flow entry ONLY" — read literally, that leaves open what a removed
|
|
57
|
+
// node/edge/dataElement gets. The same reasoning the brief gives for
|
|
58
|
+
// added/changed entries applies here too ("no other real signal
|
|
59
|
+
// exists... do not invent one") — a removed node/edge/dataElement has
|
|
60
|
+
// no flow-level protection/policy verdict to have regressed, and this
|
|
61
|
+
// module has no coverage-completeness signal scoped to a bare node or
|
|
62
|
+
// edge (coverage.js's own ledger is source/sink/language-level, not
|
|
63
|
+
// node/edge-level) — so 'application_change' is the only honest
|
|
64
|
+
// default for those three entity kinds.
|
|
65
|
+
//
|
|
66
|
+
// 3. Change-cause classification for flows.changed entries is always
|
|
67
|
+
// 'application_change', per the brief's own literal instruction — a
|
|
68
|
+
// CHANGED flow (same id, different watched field) can never be a
|
|
69
|
+
// coverage regression by definition: coverage regression means the
|
|
70
|
+
// engine stopped seeing something, and a flow whose id is still
|
|
71
|
+
// present in both snapshots was, by construction, seen in both.
|
|
72
|
+
//
|
|
73
|
+
// 4. Reidentification (fix round 1, Important 1). flowId's own
|
|
74
|
+
// discriminator (graph-builder.js's `ids.flowId(src.id, snk.id,
|
|
75
|
+
// [de.id], [p.shape, g.grade, sortedT.join(',')])` call site) includes
|
|
76
|
+
// `evidenceGrade`/`transformationIds` — neither is an application-level
|
|
77
|
+
// fact; `evidenceGrade` in particular is the analyzer's own confidence
|
|
78
|
+
// in the flow. When either changes between two scans of literally the
|
|
79
|
+
// same real-world (source, sink, dataElementIds) flow — the commonest
|
|
80
|
+
// cause is a refactor the analyzer resolves less/more precisely — the
|
|
81
|
+
// flow mints a NEW flowId, and a naive id-set diff would report it as
|
|
82
|
+
// an unrelated remove+add pair: a fabricated `firstSeen` on the added
|
|
83
|
+
// entry, and a `removed` entry reading as "this flow went away" when it
|
|
84
|
+
// did not. `_flowCorrelationKey` (below) correlates a removed/added
|
|
85
|
+
// pair by REAL application identity — (source, sink, sorted
|
|
86
|
+
// dataElementIds) — instead, and computeGraphDiff marks a correlated
|
|
87
|
+
// pair `causeClassification: 'reidentified'` with a pointer
|
|
88
|
+
// (`reidentifiedFrom`/`reidentifiedTo`) at its counterpart, rather than
|
|
89
|
+
// silently treating them as independent. This never substitutes for
|
|
90
|
+
// flowId identity anywhere else in this file — it exists ONLY to
|
|
91
|
+
// detect this one reidentification case.
|
|
92
|
+
//
|
|
93
|
+
// A direct, disclosed consequence: `WATCHED_FLOW_FIELDS`'s `handling`
|
|
94
|
+
// entry is near-unreachable in the `changed.flows` bucket for the same
|
|
95
|
+
// root cause — a `handling` change almost always also changes
|
|
96
|
+
// `transformationIds`, which is itself part of flowId's own
|
|
97
|
+
// discriminator, so it manifests as a reidentification (remove+add,
|
|
98
|
+
// correlated) rather than surviving as a same-id `changed.flows` entry.
|
|
99
|
+
// This is a real, disclosed limitation of the current flowId shape, not
|
|
100
|
+
// a bug in this file.
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
const DIFF_VERSION = '1.0.0';
|
|
107
|
+
|
|
108
|
+
const ENTITY_ARRAYS = Object.freeze(['nodes', 'edges', 'dataElements', 'flows']);
|
|
109
|
+
|
|
110
|
+
// See judgment call #1 above for why `governanceRefs` is included
|
|
111
|
+
// alongside the brief's own literal four.
|
|
112
|
+
const WATCHED_FLOW_FIELDS = Object.freeze([
|
|
113
|
+
'protectionSummary', 'policyVerdict', 'handling', 'coverageStatus', 'governanceRefs',
|
|
114
|
+
]);
|
|
115
|
+
|
|
116
|
+
function _isNonEmptyString(v) { return typeof v === 'string' && v.length > 0; }
|
|
117
|
+
function _isPlainObject(v) { return v !== null && typeof v === 'object' && !Array.isArray(v); }
|
|
118
|
+
|
|
119
|
+
function _idMap(arr) {
|
|
120
|
+
const m = new Map();
|
|
121
|
+
for (const e of arr ?? []) {
|
|
122
|
+
if (e && typeof e.id === 'string') m.set(e.id, e);
|
|
123
|
+
}
|
|
124
|
+
return m;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Sorted id-set diff between two id->entity Maps. Deterministic order. */
|
|
128
|
+
function _idSetDiff(beforeMap, afterMap) {
|
|
129
|
+
const added = [];
|
|
130
|
+
const removed = [];
|
|
131
|
+
for (const id of afterMap.keys()) if (!beforeMap.has(id)) added.push(id);
|
|
132
|
+
for (const id of beforeMap.keys()) if (!afterMap.has(id)) removed.push(id);
|
|
133
|
+
added.sort();
|
|
134
|
+
removed.sort();
|
|
135
|
+
return { added, removed };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Correlates a flow across a commit boundary by APPLICATION identity
|
|
139
|
+
// (source, sink, dataElementIds) — deliberately NOT by flowId, since
|
|
140
|
+
// flowId's own discriminator includes evidenceGrade/transformationIds
|
|
141
|
+
// (engine-confidence/shape signals, not application facts — see
|
|
142
|
+
// graph-builder.js's ids.flowId call site), so the SAME real-world flow
|
|
143
|
+
// can legitimately mint two different ids across two scans. Never a
|
|
144
|
+
// substitute for flowId identity elsewhere in this file — used ONLY to
|
|
145
|
+
// detect this one specific reidentification case.
|
|
146
|
+
function _flowCorrelationKey(flow) {
|
|
147
|
+
const des = Array.isArray(flow.dataElementIds) ? [...flow.dataElementIds].sort() : [];
|
|
148
|
+
return `${flow.source}|${flow.sink}|${des.join(',')}`;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function _addedEntry(id, afterSnapshot) {
|
|
152
|
+
return {
|
|
153
|
+
id,
|
|
154
|
+
causeClassification: 'application_change',
|
|
155
|
+
firstSeen: { commit: afterSnapshot.commit, capturedAt: afterSnapshot.capturedAt },
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function _removedEntry(id, beforeSnapshot, causeClassification, extra = {}) {
|
|
160
|
+
return {
|
|
161
|
+
id,
|
|
162
|
+
causeClassification,
|
|
163
|
+
lastSeen: { commit: beforeSnapshot.commit, capturedAt: beforeSnapshot.capturedAt },
|
|
164
|
+
...extra,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Diffs one flow's WATCHED_FLOW_FIELDS between two snapshots of the SAME
|
|
170
|
+
* flow id. Returns an array of {field, before, after} — empty when
|
|
171
|
+
* nothing watched differs. Never a bare "something changed" — every
|
|
172
|
+
* entry names the exact field and its real before/after value.
|
|
173
|
+
*/
|
|
174
|
+
function _diffFlowFields(before, after) {
|
|
175
|
+
const changes = [];
|
|
176
|
+
for (const field of WATCHED_FLOW_FIELDS) {
|
|
177
|
+
if (field === 'governanceRefs') {
|
|
178
|
+
const b = before.governanceRefs ?? {};
|
|
179
|
+
const a = after.governanceRefs ?? {};
|
|
180
|
+
for (const gField of _dataflow_privacy_governance_js__WEBPACK_IMPORTED_MODULE_2__/* .GOVERNANCE_FIELDS */ .n4) {
|
|
181
|
+
const bv = b[gField] ?? null;
|
|
182
|
+
const av = a[gField] ?? null;
|
|
183
|
+
if (JSON.stringify(bv) !== JSON.stringify(av)) {
|
|
184
|
+
changes.push({ field: `governanceRefs.${gField}`, before: bv, after: av });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
const bv = before[field] ?? null;
|
|
190
|
+
const av = after[field] ?? null;
|
|
191
|
+
if (bv !== av) changes.push({ field, before: bv, after: av });
|
|
192
|
+
}
|
|
193
|
+
return changes;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Real, checkable coverage-completeness signals — read directly against
|
|
198
|
+
* coverage.js's own buildCoverageLedger output shape: `sources.matched`,
|
|
199
|
+
* `sinks.callStatementSites`, `languages[].filesAnalyzed`. Returns an
|
|
200
|
+
* array of reason strings naming exactly which completeness field
|
|
201
|
+
* regressed (empty when none did — never a guess in the regression
|
|
202
|
+
* direction).
|
|
203
|
+
*/
|
|
204
|
+
function _coverageRegressionReasons(coverageBefore, coverageAfter) {
|
|
205
|
+
const b = coverageBefore ?? {};
|
|
206
|
+
const a = coverageAfter ?? {};
|
|
207
|
+
const reasons = [];
|
|
208
|
+
|
|
209
|
+
const beforeMatched = b.sources?.matched ?? 0;
|
|
210
|
+
const afterMatched = a.sources?.matched ?? 0;
|
|
211
|
+
if (afterMatched < beforeMatched) {
|
|
212
|
+
reasons.push(`sources.matched decreased (${beforeMatched} -> ${afterMatched})`);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const beforeSites = b.sinks?.callStatementSites ?? 0;
|
|
216
|
+
const afterSites = a.sinks?.callStatementSites ?? 0;
|
|
217
|
+
if (afterSites < beforeSites) {
|
|
218
|
+
reasons.push(`sinks.callStatementSites decreased (${beforeSites} -> ${afterSites})`);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const beforeLangs = new Map((b.languages ?? []).map((l) => [l.language, l.filesAnalyzed]));
|
|
222
|
+
for (const l of a.languages ?? []) {
|
|
223
|
+
const prevAnalyzed = beforeLangs.get(l.language);
|
|
224
|
+
if (prevAnalyzed != null && l.filesAnalyzed < prevAnalyzed) {
|
|
225
|
+
reasons.push(`languages.${l.language}.filesAnalyzed decreased (${prevAnalyzed} -> ${l.filesAnalyzed})`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return reasons;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Structural validation only — mirrors graph-snapshot.js's own
|
|
234
|
+
* validateGraphSnapshot {valid, errors} shape and "never throws"
|
|
235
|
+
* contract. Checks the record's own top-level shape plus each
|
|
236
|
+
* added/removed/changed entry's own minimal shape; never cross-references
|
|
237
|
+
* a real graph (this module's validator, like every §10.10 extension
|
|
238
|
+
* contract's own validator, is a pure shape check).
|
|
239
|
+
*/
|
|
240
|
+
function validateGraphDiff(record) {
|
|
241
|
+
const errors = [];
|
|
242
|
+
const err = (p, message) => errors.push({ path: p, message });
|
|
243
|
+
|
|
244
|
+
if (!record || typeof record !== 'object' || Array.isArray(record)) {
|
|
245
|
+
err('$', 'GraphDiff record must be an object');
|
|
246
|
+
return { valid: false, errors };
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (!_isNonEmptyString(record.id) || !record.id.startsWith('diff:')) {
|
|
250
|
+
err('$.id', 'id is required and must start with "diff:"');
|
|
251
|
+
}
|
|
252
|
+
if (!_isNonEmptyString(record.version)) err('$.version', 'version is required');
|
|
253
|
+
if (!_isNonEmptyString(record.beforeSnapshotId)) err('$.beforeSnapshotId', 'beforeSnapshotId is required');
|
|
254
|
+
if (!_isNonEmptyString(record.afterSnapshotId)) err('$.afterSnapshotId', 'afterSnapshotId is required');
|
|
255
|
+
if (!_isNonEmptyString(record.generatedAt)) err('$.generatedAt', 'generatedAt is required');
|
|
256
|
+
|
|
257
|
+
if (!_isPlainObject(record.comparability)) {
|
|
258
|
+
err('$.comparability', 'comparability is required and must be an object');
|
|
259
|
+
} else {
|
|
260
|
+
if (typeof record.comparability.comparable !== 'boolean') {
|
|
261
|
+
err('$.comparability.comparable', 'comparability.comparable must be a boolean');
|
|
262
|
+
}
|
|
263
|
+
if (!Array.isArray(record.comparability.reasons)) {
|
|
264
|
+
err('$.comparability.reasons', 'comparability.reasons must be an array');
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const _checkEntryArray = (bucketPath, arr, requireFirstSeen, requireLastSeen) => {
|
|
269
|
+
if (!Array.isArray(arr)) {
|
|
270
|
+
err(bucketPath, `${bucketPath} must be an array`);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
arr.forEach((entry, i) => {
|
|
274
|
+
const p = `${bucketPath}[${i}]`;
|
|
275
|
+
if (!_isPlainObject(entry)) { err(p, `${p} must be an object`); return; }
|
|
276
|
+
if (!_isNonEmptyString(entry.id)) err(`${p}.id`, `${p}.id is required`);
|
|
277
|
+
if (!_isNonEmptyString(entry.causeClassification)) err(`${p}.causeClassification`, `${p}.causeClassification is required`);
|
|
278
|
+
if (requireFirstSeen && !_isPlainObject(entry.firstSeen)) err(`${p}.firstSeen`, `${p}.firstSeen is required and must be an object`);
|
|
279
|
+
if (requireLastSeen && !_isPlainObject(entry.lastSeen)) err(`${p}.lastSeen`, `${p}.lastSeen is required and must be an object`);
|
|
280
|
+
});
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
if (!_isPlainObject(record.added)) {
|
|
284
|
+
err('$.added', 'added is required and must be an object');
|
|
285
|
+
} else {
|
|
286
|
+
for (const key of ENTITY_ARRAYS) _checkEntryArray(`$.added.${key}`, record.added[key], true, false);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (!_isPlainObject(record.removed)) {
|
|
290
|
+
err('$.removed', 'removed is required and must be an object');
|
|
291
|
+
} else {
|
|
292
|
+
for (const key of ENTITY_ARRAYS) _checkEntryArray(`$.removed.${key}`, record.removed[key], false, true);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (!_isPlainObject(record.changed)) {
|
|
296
|
+
err('$.changed', 'changed is required and must be an object');
|
|
297
|
+
} else if (!Array.isArray(record.changed.flows)) {
|
|
298
|
+
err('$.changed.flows', 'changed.flows must be an array');
|
|
299
|
+
} else {
|
|
300
|
+
record.changed.flows.forEach((entry, i) => {
|
|
301
|
+
const p = `$.changed.flows[${i}]`;
|
|
302
|
+
if (!_isPlainObject(entry)) { err(p, `${p} must be an object`); return; }
|
|
303
|
+
if (!_isNonEmptyString(entry.id)) err(`${p}.id`, `${p}.id is required`);
|
|
304
|
+
if (!_isNonEmptyString(entry.causeClassification)) err(`${p}.causeClassification`, `${p}.causeClassification is required`);
|
|
305
|
+
if (!Array.isArray(entry.changes) || entry.changes.length === 0) {
|
|
306
|
+
err(`${p}.changes`, `${p}.changes must be a non-empty array naming which field(s) changed`);
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return { valid: errors.length === 0, errors };
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Diffs two GraphSnapshot records. Refuses (throws, naming the real
|
|
316
|
+
* reasons) on an incomparable pair — never silently diffs across one.
|
|
317
|
+
*
|
|
318
|
+
* added/removed: an ID-set diff across nodes/edges/dataElements/flows.
|
|
319
|
+
* changed: flows ONLY — every flow id present in both snapshots whose
|
|
320
|
+
* WATCHED_FLOW_FIELDS differ.
|
|
321
|
+
*
|
|
322
|
+
* Change-cause classification: every added/changed entry gets
|
|
323
|
+
* 'application_change' (no other real signal exists for those — see this
|
|
324
|
+
* file's own header). Every removed FLOW entry gets
|
|
325
|
+
* 'possible_coverage_regression' when the AFTER snapshot's real coverage
|
|
326
|
+
* is measurably lower on a real completeness field, otherwise
|
|
327
|
+
* 'application_change'; every removed node/edge/dataElement entry gets
|
|
328
|
+
* 'application_change' unconditionally (see judgment call #2 above).
|
|
329
|
+
*/
|
|
330
|
+
function computeGraphDiff(snapshotBefore, snapshotAfter, opts = {}) {
|
|
331
|
+
const { comparable, reasons } = (0,_graph_snapshot_js__WEBPACK_IMPORTED_MODULE_0__/* .snapshotsComparable */ .mx)(snapshotBefore, snapshotAfter);
|
|
332
|
+
if (!comparable) {
|
|
333
|
+
throw new Error(`computeGraphDiff: snapshots are not comparable — ${reasons.join('; ')}`);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const graphBefore = snapshotBefore.graph ?? {};
|
|
337
|
+
const graphAfter = snapshotAfter.graph ?? {};
|
|
338
|
+
|
|
339
|
+
const coverageRegressionReasons = _coverageRegressionReasons(snapshotBefore.coverage, snapshotAfter.coverage);
|
|
340
|
+
const flowRemovalCause = coverageRegressionReasons.length ? 'possible_coverage_regression' : 'application_change';
|
|
341
|
+
|
|
342
|
+
const added = {};
|
|
343
|
+
const removed = {};
|
|
344
|
+
const flowMaps = {};
|
|
345
|
+
|
|
346
|
+
for (const key of ENTITY_ARRAYS) {
|
|
347
|
+
const beforeMap = _idMap(graphBefore[key]);
|
|
348
|
+
const afterMap = _idMap(graphAfter[key]);
|
|
349
|
+
if (key === 'flows') {
|
|
350
|
+
flowMaps.before = beforeMap;
|
|
351
|
+
flowMaps.after = afterMap;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const { added: addedIds, removed: removedIds } = _idSetDiff(beforeMap, afterMap);
|
|
355
|
+
|
|
356
|
+
// Reidentification pairing (see judgment call #4 in this file's own
|
|
357
|
+
// header for the full reasoning): group removed/added flow ids by
|
|
358
|
+
// _flowCorrelationKey, pair them 1:1 (sorted by id, index-aligned)
|
|
359
|
+
// within each matching key. A pair is a re-identification, not a real
|
|
360
|
+
// remove+add. Any surplus on either side (uncommon — would need >1
|
|
361
|
+
// flow sharing the same correlation key on one side) falls through to
|
|
362
|
+
// the existing add/remove logic unchanged.
|
|
363
|
+
const reidentifiedFrom = new Map(); // addedId -> removedId
|
|
364
|
+
const reidentifiedTo = new Map(); // removedId -> addedId
|
|
365
|
+
if (key === 'flows') {
|
|
366
|
+
const removedByKey = new Map();
|
|
367
|
+
for (const id of removedIds) {
|
|
368
|
+
const f = beforeMap.get(id);
|
|
369
|
+
const k = _flowCorrelationKey(f);
|
|
370
|
+
if (!removedByKey.has(k)) removedByKey.set(k, []);
|
|
371
|
+
removedByKey.get(k).push(id);
|
|
372
|
+
}
|
|
373
|
+
const addedByKey = new Map();
|
|
374
|
+
for (const id of addedIds) {
|
|
375
|
+
const f = afterMap.get(id);
|
|
376
|
+
const k = _flowCorrelationKey(f);
|
|
377
|
+
if (!addedByKey.has(k)) addedByKey.set(k, []);
|
|
378
|
+
addedByKey.get(k).push(id);
|
|
379
|
+
}
|
|
380
|
+
for (const [k, removedGroup] of removedByKey) {
|
|
381
|
+
const addedGroup = addedByKey.get(k);
|
|
382
|
+
if (!addedGroup) continue;
|
|
383
|
+
removedGroup.sort();
|
|
384
|
+
addedGroup.sort();
|
|
385
|
+
const n = Math.min(removedGroup.length, addedGroup.length);
|
|
386
|
+
for (let i = 0; i < n; i++) {
|
|
387
|
+
reidentifiedTo.set(removedGroup[i], addedGroup[i]);
|
|
388
|
+
reidentifiedFrom.set(addedGroup[i], removedGroup[i]);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
added[key] = addedIds.map((id) => {
|
|
394
|
+
const entry = _addedEntry(id, snapshotAfter);
|
|
395
|
+
if (key === 'flows' && reidentifiedFrom.has(id)) {
|
|
396
|
+
entry.causeClassification = 'reidentified';
|
|
397
|
+
entry.reidentifiedFrom = reidentifiedFrom.get(id);
|
|
398
|
+
}
|
|
399
|
+
return entry;
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
if (key === 'flows') {
|
|
403
|
+
removed[key] = removedIds.map((id) => {
|
|
404
|
+
const extra = coverageRegressionReasons.length ? { coverageRegressionReasons } : {};
|
|
405
|
+
const entry = _removedEntry(id, snapshotBefore, flowRemovalCause, extra);
|
|
406
|
+
if (reidentifiedTo.has(id)) {
|
|
407
|
+
entry.causeClassification = 'reidentified';
|
|
408
|
+
entry.reidentifiedTo = reidentifiedTo.get(id);
|
|
409
|
+
}
|
|
410
|
+
return entry;
|
|
411
|
+
});
|
|
412
|
+
} else {
|
|
413
|
+
removed[key] = removedIds.map((id) => _removedEntry(id, snapshotBefore, 'application_change'));
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
const changedFlows = [];
|
|
418
|
+
for (const [id, beforeFlow] of flowMaps.before) {
|
|
419
|
+
const afterFlow = flowMaps.after.get(id);
|
|
420
|
+
if (!afterFlow) continue; // removed — already handled above
|
|
421
|
+
const changes = _diffFlowFields(beforeFlow, afterFlow);
|
|
422
|
+
if (changes.length > 0) {
|
|
423
|
+
changedFlows.push({ id, causeClassification: 'application_change', changes });
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
changedFlows.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
|
|
427
|
+
|
|
428
|
+
const record = {
|
|
429
|
+
id: (0,_ids_js__WEBPACK_IMPORTED_MODULE_1__/* .diffId */ .Jd)({ beforeSnapshotId: snapshotBefore.id, afterSnapshotId: snapshotAfter.id }),
|
|
430
|
+
version: DIFF_VERSION,
|
|
431
|
+
beforeSnapshotId: snapshotBefore.id,
|
|
432
|
+
afterSnapshotId: snapshotAfter.id,
|
|
433
|
+
comparability: { comparable: true, reasons: [] },
|
|
434
|
+
added,
|
|
435
|
+
removed,
|
|
436
|
+
changed: { flows: changedFlows },
|
|
437
|
+
generatedAt: opts.generatedAt ?? new Date().toISOString(),
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
const { valid, errors } = validateGraphDiff(record);
|
|
441
|
+
if (!valid) {
|
|
442
|
+
throw new Error(`computeGraphDiff: internal error — produced an invalid GraphDiff: ${JSON.stringify(errors)}`);
|
|
443
|
+
}
|
|
444
|
+
return record;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
/***/ })
|
|
449
|
+
|
|
450
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export const id =
|
|
2
|
-
export const ids = [
|
|
1
|
+
export const id = 3526;
|
|
2
|
+
export const ids = [3526,2238];
|
|
3
3
|
export const modules = {
|
|
4
4
|
|
|
5
5
|
/***/ 2238:
|
|
@@ -65,7 +65,7 @@ const RELIABLE_N = 10;
|
|
|
65
65
|
const FIX_STAGES = Object.freeze(['rescan', 'lint', 'tests', 'honesty', 'poc']);
|
|
66
66
|
|
|
67
67
|
function _logPath(scanRoot) {
|
|
68
|
-
return (0,_state_dir_js__WEBPACK_IMPORTED_MODULE_2__
|
|
68
|
+
return (0,_state_dir_js__WEBPACK_IMPORTED_MODULE_2__.statePath)(scanRoot, LOG_FILE);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/**
|
|
@@ -311,8 +311,8 @@ var external_node_child_process_ = __webpack_require__(1421);
|
|
|
311
311
|
var external_node_fs_ = __webpack_require__(3024);
|
|
312
312
|
// EXTERNAL MODULE: external "node:path"
|
|
313
313
|
var external_node_path_ = __webpack_require__(6760);
|
|
314
|
-
// EXTERNAL MODULE: ./src/engine.js +
|
|
315
|
-
var engine = __webpack_require__(
|
|
314
|
+
// EXTERNAL MODULE: ./src/engine.js + 244 modules
|
|
315
|
+
var engine = __webpack_require__(9753);
|
|
316
316
|
;// CONCATENATED MODULE: ./src/posture/fix-honesty-gate.js
|
|
317
317
|
// Deterministic honesty gates on fix / finding output (#7).
|
|
318
318
|
//
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export const id =
|
|
2
|
-
export const ids = [
|
|
1
|
+
export const id = 3736;
|
|
2
|
+
export const ids = [3736];
|
|
3
3
|
export const modules = {
|
|
4
4
|
|
|
5
5
|
/***/ 3736:
|
|
@@ -230,7 +230,7 @@ function loadPolicyBundles(scanRoot) {
|
|
|
230
230
|
const entries = [];
|
|
231
231
|
for (const scope of SCOPES) {
|
|
232
232
|
let fp;
|
|
233
|
-
try { fp = (0,_state_dir_js__WEBPACK_IMPORTED_MODULE_5__
|
|
233
|
+
try { fp = (0,_state_dir_js__WEBPACK_IMPORTED_MODULE_5__.statePath)(scanRoot, 'policy-bundles', `${scope}.json`); } catch { continue; }
|
|
234
234
|
let raw;
|
|
235
235
|
try { raw = node_fs__WEBPACK_IMPORTED_MODULE_0__.readFileSync(fp, 'utf8'); } catch { continue; }
|
|
236
236
|
try {
|
|
@@ -251,7 +251,7 @@ function loadPolicyBundles(scanRoot) {
|
|
|
251
251
|
function loadPolicyPublicKey(scanRoot) {
|
|
252
252
|
if (!scanRoot) return null;
|
|
253
253
|
let fp;
|
|
254
|
-
try { fp = (0,_state_dir_js__WEBPACK_IMPORTED_MODULE_5__
|
|
254
|
+
try { fp = (0,_state_dir_js__WEBPACK_IMPORTED_MODULE_5__.statePath)(scanRoot, 'policy-bundle-public-key.pem'); } catch { return null; }
|
|
255
255
|
try { return node_fs__WEBPACK_IMPORTED_MODULE_0__.readFileSync(fp, 'utf8'); } catch { return null; }
|
|
256
256
|
}
|
|
257
257
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export const id =
|
|
2
|
-
export const ids = [
|
|
1
|
+
export const id = 3839;
|
|
2
|
+
export const ids = [3839];
|
|
3
3
|
export const modules = {
|
|
4
4
|
|
|
5
5
|
/***/ 3839:
|
|
@@ -32,7 +32,7 @@ export const modules = {
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
function _read(scanRoot, name) {
|
|
35
|
-
try { return node_fs__WEBPACK_IMPORTED_MODULE_0__.readFileSync((0,_state_dir_js__WEBPACK_IMPORTED_MODULE_2__
|
|
35
|
+
try { return node_fs__WEBPACK_IMPORTED_MODULE_0__.readFileSync((0,_state_dir_js__WEBPACK_IMPORTED_MODULE_2__.statePath)(scanRoot, name), 'utf8'); } catch { return null; }
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
function _readJson(scanRoot, name) {
|
|
@@ -113,7 +113,7 @@ function queryFindingsMemory(scanRoot, query) {
|
|
|
113
113
|
|
|
114
114
|
// 3. Scan history.
|
|
115
115
|
try {
|
|
116
|
-
const histDir = (0,_state_dir_js__WEBPACK_IMPORTED_MODULE_2__
|
|
116
|
+
const histDir = (0,_state_dir_js__WEBPACK_IMPORTED_MODULE_2__.statePath)(scanRoot, 'scan-history');
|
|
117
117
|
if (node_fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(histDir)) {
|
|
118
118
|
const files = node_fs__WEBPACK_IMPORTED_MODULE_0__.readdirSync(histDir).filter(f => f.endsWith('.json')).slice(-10);
|
|
119
119
|
for (const f of files) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export const id =
|
|
2
|
-
export const ids = [
|
|
1
|
+
export const id = 4113;
|
|
2
|
+
export const ids = [4113,2238,3526];
|
|
3
3
|
export const modules = {
|
|
4
4
|
|
|
5
5
|
/***/ 2238:
|
|
@@ -65,7 +65,7 @@ const RELIABLE_N = 10;
|
|
|
65
65
|
const FIX_STAGES = Object.freeze(['rescan', 'lint', 'tests', 'honesty', 'poc']);
|
|
66
66
|
|
|
67
67
|
function _logPath(scanRoot) {
|
|
68
|
-
return (0,_state_dir_js__WEBPACK_IMPORTED_MODULE_2__
|
|
68
|
+
return (0,_state_dir_js__WEBPACK_IMPORTED_MODULE_2__.statePath)(scanRoot, LOG_FILE);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/**
|
|
@@ -492,8 +492,8 @@ var external_node_child_process_ = __webpack_require__(1421);
|
|
|
492
492
|
var external_node_fs_ = __webpack_require__(3024);
|
|
493
493
|
// EXTERNAL MODULE: external "node:path"
|
|
494
494
|
var external_node_path_ = __webpack_require__(6760);
|
|
495
|
-
// EXTERNAL MODULE: ./src/engine.js +
|
|
496
|
-
var engine = __webpack_require__(
|
|
495
|
+
// EXTERNAL MODULE: ./src/engine.js + 244 modules
|
|
496
|
+
var engine = __webpack_require__(9753);
|
|
497
497
|
;// CONCATENATED MODULE: ./src/posture/fix-honesty-gate.js
|
|
498
498
|
// Deterministic honesty gates on fix / finding output (#7).
|
|
499
499
|
//
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export const id =
|
|
2
|
-
export const ids = [
|
|
1
|
+
export const id = 4384;
|
|
2
|
+
export const ids = [4384];
|
|
3
3
|
export const modules = {
|
|
4
4
|
|
|
5
5
|
/***/ 4384:
|
|
@@ -8,7 +8,7 @@ export const modules = {
|
|
|
8
8
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
9
9
|
/* harmony export */ scanCredentials: () => (/* reexport safe */ _engine_js__WEBPACK_IMPORTED_MODULE_0__.Sv)
|
|
10
10
|
/* harmony export */ });
|
|
11
|
-
/* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(
|
|
11
|
+
/* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9753);
|
|
12
12
|
// Secrets submodule view of the engine — credential + entropy + TODO scanning.
|
|
13
13
|
|
|
14
14
|
|