# Test — Secrets in Source + Banned-Lib Hygiene + Anti-Criterion

**Task**: AZ-482_test_secrets_and_banned_libs
**Name**: OWM key not in source/bundle + no ML/JOSE/SW/dropped libs + AC-N1 anti-criterion
**Description**: Implement the 6 static blackbox tests pinning the source-/bundle-hygiene contracts: no OpenWeatherMap key in source (NFT-SEC-09), no in-browser ML libs (NFT-SEC-10), no JOSE / response-signature libs (NFT-SEC-11), no service worker (NFT-SEC-12), no dropped legacy features (NFT-SEC-13), and the AC-N1 anti-criterion (no concurrent-edit reconciliation surfaces in source) (NFT-SEC-14).
**Complexity**: 3 points
**Dependencies**: AZ-456_test_infrastructure
**Component**: 00_foundation + cross-cutting (Blackbox Tests)
**Tracker**: AZ-482
**Epic**: AZ-455

## Problem

Six contract pins that are all static-checkable and all about what MUST NOT exist in the codebase / built bundle. Each comes from a hard restriction in `_docs/00_problem/restrictions.md` (R*) or `_docs/00_problem/security_approach.md`. Without static enforcement, they regress on the day someone "just adds" a banned library.

## Outcome

- 6 scenarios pass (as static checks).

## Scope

### Included

| Scenario | Profile | Source file | results_report row |
|----------|---------|-------------|--------------------|
| NFT-SEC-09 — OpenWeatherMap API key is not shipped in source or bundle | static | security-tests.md | 63 |
| NFT-SEC-10 — No in-browser ML libs | static | security-tests.md | per NFT-SEC-10 |
| NFT-SEC-11 — No response-signature / JOSE libs on the request path | static | security-tests.md | per NFT-SEC-11 |
| NFT-SEC-12 — No service worker — offline mode is explicitly absent | static + e2e | security-tests.md | per NFT-SEC-12 |
| NFT-SEC-13 — Dropped legacy features are not present in source | static | security-tests.md | per NFT-SEC-13 |
| NFT-SEC-14 — Anti-criterion AC-N1 — no concurrent-edit reconciliation surfaces | static | security-tests.md | per NFT-SEC-14 |

### Excluded

- Auth-storage assertions (covered in 02_test_auth_token_handling).
- Destructive `alert()` ban (covered in 11_test_destructive_ux).

## Acceptance Criteria

**AC-1: OWM key absence**
NFT-SEC-09 — `grep -rn '335799082893fad97fa36118b131f919' src/` returns 0 hits (per the autodev Step 4 C01 refactor); `grep -rn` against `dist/` after `bun run build` also returns 0 hits. The OWM key is provided only via `VITE_OWM_API_KEY` at build time.

**AC-2: No ML libs**
NFT-SEC-10 — `package.json` does not declare `tensorflow`, `tfjs`, `onnxruntime`, `@tensorflow/*`, `@huggingface/*`; the static check enumerates against an explicit deny-list.

**AC-3: No JOSE / signature libs**
NFT-SEC-11 — `package.json` does not declare `jose`, `jsonwebtoken`, `node-forge`, `tweetnacl`; same deny-list pattern.

**AC-4: No service worker**
NFT-SEC-12 — `grep -rn 'serviceWorker' src/` returns no `register(` call; `grep -rn 'sw\.js\|workbox' src/ public/` returns 0; e2e: `navigator.serviceWorker.getRegistrations()` returns `[]`.

**AC-5: Dropped features absent**
NFT-SEC-13 — `grep -rn 'WhatsApp\|TelegramBot\|D-Bus\|libsignal' src/` returns 0 hits (the dropped legacy integrations).

**AC-6: AC-N1 anti-criterion**
NFT-SEC-14 — no source string matches `concurrent.edit|operational.transform|crdt|y-?websocket` — the SPA has no concurrent-edit reconciliation surface.

## System Under Test Boundary

- System under test: the source tree at HEAD, the built `dist/` after `bun run build`, and `package.json` / `bun.lock`.
- Allowed stubs: none — these are pure ripgrep / grep / build-output checks.
- Disallowed: bypassing the build to test against a hand-edited bundle.

## Constraints

- All checks runnable from `scripts/run-tests.sh --static-only`; total runtime ≤ 30 s.
- AC-2 / AC-3 deny-list lives in `tests/security/banned-deps.json` so additions are visible in code review.
