<!-- nornir:class: reasoning -->
# Móðguðr — Engine B catalog of advanced analyses (design, post-demo)
> Móðguðr guards Gjallarbrú: she watches the **whole dependency world** and tracks
> **every change to the smallest bit**. Engine B is not "a diff" — it is a battery of
> tripwires, graph algorithms, and anomaly detectors over **(the SCIP world × time)**.
>
> Inputs available to us:
> - **SCIP facts** — symbol defs/refs, the call graph, monikers (cross-repo symbol
> identity), per-symbol reference closure. Lifted from nornir's SCIP/knowledge modules.
> - **Dep graph** — resolved transitive tree per ecosystem (cargo/maven/npm/pip/go…).
> - **Registry metadata** — publisher, keys, timestamps, download counts, yank state.
> - **Provenance** — CMS signatures (znippy `sign`), SLSA/in-toto attestations.
> - **Embeddings** — the nornir embedder (jina/Qwen) → code/package vectors.
> - **Time-travel** — Apache Iceberg snapshots via **skade** (modgunn → skade, leaf;
> never nornir). Any two world-snapshots are diffable; full history is queryable.
>
> Verdict surface: every analysis emits `Finding{severity, kind, subject, evidence}`
> folded into a `core::Verdict` (Pass/Warn/Block), the SAME shape Engine A uses, plus a
> `Tripwire` event stream for the world-delta site.
---
## Build status (2026-07) — what is actually implemented
> **Authoritative, code-verified.** DONE = implemented + unit-tested; PARTIAL =
> core landed, a piece of the full analysis still design-only; DESIGN = not yet
> coded. Symbols are in `src/scip.rs` unless noted `provenance.rs` / `warehouse.rs`.
> **25 / 25 catalog analyses are landed** (22 in the Engine-B graph core `scip.rs`
> + 2 on the provenance surface + the world-time-travel two-point diff verb in
> `warehouse.rs`), up from the 5 the old status table claimed — plus a
> **taint-path (source→sink)** analysis (`taint_path_findings`) beyond the numbered
> catalog (the SAST/dataflow-rival capability, master-plan "A12").
| # | Analysis | State | Implementing symbol |
|---|---|---|---|
| 1 | Call-graph delta | ✅ DONE | `CallGraphDeltaTripwire` |
| 2 | Capability-surface drift | ✅ DONE | `capability_surface` + `CapabilityDriftTripwire` |
| 3 | Silent behavior fingerprint | ✅ DONE | `FingerprintDriftTripwire` (FNV-1a over the reachable closure) |
| 4 | Reachability-gated vuln | ✅ DONE | `reachability_gated_vulns` / `unreachable_vulns` |
| 5 | Sink-newly-reachable | ✅ DONE | `SinkNewlyReachableTripwire` |
| 6 | Publisher/maintainer anomaly | ✅ DONE | `MaintainerAnomalyTripwire` (ownership-transfer delta over `DepNode::owners`: disjoint owner set → High takeover, partial change → Medium, maintainer-count collapse → Low); signer-change co-signal via `provenance::attestation_delta` |
| 7 | Release-cadence / timeline anomaly | ✅ DONE | `release_cadence_anomalies` (per-package inter-arrival z-score; `DepNode::release_epochs` input) |
| 8 | Typosquat & dependency-confusion | ✅ DONE | `typosquat_findings` (+ `levenshtein`) |
| 9 | Attestation delta (SLSA/in-toto) | ✅ DONE | `provenance::attestation_delta` + `ProvenanceRequirement::evaluate` |
| 10 | Source↔artifact divergence | ✅ DONE | `provenance::verify_sealed_provenance` / `evaluate_sealed` (znippy-sealed build-provenance VERIFY: CMS seal + content-addressing + source-repo, feature `provenance-verify`) |
| 11 | Blast-radius centrality | ✅ DONE | `blast_radius` (PageRank) / `blast_radius_findings` |
| 12 | Bus-factor / SPOF | ✅ DONE | `bus_factor_findings` (`DepNode::maintainers` input) |
| 13 | Owner-cluster correlation | ✅ DONE | `owner_cluster_findings` (label-propagation community detection over the co-ownership graph; `DepNode::owners` input) |
| 14 | Entrypoint→sink path + min-cut | ✅ DONE | `sink_chokepoints` (single-vertex cuts) |
| 15 | Diamond / multi-version conflict | ✅ DONE | `diamond_conflicts` |
| 16 | Metric-outlier detection | ✅ DONE | `zscore_outliers` primitive + `dep_fanin_outliers` |
| 17 | Obfuscation / entropy spike | ✅ DONE | `shannon_entropy` + `ObfuscationTripwire` |
| 18 | Embedding-novelty | ✅ DONE | `embedding_novelty_findings` (per-ecosystem centroid + `cosine_distance` novelty outliers; `DepNode::embedding` input — producer attaches the nornir embedder's vector, honest-optional) |
| 19 | License-transition | ✅ DONE | `license_transition_findings` (riskward relicense across version history, ranked by `license_risk_tier`; `DepNode::license_history` input) — transitive copyleft-contamination-path cut is a further extension |
| 20 | SBOM drift | ✅ DONE | `SbomDriftTripwire` (component set-diff over `DepNode::key` → entered/left Findings; entered-unverified → Low, else Info) — the catalog-surface companion to the raw `warehouse::sbom_drift` `(name,version)` helper |
| 21 | Policy tripwires | ✅ DONE | `PolicyRule` DSL (`NoCapabilityGrowth`/`NoNewNativeCode`/`NoUnverifiedDependencyAdded`/`ForbidEcosystem`) + `PolicyTripwire` + `default_policy()` — declarative boolean assertions firing High on the delta |
| 22 | Threshold tripwires | ✅ DONE | `ThresholdRule` DSL (`UnverifiedCentralityOver`/`CapabilitySurfaceGrewBy`/`NewSymbolEntropyOver`/`FanInAtLeast`) + `ThresholdTripwire` — declarative numeric-bound crossings |
| 23 | Honeytoken / canary | ✅ DONE | `Honeytoken` (`InternalName`/`CanaryToken`) + `honeytoken_findings` — resolved internal name = dependency-confusion hit, surfaced canary token = exfiltration; every hit Critical, unplanted world never fires |
| 24 | World time-travel | ✅ DONE | `warehouse::world_diff(snap_a, snap_b) -> WorldEdgeDiff` — the explicit two-point diff verb over persisted snapshots (entered/left dep-graph edges + node sets), atop the capture + CDC seam (`capture_world_snapshot`/`commit_seq`/`table_delta`) |
| 25 | Change-velocity baselines | ✅ DONE | `change_velocity_anomalies` (trailing-window release-rate burst; z-score over the rolling velocity series; reuses `DepNode::release_epochs`) |
> **Beyond the numbered catalog — taint-path (source→sink).** `taint_path_findings`
> flags call-graph paths from an **untrusted source** ([`Symbol::is_taint_source`] —
> a network / IPC / deserialization read) to a **sensitive sink** (a symbol
> exercising a capability in `default_taint_sinks`: process/dynamic-code/filesystem/
> ffi/env). This is the SAST/dataflow-rival capability (Semgrep/CodeQL taint) the
> master-plan lists as "A12"; `Critical` for code/command-exec sinks, else `High`.
> Empty (no source marked) ⇒ doesn't fire.
---
## Family 1 — Behavior-delta (the core "world-delta")
1. **Call-graph delta.** New/removed edges between two versions of a symbol's transitive
call set. *Fires when:* a leaf dep grows edges into network/fs/process/FFI it never had.
*Data:* SCIP call graph × 2 snapshots. *Algo:* graph set-diff + edge classification.
2. **Capability-surface drift.** Track the set of **dangerous capabilities** a package
reaches transitively — network, filesystem, process-spawn, env/secret read, dynamic
code load, reflection, FFI/`unsafe`, clock/rng. Alert when the set *grows*.
*Algo:* reachability closure over the call graph to a labeled sink set; set delta.
3. **Silent behavior fingerprint.** Hash/embed a symbol's *effective behavior* (its
transitive reference closure). **Fire when the fingerprint changes but the version /
public API signature did NOT** — the classic "5th-level jar, unchanged for years,
suddenly behaves differently." *Algo:* SCIP closure → stable hash + embedding; compare
to the symbol's own history.
4. **Reachability-gated vuln prioritization.** Only alert on a CVE if the vulnerable
function is **call-reachable from your entrypoints** (kills the 90% false-positive
noise of version-only matchers). *Algo:* multi-source BFS entrypoints → CVE sink.
5. **Sink-newly-reachable tripwire.** A delta that makes any sink (CVE, capability,
tainted source) reachable that previously was not — the highest-signal delta event.
## Family 2 — Supply-chain integrity & provenance anomalies
6. **Publisher/maintainer anomaly.** New signing key, ownership transfer, sudden
maintainer change → account-takeover signal. *Data:* registry + provenance history.
7. **Release-cadence / timeline anomaly.** Dormant package (no release in years) suddenly
publishes; off-hours/weekend publish; unusual version jump. *Algo:* per-package
inter-arrival baseline + z-score on the warehouse time series.
8. **Typosquat & dependency-confusion.** Name edit-distance / homoglyph similarity to
popular packages; **internal package name now resolvable on a public registry**
(the dep-confusion attack). *Algo:* normalized edit distance + homoglyph table +
internal-namespace set membership.
9. **Attestation delta (SLSA/in-toto).** Attestation appears/disappears, builder identity
changes, source-repo URL mismatch vs the artifact's claimed origin.
10. **Source↔artifact divergence.** Does the published artifact rebuild from the tagged
source (reproducible-build / git-SHA→package linkage)? Flag artifacts that don't.
## Family 3 — Graph / structural algorithms (the "government-grade" core)
11. **Blast-radius centrality.** Betweenness / PageRank over the dep graph → rank which
deps, if compromised, touch the most of your surface. Drives monitoring priority.
12. **Bus-factor / single-point-of-failure.** Highly central deps with a single
maintainer (correlate centrality × maintainer-count).
13. **Owner-cluster correlation.** Community detection over (dep → publisher) to surface
clusters controlled by one entity → correlated, not independent, risk.
14. **Entrypoint→sink path analysis + min-cut.** All paths from your code to a sink, and
the **chokepoints** (min vertex cut) you could patch/pin to sever the most paths.
15. **Diamond / multi-version conflict.** Same crate at N versions in the tree, one of
which is vulnerable or unverified.
## Family 4 — Statistical & ML anomaly detection
16. **Metric-outlier detection.** Size delta, dep-count delta, file-count jump,
download-count anomalies → z-score / isolation forest over the warehouse history.
17. **Obfuscation / entropy spike.** High-entropy strings, minified/obfuscated regions,
base64/hex blobs, `eval`-like dynamic execution newly introduced. *Algo:* per-file
Shannon entropy + AST/SCIP markers, delta vs prior version.
18. **Embedding-novelty.** Embed each package version (nornir embedder) and flag a release
whose vector moves far from **its own history** or from the **ecosystem norm**
(cosine distance > threshold). Catches semantically-novel injected code.
## Family 5 — License & legal drift
19. **License-transition tracking.** A dep relicenses mid-stream (MIT→AGPL); detect
**copyleft-contamination paths** (transitive license-compatibility cut).
20. **SBOM drift.** Full CycloneDX/SPDX SBOM delta between two world snapshots — the
auditable record of "what entered/left the world and when."
## Family 6 — Tripwires (declarative, active)
21. **Policy tripwires.** Declarative rules that fire on delta: "no new native FFI in
transitive deps", "no dep added without provenance", "no dep from registry X",
"capability surface may not grow without review".
22. **Threshold tripwires.** "centrality of an unverified dep crossed T", "entropy spike >
σ", "capability set grew by ≥ k".
23. **Honeytoken / canary.** Planted markers that fire if a watched internal name or
secret-shaped token is exfiltrated/resolved externally.
## Family 7 — Temporal (warehouse-backed — where skade/Iceberg earns its keep)
24. **World time-travel.** Iceberg snapshot = "what did the dep world look like on date X";
diff any two points; reconstruct the full provenance timeline of any dep.
25. **Change-velocity baselines.** Per-dep historical change-rate model; flag deviations
(sudden burst, or suspicious freeze-then-spike).
---
## Compute tiers
- **Cheap (holger gate / per-serve, online):** 4, 5, 8, 9, 19, 21 — set lookups + small
reachability. These can run in Engine A's latency budget.
- **Medium (per-promote / nightly):** 1, 2, 6, 7, 16, 17, 20, 22, 25.
- **Heavy (the world-delta site, 128 GB – 1 TB RAM):** 3, 10–15, 18, 23, 24 — full SCIP
closure + whole-graph algorithms + embeddings over the entire transitive world.
## Recommended first slice (when Engine B starts, post-demo)
1. **`WorldSnapshot` capture** — persist the resolved dep graph + SCIP symbol/edge facts
into `skade` Iceberg tables (`world_snapshots`, `dep_edges`, `scip_symbols`).
2. **`diff()` → `BehaviorDelta`** — Family-1 #1 (call-graph delta) + #2 (capability drift)
as the first two real signals; emit `Tripwire` events.
3. **#4 reachability-gated vuln prioritization** — immediately makes Engine A's CVE
verdicts *precise* (reachable vs merely-present), the highest user-visible win.
4. Then layer #11 blast-radius centrality (cheap, high value) and #18 embedding-novelty
(reuses the existing embedder).
All of the above are **leaf-clean**: SCIP/knowledge machinery is *lifted into* modgunn;
persistence is `modgunn → skade`; nornir remains the consumer (viz pane + tripwire feed).
See [`nornir/.nornir/modgunn-security-scanner.md`](../../nornir/.nornir/modgunn-security-scanner.md).