# Expected Findings — Supply Chain Attack Walkthrough

This is the testable contract. `run-supply-chain.mjs` exits 0 only
when every row matches.

## Stage A — pre-install-supply-chain hook

| Case | Command | Exit | stderr/stdout must contain |
|------|---------|------|----------------------------|
| 1 | `npm install event-stream@3.3.6` | **2** | `COMPROMISED` and a reference to the `socket.dev` URL |
| 2 | `npm install @evilcorp/lodash` | 0 | `SCOPE-HOPPING SUSPECTED` advisory |
| 3 | `npm install lodash` | 0 | (no advisory required) |

The hook's BLOCK output goes to stderr with the literal prefix
`🛑 BLOCKED: Supply chain risk detected [npm]`. Advisories use the
prefix `⚠️ Supply chain advisory [npm]:`. Both are checked
case-insensitively by `run-supply-chain.mjs`.

## Stage B — dep-auditor on `fixture/package.json`

Findings array MUST contain at least:

| Severity | Title pattern | Source |
|----------|---------------|--------|
| HIGH | `Possible typosquatting: "expresss" vs "express" (edit distance 1)` | typosquat — Levenshtein 1 |
| MEDIUM | `Potential typosquatting: "loadsh" vs "lodash" (edit distance 2)` | typosquat — Levenshtein 2 |
| MEDIUM | `Potential typosquatting: "axois" vs "axios" (edit distance 2)` | typosquat — Levenshtein 2 |
| HIGH | `Possible typosquatting: "reaact" vs "react" (edit distance 1)` | typosquat — Levenshtein 1 |
| HIGH | `Possible typosquatting: "chalkk" vs "chalk" (edit distance 1)` | typosquat — Levenshtein 1 (devDependencies) |
| HIGH | `Suspicious npm install hook: scripts.postinstall contains network/exec patterns` | install-script heuristic |

Total: **6 findings**.

`run-supply-chain.mjs` asserts:

- `>= 4` typosquat findings (allowing minor changes in dep-auditor)
- `>= 1` install-script finding

## Side effects

- No real `npm install` runs — only synthetic JSON sent to the hook
- No write to the user's `node_modules/`
- No network call (deterministic mode); OSV.dev path is not exercised
- The fixture `package.json` is parsed read-only

## Notes for forks

If a fork extends `NPM_COMPROMISED` or `top-packages.json`:

- The compromised-version block (case 1) may match a different list
  entry — adjust the regex if needed
- The typosquat findings are tied to the top-100 list. Adding/removing
  entries near `chalk`/`react`/`express`/`lodash`/`axios` may change
  the severity from MEDIUM to HIGH or vice-versa
- The install-script heuristic regex lives in `dep-auditor.mjs` — if
  reworded, update the test pattern in `run-supply-chain.mjs`
