Road to 10 — Wave 2 · PR-T5 (final)

Stub-fallback integration test

15 assertions · guards the 401 → stub swap path

What breaks without this test

Every feature-branch PR's docs build relies on the docs/stubs/analytics-stub being installable, importable, and shape-compatible with the real @yonatan-hq/analytics. If anyone later removes an export from the stub, renames the package, or breaks the type=module declaration, every PR's docs build fails at once with a confusing error. This test pins the contract.

What it locks

Local run output

▶ Test 1: stub structure
  ✓ stub directory exists
  ✓ package name is @yonatan-hq/analytics
  ✓ exports['.'].default is defined
  ✓ exports['./edge'].default is defined
  ✓ stub declares type=module (ESM)

▶ Test 2: dist outputs
  ✓ dist/index.js exists
  ✓ dist/edge.js exists
  ✓ dist/index.d.ts exists
  ✓ dist/edge.d.ts exists

▶ Test 3: ESM imports resolve without error
  ✓ imports resolve
  ✓ HQAnalytics is a function
  ✓ HQAnalytics() returns null/falsy (no-op component)
  ✓ edge POST + OPTIONS handlers are functions

▶ Test 4: simulate docs.yml's `npm pkg set ...`
  ✓ package.json rewrite succeeded
  ✓ rewritten package.json is still valid JSON

════════════════════════════════════════════════════════════════
  Total: 15  |  Passed: 15  |  Failed: 0
════════════════════════════════════════════════════════════════

Wave 2 complete (5 of 5)

PR-T1   formatStars unit test                ✓ merged (#1412)
PR-T2   sync_versions round-trip             ✓ merged (#1414)
PR-T3   Playwright E2E for landing           open (#1415)
PR-T4   handoff bundle schema validator      open (#1416)
PR-T5   stub-fallback integration test       ← THIS PR, last of wave