asdfas
0

Configure Feed

Select the types of activity you want to include in your feed.

H12: mark shipped in roadmap + plan (bundle builds, gateway wired, harness green)

+39 -1
+11 -1
h12-verifier-sw-plan.md
··· 84 84 (`platform:"browser"`, `noExternal`, `noNodeBuiltinsPlugin` guard, `node:timers/promises` stub). 85 85 - **Done:** `apps/gateway/src/main.ts` — reads `packages/verify/dist/sw.js` at startup (`SW_SCRIPT_PATH` 86 86 override), wires `opts.sw = { path:"/sw.js", script }`. **Not yet typechecked/built** (blocked on bundle). 87 - - **BUNDLE BLOCKER — RESOLVED, alias map below (NEXT ACTION).** The browser build fails because 87 + - **✅ DONE (2026-07-17) — bundle builds, gateway wired, harness green, merged to `main`.** The browser 88 + IIFE `dist/sw.js` builds browser-clean; `@minisite/verify` + `apps/gateway` build+typecheck; the Playwright 89 + harness (`test/sw-harness.test.ts`) proves the compiled SW verifies (positive) and fails closed on tamper 90 + (negative 502). Full gate: 1252 tests / 86 files. Bundle fix = `@atproto/common` alias stub + 91 + `buffer` polyfill (resolver plugin past the guard) + `sw.js` output name — see `packages/verify/ 92 + tsup.config.ts` and `src/sw-shims/*.ts`. **Q-A answered:** reused the frozen fixtures (no new signing 93 + helper); the SW's cross-origin reads are route-mocked in Playwright (confirmed: `context.route` intercepts 94 + service-worker fetches). **Q-B answered:** the chain bundles clean once `@atproto/common` is aliased and 95 + `Buffer`/`node:timers/promises` are shimmed. Remaining: SRI (deferred), deploy via `railway up` (separate). 96 + Everything below is the historical blocker analysis. 97 + - **BUNDLE BLOCKER — RESOLVED, alias map below (was NEXT ACTION; now DONE per above).** The browser build failed because 88 98 `@atproto/repo`'s barrel → `repo/dist/logger.js` → `@atproto/common` barrel drags in `node:fs`, 89 99 `node:fs/promises`, `node:stream`, `node:zlib`, `node:crypto`. **All four are dead-but-imported on the 90 100 verify path** (createHash lives only in `common/dist/ipld.js`'s `VerifyCidTransform`, never instantiated;
+28
roadmap.md
··· 466 466 read-back does not re-derive the pins from the stored records. Closing that needs a second write, not a 467 467 stricter comparison. 468 468 469 + ✅ **SHIPPED (2026-07-17)** — **H12 — the verifier service worker is now wired, served, and proven in a real 470 + browser** (merged to `main`; NOT yet deployed — deploy is a separate `railway up`). The root-scope SW *is* 471 + the gateway verifier: after first hit the gateway is untrusted for content (§9.3/§9.4). What landed: 472 + - `packages/verify/src/sw-entry.ts` — the classic-script entry: `deriveTarget()` reverses the per-site 473 + origin host (`<siteRkey>--<did-suffix>`) to the target AT-URI (passthrough when the host carries no 474 + reversible identity); `lazyReaderForTarget()` builds the verifying `atpReader` (records + DID doc read 475 + CROSS-ORIGIN DIRECT — plc.directory + owner PDS — never proxied through the gateway, that independence is 476 + §11.3); `raslFetcher()` reads blob bytes same-origin from `/.well-known/rasl/<cid>` (re-hashed by 477 + `VerifyingCache`, so trustless). Lives in `@minisite/verify` because it's the only package depending on 478 + both the verifier and `@minisite/gateway`; the reverse edge stays forbidden. 479 + - `packages/verify/tsup.config.ts` — a browser IIFE build emitting `dist/sw.js` (a classic self-contained 480 + script the injected `register("sw.js")` can load). The blocker (`@atproto/repo`→`@atproto/common` dragging 481 + `node:fs/stream/zlib/crypto` into the bundle) is severed by aliasing `@atproto/common` → a no-op 482 + `subsystemLogger` stub (audited: the verify path consumes only that export, and never invokes it); a 483 + `Buffer` polyfill (`buffer` npm pkg, injected) covers `repo`'s `Buffer.concat`; the `node:timers/promises` 484 + yield stays a microtask stub. Bundle verified browser-clean (0 `node:` builtins, 0 `process.env`). 485 + - `apps/gateway/src/main.ts createServerFromEnv()` — reads `packages/verify/dist/sw.js` at startup 486 + (`SW_SCRIPT_PATH` override) and sets `opts.sw = { path: "/sw.js", script }`; `http.ts` serves it 487 + `no-cache` (§9.5). SRI/integrity deferred (§9.5 SHOULD). Dockerfile already ships `packages/verify/dist/`. 488 + - **First wiring = first execution, and it's proven.** `packages/verify/test/sw-harness.test.ts` loads the 489 + built `dist/sw.js` into headless Chromium (Playwright) on a derived per-site origin and asserts: (positive) 490 + the SW serves the site's signed `/index.html` verified end-to-end; (negative) tampered same-origin blob 491 + bytes → the SW FAILS CLOSED (502), never serving forged bytes. Frozen fixtures in 492 + `packages/gateway/test/fixtures/sw/` (also driven in Node by `sw-fixture.test.ts`). Gate: 1252 tests / 86 493 + files green. **The gate now requires a Chromium binary** (`pnpm --filter @minisite/verify exec playwright 494 + install chromium`). Deferred: SRI; the SW on slug/custom-domain origins (needs the `<meta>`-target path — 495 + `bootstrapHtml` emits it, still read by nobody). 496 + 469 497 **H12 — Verifier SW never served; a dead `sw.js` registration is baked into every site's root CID; an author 470 498 SW is neutralized then registered at root scope (inverse of §9.3).** `packages/gateway/src/sw.ts 471 499 registerServiceWorker()` is never called; `apps/gateway/src/main.ts` never sets `opts.sw`;