INTEGRATION-CONTRACT.md

7.3 KB · raw

rendered · source

1# Test Expansion Integration Contract23Generated by session: `test coverage expansion`  4Agent: `claude-sonnet-4-6`  5Priority 1: T-001–T-010 (10 files), Priority 2: T-011–T-024 (11 files, T-011–T-014 in one file), Priority 3: T-025, T-030, T-037 (3 files)67---89## Test File Index1011| File | T-numbers | Asserts | Notes |12|------|-----------|---------|-------|13| `recovery-words.integrity.test.ts` | T-001 | 5 | Word list structural checks |14| `recovery-words.checksum.test.ts` | T-002 | 6 | Round-trip, swap, order, length |15| `recovery-words.kek.test.ts` | T-003 | 5 | HKDF round-trip, zero-pad bytes[16-31] |16| `totp.rfc6238.test.ts` | T-004 | 6 | RFC 6238 SHA1/256/512, boundary, URI parse |17| `peachPayload.bomb.test.ts` | T-005 | 4 | MV-4 length-bomb, decompressZstd NOT called |18| `backup.nfc-fallback.test.ts` | T-006 | 5 | LV-1 NFD-sealed unlocked with NFC |19| `pdf-import.sandbox.test.ts` | T-007 | 4 | MV-9 pdf.js hardened flags |20| `messages.batch-sanitize.test.ts` | T-008 | 6 | PCH-01-016 canary/tag sanitization |21| `license.verification.test.ts` | T-009 | 6 live + 2 todo | Ed25519 verify, structural checks |22| `chirp-transport.probe.test.ts` | T-010 | 3 | PCH-01-018 no-msg3 identity leak |23| `content.orchestration.test.ts` | T-011–T-014 | 0 live + 11 todo | All stubs (index.ts exports nothing) |24| `passkey.ed25519.test.ts` | T-015 | 7 | Ed25519 COSE, sign, verify, replay |25| `vault.rotate-sync-identity.test.ts` | T-016 | 7 | MV-8 rotation: new key, clear peers, recovery pending |26| `codex.multistripe.test.ts` | T-017 | 5 | Multi-stripe RS round-trip + erasure |27| `vault.corruption.test.ts` | T-018 | 5 live + 1 todo | corrupted vs wrong_key discrimination |28| `argon2id.kat.test.ts` | T-019 | 6 (1 skipped until KAT generated) | KDF params, determinism, NFC |29| `sync.disconnect.test.ts` | T-020 | 4 | PCH-01-026 #9 onerror/onclose |30| `import.csv.formulainjection.test.ts` | T-021 | 6 | Formula-injection round-trip |31| `messages.edit-origin.test.ts` | T-022 | 5 | GET_ENTRY_FOR_EDIT origin check, includeAll guard |32| `vault.consolidate-passkeys.test.ts` | T-023 | 4 | mergePasskeyOnlyIntoLogins lastUsed sort |33| `vault.purge-trash.test.ts` | T-024 | 5 | Retention cutoff, 0-day guard, count |34| `generate.empty-pool.test.ts` | T-025 | 8 | Empty pool fallback, 128-char, min/max |35| `ml.predictbatch.test.ts` | T-030 | 8 | Batch sizes, softmax stability |36| `clipboard.double-failure.test.ts` | T-037 | 4 | alreadyWritten skip, double-fail no throw |3738**Total: 24 test files, ~150 live assertions, ~13 todos**3940---4142## Real Crypto vs. Mocked Crypto (Priority 1)4344All Priority 1 tests use **real cryptographic primitives**:4546| Test | Crypto used | Notes |47|------|-------------|-------|48| T-001 | None | Word list structural |49| T-002 | SubtleCrypto AES-GCM, HKDF, BLAKE2s | Via `recovery-words.ts` |50| T-003 | SubtleCrypto HKDF, AES-GCM | Via `recovery-words.ts` |51| T-004 | HMAC-SHA1/256/512 | Via `otpauth` library |52| T-005 | Argon2id (m=65536, t=3, p=4), AES-GCM | `vi.mock("../../crypto/zstd")` for decompressZstd spy only |53| T-006 | Argon2id, AES-GCM | Via `backup.ts` / `derivePeachExportKey` |54| T-007 | None | `vi.mock("pdfjs-dist")` — testing flag plumbing only |55| T-008 | Argon2id, AES-GCM | Via full vault setup |56| T-009 | Ed25519 sign/verify | Local `validateLicenseWithKey` re-impl; prod `validateLicense` for structural checks |57| T-010 | Curve25519 DH (Noise XX) | Via `noiseXXInitiator` + `noiseXXResponder` |5859---6061## New Dependencies Added6263These dependencies are used in the draft tests but are already present in `package.json`:64- `@stablelib/x25519` — Noise XX keypair generation (T-010, T-020)65- `pako` — deflate/inflate for Codex tests (T-017)66- `hash-wasm` — Argon2id in T-005, T-006 (already used by production code)67- `otpauth` — TOTP generation (T-004, already used by production code)6869No new npm dependencies are required.7071---7273## Source Refactoring Recommendations7475### Required for T-011–T-014 (content orchestration) — HIGH PRIORITY76`src/content/index.ts` exports nothing. All orchestration state and functions77are module-private. To make the autofill orchestration tests runnable:7879```typescript80// src/content/index.ts — add these exports8182export { handleFieldInteraction }       // T-01283export { initialScan }                  // T-01384export { wasAlreadyFilled }             // T-0118586export const _testSeam = {87  getLastDismissedField(): HTMLInputElement | null { return lastDismissedField; },88  setLastDismissedField(f: HTMLInputElement | null): void { lastDismissedField = f; },89  isDismissLocked(): boolean { return dismissLock !== null; },90  DISMISS_LOCK_MS,91} as const;92```9394Additionally, the vitest environment for this file must be switched to `jsdom`:95```typescript96// vitest.config.ts97environmentMatchGlobs: [98  ['src/drafts/TEST-EXPANSION/content.orchestration.test.ts', 'jsdom'],99]100```101102### Required for T-009f/g (license + chrome storage)103Add `validateLicenseWithKey(keyString: string, pubKeyHex: string)` as an104exported helper in `src/background/license.ts` with injectable public key.105Currently the public key is hardcoded in a private `importPublicKey()` closure.106107### Required for T-018f (consumeLastUnlockFailureReason integration)108The test needs chrome.storage mock setup identical to T-008/T-016. The109`it.todo` can be promoted to a live test using the same mock pattern.110111### Recommended for T-019a (Argon2id KAT)112Add a script at `scripts/gen-argon2id-kat.ts` to generate the expected hash113vector and update `KAT_EXPECTED_HEX` in `argon2id.kat.test.ts`. Run once and114commit. See the inline documentation in the test for the script body.115116---117118## Environment Requirements119120| Test file | Environment | Notes |121|-----------|-------------|-------|122| All current tests | `node` (default vitest env) | — |123| `content.orchestration.test.ts` | `jsdom` required | Needs `environmentMatchGlobs` |124| `sync.disconnect.test.ts` | `node` | Uses `vi.stubGlobal("WebSocket", ...)` |125126---127128## CI/Exclusion Configuration129130The `vitest.config.ts` already excludes `src/drafts/**` from CI runs:131```typescript132exclude: ["src/drafts/**"]133```134135Draft tests do not run automatically. To promote a test file to CI, move it136from `src/drafts/TEST-EXPANSION/` to the canonical location beside its source137(e.g., `src/background/vault.rotate-sync-identity.test.ts`) and remove it from138the drafts directory.139140---141142## T-numbers Not Implemented143144The following Priority 3 test numbers from the brief were not implemented in145this session (available for follow-up):146147- **T-026**: timestamp-clamp + manifest-freshness boundaries148- **T-027**: full Codex UI round-trip e2e149- **T-028**: autofill real-page e2e150- **T-029**: inject.ts selector keyboard nav151- **T-031**: SW eviction mid-operation152- **T-032**: backup.ts empty-password contradiction153- **T-033**: Firefox passkey e2e154- **T-034**: LV-2 homograph UI surfacing155- **T-035**: HIBP breach-check integration156- **T-036**: reed-solomon try/finally free157- **T-038**: favicon canvas fallbacks158- **T-039**: chirp pairing failure paths159- **T-040**: sync alert queue bounds160161---162163## Summary Statistics164165| Category | Count |166|----------|-------|167| Priority 1 files | 10 |168| Priority 2 files | 11 |169| Priority 3 files | 3 |170| **Total draft files** | **24** |171| Live assertions (approx.) | ~150 |172| `it.todo` stubs | ~13 |173| Tests using real crypto | All P1 (except T-007 which tests flag plumbing) |174| Tests requiring source refactoring | T-011–T-014 (index.ts exports) |