# Expected findings — toxic-agent-demo

This is the testable contract enforced by `run-toxic-flow.mjs`.
Three independent assertions. Any drift = scanner regression or
fixture rot.

## Required assertions (3 / 3 must pass)

### 1. Direct trifecta — single component covers all 3 legs

- The TFA scanner returns at least 1 finding whose `title`
  starts with `Lethal trifecta:`.
- At least one of those findings has `severity === 'critical'`.

The component covering all three legs is
`agents/exfil-helper.fixture.md`. With `tools: [Bash, Read,
WebFetch]`, the tool-based classifier alone covers:

- **Leg 1** (input surface) — `Bash` is in `INPUT_SURFACE_TOOLS`.
- **Leg 2** (data access) — `Read` is in `DATA_ACCESS_TOOLS`;
  `Bash` also adds the "cat/find/grep capable" evidence string.
- **Leg 3** (exfil sink) — both `Bash` and `WebFetch` are in
  `EXFIL_SINK_TOOLS`.

Keywords in description and body reinforce all three:

| Leg | Keyword(s) hit |
|-----|----------------|
| 1   | `untrusted`, `user input`, `url`, `remote` |
| 2   | `secret`, `credential`, `.env`, `.aws`, `keychain` |
| 3   | `webhook`, `upload`, `curl`, `network`, `http`, `transfer`, `exfil` |

### 2. Finding mentions the exfil-helper component

The trifecta finding's `title` matches `/exfil-helper/i`. This
guards against a regression where TFA emits a generic
project-level fallback instead of the per-component finding.

### 3. No hook guards detected

The trifecta finding's `description` matches
`/no hook guards detected/i`. This proves the mitigation logic
correctly identified the missing `hooks/hooks.json` and kept the
severity at CRITICAL rather than downgrading to HIGH or MEDIUM.

If a real `hooks/hooks.json` is later added to the fixture, the
description switches to `Mitigated by active hook guards
(severity reduced).` and the severity drops to HIGH (one guard
type) or MEDIUM (both guard types) — this assertion would fail
and signal that the mitigation path activated.

## Total finding shape

```
Total TFA findings:        1
  direct trifectas:        1
  cross-component:         0
  project-level fallback:  0
Files scanned (components): 1
Scanner status:            ok
```

If the scanner emits more than one direct trifecta, add a second
component to the fixture or update this contract — extra
findings are not a failure, but they are a deliberate fixture
change.

## Out of scope (intentionally)

- Cross-component trifectas (would need a second agent/command
  splitting the legs) — see `tests/lib/toxic-flow-analyzer.test.mjs`
  for that case.
- Mitigation downgrade to HIGH / MEDIUM — would need a real
  `hooks/hooks.json` referencing one of the guard scripts.
- Prior-scanner enrichment via `enrichFromPriorResults()` — this
  walkthrough passes `priorResults = {}` to keep the demonstration
  reproducible and isolated. The full `scan-orchestrator.mjs` flow
  exercises that pass in production.
