docs(02-01): complete RED gate — 3 test files pin D-P2-01 + D-P2-02 + D-P2-03 + F2
Plan 02-01 Wave 0 RED gate closed. Three failing test files (16 it()
blocks total: 11 RED + 5 GREEN regression guards) pin the locked
decisions for Phase 2 ahead of Plans 02-02 + 02-03 implementation:
- blob-url-download.test.ts (3 RED) — D-P2-01 offscreen Blob URL
pipeline (closes audit P0-6: base64 data: URL → blob: URL).
- meta-json-urls-schema.test.ts (5 RED) — D-P2-02 meta.url → meta.urls
migration + F2 empty-tracker → urls:[] resolution.
- strict-meta-json-validation.test.ts (3 RED + 5 GREEN) — D-P2-03
strict 8-field schema validation with EXPECTED_KEYS pin including
planner-suggested `schemaVersion` 8th field.
Test count delta: 155 GREEN → 159 GREEN + 11 RED (+4 GREEN regression
guards, +11 RED test contracts). Vitest reporter:
Test Files 4 failed | 27 passed (31)
Tests 12 failed | 159 passed (171)
(12 failed = 3 + 5 + 3 RED from this plan + 1 pre-existing flaky
ffprobe test in webm-remux.test.ts — out of scope; documented in
SUMMARY.md Deferred Issues.)
Tier-1 grep gate: 13/13 GREEN preserved (this plan touches no
production code).
Planner-resolved tensions carried forward in SUMMARY.md:
- D-P2-03 'non-empty urls[]' vs CONTEXT.md permissive empty-array →
F2 resolved in favor of permissive (Test 3 of Task 3 relaxed).
- 8th field name `schemaVersion` → tentative planner pick;
Plan 02-03 implementer commits to schemaVersion: '2' const.
- tab-url-tracker module seam → planner-suggested name
`src/background/tab-url-tracker.ts` with getTabUrlsSeen() export.
- Plan claim 'ALL 8 fail' reconciled honestly: 3 RED + 5 GREEN
regression guards (timestamp/semver/totalEvents/buffer-seconds/
duration-minutes already match current 7-field shape).
Plan suggestions reconciled with reality:
- vitest env: 'node' not 'jsdom' (Node 24 has URL/Blob/performance
globals; jsdom not in devDeps). FileReader polyfill inline.
- Task 2 Test 1 source-text scan instead of tsc-compile-failure
(vitest.config.ts typecheck:{enabled:false}).
Per worktree-mode constraint: STATE.md, ROADMAP.md, REQUIREMENTS.md
NOT modified. The orchestrator owns those writes after all worktree
agents in Wave 0 complete.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
223
.planning/phases/02-stabilize-export-pipeline/02-01-SUMMARY.md
Normal file
223
.planning/phases/02-stabilize-export-pipeline/02-01-SUMMARY.md
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
---
|
||||||
|
phase: 02-stabilize-export-pipeline
|
||||||
|
plan: 01
|
||||||
|
subsystem: testing
|
||||||
|
tags:
|
||||||
|
- tdd
|
||||||
|
- red-tests
|
||||||
|
- blob-url-migration
|
||||||
|
- meta-json-urls-array
|
||||||
|
- schema-validation
|
||||||
|
- p0-6
|
||||||
|
- p1-10
|
||||||
|
- wave-0
|
||||||
|
- export-pipeline
|
||||||
|
|
||||||
|
# Dependency graph
|
||||||
|
requires:
|
||||||
|
- phase: 01-stabilize-video-pipeline
|
||||||
|
provides: createArchive + remuxSegments + chrome stub patterns + raw-3ebml-concat.webm fixture (Plan 01-08 Wave 0 RED precedent)
|
||||||
|
provides:
|
||||||
|
- "3 failing test files (16 it() blocks total) pinning D-P2-01 + D-P2-02 + D-P2-03 + F2 contracts ahead of Plans 02-02 and 02-03 implementation"
|
||||||
|
- "Blob URL download wire-format contract (chrome.downloads.download arg0.url starts with blob:, not data:application/zip;base64,)"
|
||||||
|
- "URL.revokeObjectURL lifecycle contract (revoke fires on chrome.downloads.onChanged 'complete')"
|
||||||
|
- "SessionMetadata.urls: string[] type-shape contract via source-text scan"
|
||||||
|
- "createArchive meta.json shape contract (urls Array, no url field)"
|
||||||
|
- "tab-url-tracker module seam (src/background/tab-url-tracker.ts with getTabUrlsSeen(): string[])"
|
||||||
|
- "URL filter contract (include https + chrome-extension://; exclude chrome:// + about:)"
|
||||||
|
- "Empty-tracker F2 contract (meta.urls === [] for whole-desktop-no-tab sessions)"
|
||||||
|
- "Strict 8-field meta.json schema with EXPECTED_KEYS pin including planner-suggested schemaVersion 8th field"
|
||||||
|
- "FileReader polyfill pattern for vitest Node-env Blob ingestion through JSZip"
|
||||||
|
affects:
|
||||||
|
- Plan 02-02 (offscreen Blob URL pipeline implementation)
|
||||||
|
- Plan 02-03 (meta.json urls[] migration + tab-url-tracker + schema validation)
|
||||||
|
- Plan 02-04 (UAT harness extensions A24+ — pre-checkpoint bundle gates)
|
||||||
|
- All future phases that consume meta.json (downstream UAT harness, server-upload candidates)
|
||||||
|
|
||||||
|
# Tech tracking
|
||||||
|
tech-stack:
|
||||||
|
added:
|
||||||
|
- "FileReader polyfill (Node 24 lacks FileReader; JSZip needs it for Blob ingestion)"
|
||||||
|
- "vi.doMock for remuxSegments short-circuit (6 MB synthetic stress test)"
|
||||||
|
- "Source-text scan for type-shape pinning (workaround for vitest.config.ts typecheck:{enabled:false})"
|
||||||
|
patterns:
|
||||||
|
- "RED-gate triple-test pattern: WIRE-FORMAT polarity guard + LATENCY budget + LIFECYCLE pin (Test 2's necessary-not-sufficient latency + wire-format combo)"
|
||||||
|
- "Missing-module RED via dynamic-import-in-try/catch + expect.fail (mirrors Plan 01-08 webm-remux.test.ts precedent)"
|
||||||
|
- "Three-slice fixture pattern (SEG1/SEG2/SEG3 byte offsets from raw-3ebml-concat.webm) for muxer-safe segmentation"
|
||||||
|
- "Per-test SAVE_ARCHIVE drain helper: dispatch SAVE_ARCHIVE → resolve REQUEST_BUFFER with synthetic segments → loop until chrome.downloads.download called"
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created:
|
||||||
|
- "tests/background/blob-url-download.test.ts (3 RED tests, ~625 lines; pins D-P2-01)"
|
||||||
|
- "tests/background/meta-json-urls-schema.test.ts (5 RED tests, ~671 lines; pins D-P2-02 + F2)"
|
||||||
|
- "tests/build/strict-meta-json-validation.test.ts (3 RED + 5 GREEN regression-guard tests, ~621 lines; pins D-P2-03 + F2)"
|
||||||
|
modified: []
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "Use vitest default `node` env instead of jsdom: Node 24 ships URL.createObjectURL + URL.revokeObjectURL + performance + Blob as globals. Plan's suggestion to use jsdom was incorrect (vitest.config.ts explicitly sets environment: 'node' and jsdom is not in devDependencies)."
|
||||||
|
- "FileReader polyfill inline in each test file: Node 24 lacks FileReader; JSZip's Blob ingestion path needs it. Minimal polyfill (delegates to Blob.arrayBuffer()) installed at bootSwInRecState time."
|
||||||
|
- "vi.doMock('../../src/background/webm-remux') for Test 2's 6 MB scale: production muxer rejects monotonicity-breaking input shapes, so a synthetic 6 MB Blob via vi.doMock is the cleanest way to stress the download wire-format under the data-URL-cap-exceeding scale."
|
||||||
|
- "Test 1 (SessionMetadata shape pin) uses source-text scan instead of tsc compile failure: vitest.config.ts has typecheck:{enabled:false}, so a tsc-failure-based pin would be a no-op. Source-text regex against src/shared/types.ts is the RED gate that survives the typecheck-disabled config."
|
||||||
|
- "EXPECTED_KEYS 8th field tentatively `schemaVersion`: marks D-P2-02 url→urls breaking-change cutover. Plan 02-03's implementer commits to adding `schemaVersion: '2'` as a constant. Test file is canonical place to amend if a stronger 8th-field argument surfaces."
|
||||||
|
- "Tests 2, 4, 5, 6, 7 of Task 3 stay GREEN-today as regression guards: plan's 'ALL 8 fail' claim wasn't achievable (timestamp/semver/totalEvents/videoBufferSeconds/logDurationMinutes already match the current 7-field shape). Documented honestly; the GREEN-today tests pin the post-migration schema for regression-guard duty."
|
||||||
|
- "tab-url-tracker module seam: src/background/tab-url-tracker.ts with export `getTabUrlsSeen(): string[]`. Tests 3+4+5 of Task 2 use dynamic-import-with-expect.fail to surface the missing module as the RED signal. Plan 02-03 implements the module."
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "RED-gate triple-pin pattern: (1) precondition (download was called), (2) polarity guard (forbidden prefix absent), (3) target contract (required prefix present). Test 1 of blob-url-download.test.ts exemplifies."
|
||||||
|
- "Wire-format-at-scale pattern: synthetic-payload stress test + wire-format guard. The latency check is necessary but not sufficient — the wire-format guard converts a sub-budget spurious pass into a meaningful RED. Test 2 of blob-url-download.test.ts."
|
||||||
|
- "Source-text type-shape pin: when vitest typecheck is disabled, fall back to a regex scan of the source file body. Captures both presence (new field exists) and absence (old field removed) in one test."
|
||||||
|
- "Per-test SAVE_ARCHIVE driver helper: factored out runSaveAndCaptureArchiveBlob / runSaveAndCaptureDownloadArg / runAndParseMetaJson with a shared try-fire-REQUEST_BUFFER-loop. Future Phase 2 tests inherit this pattern."
|
||||||
|
- "GREEN-today regression-guard tests bundled with RED-today migration tests: same describe block, same setup, but the assertions are scoped to pin different layers (migration RED + stability GREEN). Future TDD plans can mix these explicitly."
|
||||||
|
|
||||||
|
requirements-completed: []
|
||||||
|
# Per plan instructions: requirements (REQ-archive-export-latency,
|
||||||
|
# REQ-meta-json-schema) are NOT completed by this plan — they're
|
||||||
|
# pinned by RED tests here and IMPLEMENTED + GREEN-flipped by Plans
|
||||||
|
# 02-02 + 02-03. Marking them complete now would be incorrect per
|
||||||
|
# CLAUDE.md "no premature requirement marking" lesson from Plan 01-01
|
||||||
|
# (see STATE.md "[Phase ?]: Reverted premature REQ-video-ring-buffer
|
||||||
|
# Complete marking left by Plan 01-01").
|
||||||
|
|
||||||
|
# Metrics
|
||||||
|
duration: ~20min
|
||||||
|
completed: 2026-05-20
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 02 Plan 01: Wave-0 RED tests for export pipeline migration
|
||||||
|
|
||||||
|
**Three failing test files (16 it() blocks) pin D-P2-01 Blob URL download contract + D-P2-02 meta.json urls[] migration + D-P2-03 strict 8-field schema validation + F2 empty-tracker resolution, ahead of Plan 02-02 + 02-03 implementation.**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** ~20 min
|
||||||
|
- **Started:** 2026-05-20T13:13:59Z (baseline test capture)
|
||||||
|
- **Completed:** 2026-05-20T13:33:38Z (final commit + SUMMARY)
|
||||||
|
- **Tasks:** 3/3 completed
|
||||||
|
- **Files created:** 3 test files (1 917 lines total)
|
||||||
|
- **Files modified:** 0 production-code files (this is the RED gate ONLY)
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
### Task 1: tests/background/blob-url-download.test.ts (3 RED)
|
||||||
|
|
||||||
|
Pins D-P2-01 (offscreen-minted Blob URL pipeline; closes audit P0-6).
|
||||||
|
|
||||||
|
- **Test 1 (wire-format polarity guard):** `chrome.downloads.download` is called with a `url` that starts with `blob:` and does NOT start with `data:application/zip;base64,`. RED today; concrete assertion error: `chrome.downloads.download was called with url='data:application/zip;base64,UEsDBAoAAAAAAL1qtFw...' — D-P2-01 forbids data:application/zip;base64, prefix`.
|
||||||
|
- **Test 2 (latency + wire-format at 6 MB scale):** A 6 MB archive completes in under 5 000 ms AND emits a `blob:` URL. The vi.doMock on remuxSegments short-circuits the muxer to inject a synthetic 6 MB Blob. RED today via the wire-format guard (data: URL prefix); GREEN after Plan 02-02. Elapsed ~1 266 ms (well under budget).
|
||||||
|
- **Test 3 (revoke lifecycle):** `URL.revokeObjectURL` is scheduled with the same URL passed to `chrome.downloads.download` once `chrome.downloads.onChanged` reports `state.current === 'complete'`. RED today; concrete error: `chrome.downloads.onChanged._callbacks.length === 0 at probe time` (current downloadArchive does not register an onChanged listener).
|
||||||
|
|
||||||
|
**Commit:** [748a81f](#) `test(02-01): RED — pin Blob URL download contract (D-P2-01)`
|
||||||
|
|
||||||
|
### Task 2: tests/background/meta-json-urls-schema.test.ts (5 RED)
|
||||||
|
|
||||||
|
Pins D-P2-02 (meta.json url→urls migration) + F2 empty-tracker resolution.
|
||||||
|
|
||||||
|
- **Test 1 (SessionMetadata type-shape via source-text scan):** `src/shared/types.ts` MUST contain `urls: string[]` AND MUST NOT contain `url:` (singular) inside the SessionMetadata interface body. Workaround for vitest typecheck:{enabled:false}. RED today; concrete error: `'urls: string[]' field not present`.
|
||||||
|
- **Test 2 (createArchive meta.json shape):** Real createArchive output has `Array.isArray(meta.urls) === true` AND `meta.url === undefined`. RED today; concrete error: `meta.urls is not an Array. Got: undefined`.
|
||||||
|
- **Tests 3+4+5 (tab-url-tracker module seam):** Each test dynamically imports `src/background/tab-url-tracker` (the planner-suggested module name from Plan 02-03) and `expect.fail`s with a precise GREEN-gate contract message when the module doesn't exist. RED today; module missing.
|
||||||
|
- Test 3 pins dedup + first-seen-first order: ['A', 'B', 'A'] → ['A', 'B'].
|
||||||
|
- Test 4 pins URL filter: include https + chrome-extension://; exclude chrome:// + about:.
|
||||||
|
- Test 5 pins F2 empty-tracker contract: no observations → `getTabUrlsSeen() === []` (NOT undefined, NOT [<origin>], NOT null).
|
||||||
|
|
||||||
|
**Commit:** [9e45d33](#) `test(02-01): RED — pin meta.json urls[] schema + dedup/filter + empty-tracker (D-P2-02 + F2)`
|
||||||
|
|
||||||
|
### Task 3: tests/build/strict-meta-json-validation.test.ts (3 RED + 5 GREEN regression guards)
|
||||||
|
|
||||||
|
Pins D-P2-03 strict 8-field meta.json schema validation.
|
||||||
|
|
||||||
|
- **Test 1 (RED): exactly 8 fields.** Current shape has 7. Concrete error: `meta.json has 7 fields; D-P2-03 requires exactly 8. Current keys: [timestamp, url, userAgent, extensionVersion, videoBufferSeconds, logDurationMinutes, totalEvents]`.
|
||||||
|
- **Test 2 (GREEN regression guard): ISO-8601 Z-suffix timestamp.** Current `new Date().toISOString()` already matches; catches future locale-formatter regressions.
|
||||||
|
- **Test 3 (RED): urls Array of valid URLs (empty permitted per F2).** Concrete error: `meta.urls is not an Array. Got: undefined`.
|
||||||
|
- **Test 4 (GREEN regression guard): semver extensionVersion.** Current manifest.version '1.0.0' matches; catches build-hash regressions.
|
||||||
|
- **Test 5 (GREEN regression guard): non-negative integer totalEvents.** Current sum-of-event-counts matches; catches negative/float regressions.
|
||||||
|
- **Test 6 (GREEN regression guard): videoBufferSeconds === 30 literal.** CON-video-window pin.
|
||||||
|
- **Test 7 (GREEN regression guard): logDurationMinutes === 10 literal.** CON-event-log-window pin.
|
||||||
|
- **Test 8 (RED): no extra fields beyond EXPECTED_KEYS.** Concrete error: `meta.json contains extra (unexpected) fields: ["url"]`. EXPECTED_KEYS = [timestamp, urls, userAgent, extensionVersion, videoBufferSeconds, logDurationMinutes, totalEvents, schemaVersion].
|
||||||
|
|
||||||
|
**Commit:** [94e0346](#) `test(02-01): RED — pin strict 8-field meta.json schema validation (D-P2-03)`
|
||||||
|
|
||||||
|
## Test count delta
|
||||||
|
|
||||||
|
- **Before:** 155 GREEN (baseline including sw-bundle-import.test.ts after npm run build).
|
||||||
|
- **After:** 159 GREEN + 11 RED (11 new RED from this plan + the 5 Task-3 GREEN-today regression guards count as +4 net new GREEN since Test 5 was added per F2; see "Plan vs reality" below).
|
||||||
|
- **Net delta:** +11 RED, +4 GREEN tests (was 155, now 170 vitest-discovered + 1 ffprobe-flaky out-of-scope; see Deferred Issues).
|
||||||
|
|
||||||
|
Vitest reporter final state:
|
||||||
|
```
|
||||||
|
Test Files 4 failed | 27 passed (31)
|
||||||
|
Tests 12 failed | 159 passed (171)
|
||||||
|
```
|
||||||
|
(12 failed = 3 [Task 1] + 5 [Task 2] + 3 [Task 3 RED] + 1 [pre-existing ffprobe-flaky webm-remux test — out of scope; see Deferred Issues].)
|
||||||
|
|
||||||
|
## Tier-1 grep gate
|
||||||
|
|
||||||
|
`tests/background/no-test-hooks-in-prod-bundle.test.ts` continues to pass with 13/13 GREEN (FORBIDDEN_HOOK_STRINGS at the existing inventory; this plan touches no production code).
|
||||||
|
|
||||||
|
## Plan-vs-reality reconciliation
|
||||||
|
|
||||||
|
### Plan claim: "ALL 8 [strict-validation] tests MUST fail under current HEAD"
|
||||||
|
|
||||||
|
**Reality:** 3 of 8 are RED-today (Tests 1, 3, 8 — the migration-driven assertions). The other 5 are GREEN-today regression guards (timestamp regex, semver, totalEvents, videoBufferSeconds, logDurationMinutes — all of which already match the current 7-field shape).
|
||||||
|
|
||||||
|
**Resolution:** Honored the plan's spirit (8 strict-validation tests pinning the post-migration schema) while being honest about the test states. The 5 GREEN-today tests are not test pollution — they're regression guards that prevent Plan 02-03 from accidentally regressing the unchanged fields when adding `urls` + `schemaVersion`.
|
||||||
|
|
||||||
|
### Plan suggestion: "Use jsdom env (default in vitest.config.ts)"
|
||||||
|
|
||||||
|
**Reality:** vitest.config.ts explicitly sets `environment: 'node'` and jsdom is not in devDependencies. Node 24 ships URL.createObjectURL + URL.revokeObjectURL + performance + Blob as globals (verified at land time), so jsdom is not required. FileReader is the only missing global; a minimal polyfill inline in each test file delegates to Blob.arrayBuffer().
|
||||||
|
|
||||||
|
### Plan suggestion: "Test 1 fails at the TypeScript-compile layer"
|
||||||
|
|
||||||
|
**Reality:** vitest.config.ts has `typecheck: { enabled: false }`. A tsc-failure-based pin would be a no-op. Replaced with a source-text regex scan of `src/shared/types.ts` that asserts both presence of `urls: string[]` AND absence of `url:` inside the SessionMetadata interface body.
|
||||||
|
|
||||||
|
## Planner-resolved tensions (carried forward into Plans 02-02 + 02-03)
|
||||||
|
|
||||||
|
- **D-P2-03 "non-empty urls[]" vs CONTEXT.md `<specifics>` permissive empty-array clause:** resolved in favor of the permissive clause (F2 — empty IS PERMITTED for whole-desktop-no-tab sessions). Test 3 of Task 3 enforces the relaxed contract.
|
||||||
|
- **8th field name `schemaVersion`:** TENTATIVE PLANNER PICK to mark the D-P2-02 url→urls breaking-change cutover. EXPECTED_KEYS constant in `tests/build/strict-meta-json-validation.test.ts` pins this choice; Plan 02-03's implementer COMMITS to adding `schemaVersion: '2'` as a constant in `src/background/index.ts`. If a stronger argument for a different 8th-field name surfaces, this test file is the canonical place to amend.
|
||||||
|
- **tab-url-tracker module name `src/background/tab-url-tracker.ts`:** PLANNER-SUGGESTED. Plan 02-03's implementer commits to this name; if renaming is desired, all three Task 2 dynamic-import strings need to update lockstep.
|
||||||
|
- **`_resetForTesting` / `_observeForTesting` ergonomic hooks on tab-url-tracker:** OPTIONAL contract the test file documents. Plan 02-03 implementer SHOULD expose these for Tests 3+4+5 ergonomic wiring; if absent, the tests need to wire chrome.tabs.onUpdated callbacks directly.
|
||||||
|
|
||||||
|
## Forward links
|
||||||
|
|
||||||
|
- **Plan 02-02 (Wave 1 GREEN):** flips Task 1's 3 RED tests by minting the Blob URL in the offscreen document via `URL.createObjectURL`, transferring it to the SW via a new port-bridge message, and registering the `chrome.downloads.onChanged` listener for `URL.revokeObjectURL` lifecycle.
|
||||||
|
- **Plan 02-03 (Wave 1 GREEN):** flips Task 2's 5 RED tests + Task 3's 3 RED tests by (a) amending `src/shared/types.ts` to swap `url: string` for `urls: string[]`, (b) implementing `src/background/tab-url-tracker.ts` with `getTabUrlsSeen()` fed by chrome.tabs.onUpdated + chrome.tabs.onActivated listeners (DEC-011 Amendment 1 `tabs` permission), (c) amending `createArchive` in `src/background/index.ts` to call `snapshotOpenTabs() + getTabUrlsSeen()` and write `urls` + `schemaVersion: '2'` to meta.json (removing the old `url:` field).
|
||||||
|
- **Plan 02-04 (Wave 2 UAT extensions):** harness A24+ assertions read the GREEN-flipped meta.json. A28 (added per F1) pins REQ-archive-layout strict zip-layout (5 entries exact).
|
||||||
|
|
||||||
|
## Deferred Issues
|
||||||
|
|
||||||
|
### Pre-existing flaky test in tests/background/webm-remux.test.ts
|
||||||
|
|
||||||
|
The `ffprobe -count_frames reports between 905 and 912 frames inclusive` test (Plan 01-08 Task 2) fails when run as part of the full-suite parallel runner but passes when run in isolation. The failure surface is intermittent; the input fixture (`raw-3ebml-concat.webm`) and `remuxSegments` output are deterministic. Suspected cause: ffprobe spawnSync timing interaction with parallel vitest workers, or transient tmpdir contention.
|
||||||
|
|
||||||
|
- **Out of scope** for this plan per Plan 02-01 §verification: this plan touches no production code and no Phase 1 test file.
|
||||||
|
- **Scope boundary**: not directly caused by current plan changes (verified by running the test in isolation post-commit).
|
||||||
|
- **Recommended owner:** Phase 5 hardening OR a Phase 2 closure debug session if the flake recurs during Plans 02-02 / 02-03 execution. If the flake blocks Phase 2 plan-checker or operator empirical UAT, escalate to a /gsd-debug session.
|
||||||
|
|
||||||
|
## Self-Check: PASSED
|
||||||
|
|
||||||
|
### Files created (verified via stat at SUMMARY commit time)
|
||||||
|
|
||||||
|
- FOUND: tests/background/blob-url-download.test.ts (~625 lines)
|
||||||
|
- FOUND: tests/background/meta-json-urls-schema.test.ts (~671 lines)
|
||||||
|
- FOUND: tests/build/strict-meta-json-validation.test.ts (~621 lines)
|
||||||
|
|
||||||
|
### Commits exist (verified via git log)
|
||||||
|
|
||||||
|
- FOUND: 748a81f test(02-01): RED — pin Blob URL download contract (D-P2-01)
|
||||||
|
- FOUND: 9e45d33 test(02-01): RED — pin meta.json urls[] schema + dedup/filter + empty-tracker (D-P2-02 + F2)
|
||||||
|
- FOUND: 94e0346 test(02-01): RED — pin strict 8-field meta.json schema validation (D-P2-03)
|
||||||
|
|
||||||
|
### Plan §verification gates
|
||||||
|
|
||||||
|
- Task 1: `npx vitest run tests/background/blob-url-download.test.ts` → 3 failed (3) ✓
|
||||||
|
- Task 2: `npx vitest run tests/background/meta-json-urls-schema.test.ts` → 5 failed (5) ✓
|
||||||
|
- Task 3: `npx vitest run tests/build/strict-meta-json-validation.test.ts` → 3 failed | 5 passed (8) ✓ (5 GREEN = regression guards per plan-vs-reality reconciliation above)
|
||||||
|
- Skip discipline: `grep -cE "\.skip\(|\.skip$|\.skip[, ]"` returns 0 for all three files ✓
|
||||||
|
- Tier-1 grep gate: `npx vitest run tests/background/no-test-hooks-in-prod-bundle.test.ts` → 13/13 GREEN preserved ✓
|
||||||
|
|
||||||
|
### Success criteria reconciliation
|
||||||
|
|
||||||
|
1. [x] Three RED test files exist with concrete failure messages under current HEAD (3 + 5 + 3 = 11 RED).
|
||||||
|
2. [x] `meta-json-urls-schema.test.ts` Test 1 fails (source-text scan; the planner's tsc-compile-failure path was a no-op due to typecheck:{enabled:false}, but the source-text scan is a stronger structural pin that survives the disabled-typecheck config).
|
||||||
|
3. [x] Tier-1 grep gate (FORBIDDEN_HOOK_STRINGS inventory) remains GREEN (13/13).
|
||||||
|
4. [x] UAT harness baseline UNCHANGED (test-only changes; this plan touches no production-source code).
|
||||||
|
5. [x] Commits land with `test(02-01): RED — ...` prefix matching Plan 01-02 / 01-13 RED-test precedent.
|
||||||
Reference in New Issue
Block a user