diff --git a/docs/plans/archive/PLAN-timer.md b/docs/plans/archive/PLAN-timer.md index 1e813ac..ea79663 100644 --- a/docs/plans/archive/PLAN-timer.md +++ b/docs/plans/archive/PLAN-timer.md @@ -562,3 +562,61 @@ If any test in §17.2 fails, the agent must: 3. Re-run the full §17.2 suite. 4. Only if the preferred remediation does not resolve it, report back with the failure detail and the pinned-version fallback **for owner decision** — never silently change versions (guardrail 12). + +### 17.5 Spike results — RUN 2026-09-07 (scratch dir /tmp/timer-spike) + +Setup: hand-written package.json (react-scripts 5.0.1, react 18.2.0, +@atproto/api 0.20.41, @atproto/oauth-client-browser 0.5.4 latest; CRA's +generator is broken on this machine under npm 11.19 allow-scripts — known +pitfall, see plan-intake skill). Node 26.8.1, npm 11.19.0. + +| Test (§17.2) | Result | Notes | +|---|---|---| +| 1 Scaffold + install | PASS | npm install clean (benign core-js install-scripts warnings only) | +| 2 Import smoke | PASS | Component importing `BskyAgent` + `@atproto/oauth-client-browser` mounts and asserts `import-ok` in Jest; webpack compiles the graph | +| 3 Prod build | PASS | exit 0, "Compiled successfully", build/index.html + hashed main.f39ba698.js (211 kB gzip) | +| 4 Dev server | PASS | "Compiled successfully!", HTTP 200 bundle.js (5.1 MB), atproto code present, no module-parse errors | +| 5 Jest trivial test importing atproto | PASS (after remediation) | see stack below | +| 6 Runtime OAuth round trip | NOT RUN — blocked | needs throwaway-account creds + metadata hosted at https://timer.psingletary.com/client-metadata.json (domain up, metadata not deployed). Not a code failure; re-run post-S11 or when owner supplies a throwaway account | +| 7 Bundle integrity | PASS | atproto code in bundle (5660 refs), no empty chunks, no unresolved/externalized warnings | + +**Verdict: build risk (F1–F4, F7) is CLEAR at latest versions — webpack 5 +bundles @atproto 0.20.41 + oauth-client-browser 0.5.4 with zero config.** +The ESM risk that made slicer pin versions does not materialize in the +bundler. The failures are confined to Jest (CJS, jest 27 under CRA 5). + +**Jest remediation stack actually required (test 5), in order:** +1. `test` script → `craco test`; add `@craco/craco@^7.1.0` (dev). +2. `craco.config.js` jest.configure: + - `transformIgnorePatterns: []` — transform ALL node_modules (a + whitelist regex alone still left atproto dist files raw). + - `moduleNameMapper`: `^multiformats/(.*)$` → + `/node_modules/multiformats/dist/src/$1.js`, + `^multiformats$` → `.../index.js`, `^await-lock$` → + `/node_modules/await-lock/build/AwaitLock.js` — jest 27 + cannot read package.json `exports` maps. + - override the js transform to `babel-jest` with + `babel-preset-react-app` + `@babel/plugin-transform-class-static-block` + (preset-react-app does not enable class-static-block transform; + @atproto 0.20 dist uses static class blocks). +3. `src/setupTests.js`: `require("@testing-library/jest-dom")` + polyfills: + TextEncoder/TextDecoder (util), crypto (node webcrypto), TransformStream/ + ReadableStream/WritableStream (stream/web), BroadcastChannel + (worker_threads). CRA auto-loads setupTests.js; jest 27's jsdom env lacks + all of these and atproto references them at import time. +4. Test runs need `--forceExit` (BroadcastChannel polyfill keeps an open + handle). jsdom also lacks navigator.locks — oauth-client-browser emits a + benign console.warn and falls back. +5. Test files that render JSX need `import React from "react"` (classic + runtime under preset-react-app in tests). + +**Impact on S13:** the plan's Jest tests target pure `src/lib/` logic +(deadline math, list-name→duration map) which does NOT import @atproto — +those pass under default CRA Jest with no shims. The shim stack is only +needed if a test must import @atproto directly. Copy the spike's +craco.config.js + setupTests.js into the app (S2) only if/when such a test +is written; do not add CRACO to the app preemptively. + +**Test 6 disposition:** defer to post-deploy (S11) or when a throwaway +account is available; it exercises DPoP/PAR in-browser, which the §17 risk +statement (bundling) does not actually gate.