- R-9: tests/kicad/project-sync.spec.ts gains an effect-asserting test —
stages a self-contained footprint lib (ecc83 R_Axial as SyncFixture.pretty
+ absolute-uri fp-lib-table via a new stageAndOpen beforeOpen hook), presses
Update PCB, and asserts the board's footprint references through
kicadCollabSnapshot/kicadCollabTestItemBlob (R777, then R888 after a
schematic rewrite + re-sync). Red-first: the dialog report said "Add R777"
while the board stayed empty when the button click never landed.
- R-2: tests/kicad/via-snapshot-assert.spec.ts — two-via board, exact widths
+ no PCB_VIA::GetWidth wx assert line in the console.
- R-4: tests/web/console-copy.spec.ts — Ctrl/Cmd+C over a console selection
fires `copy` (guard stops the keydown before wx); canvas pointerdown
collapses the selection. ControlOrMeta: headless engines use the HOST copy
accelerator regardless of the device UA.
- R-3: workers/cdn gets a vitest harness (package.json + lockfile) and
test/index.test.ts with a workerd-like stub bucket (always-defined range):
plain GET is 200/no Content-Range, Range → 206, HEAD/304/404/405/OPTIONS.
Mutation-verified (pre-1ea35f7 gating → 2 reds). CI step added after the
corpus lint; node_modules gitignored.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015j8uFzSjwRrAeJ85QWVLQa
Second half of the staging Firefox boot failure: the bucket stores
artifacts brotli-compressed (publish-wasm --compress br) with
Content-Encoding in the object metadata, but the worker returned them
with the default encodeBody:'automatic' — the runtime drops a user-set
Content-Encoding and re-negotiates, and on workers.dev that served the
raw brotli bytes with NO encoding header. The editor <script> tags
loaded binary garbage: Firefox fires onload and silently executes
nothing, so wxElementRegistry/Module never appeared even after the 206
fix. encodeBody:'manual' passes the header+body through untouched
(verified against local workerd with a br-encoded seeded object).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PmR6goSk7JC17h7fkgGvHG
The previous fix only stopped passing range options for range-less
GETs, but current workerd reports a DEFINED full-span object.range even
for a plain get() with empty options — so every response still went out
206 + Content-Range and Firefox still refused to execute the editor
glue. Verified against local workerd (wrangler dev + seeded R2): the
206 branch must key off the REQUEST having asked for a range.
Plain GET now 200 with full body; Range requests still get proper 206s.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PmR6goSk7JC17h7fkgGvHG
env.BUCKET.get(key, { range: request.headers }) makes R2 report a
DEFINED object.range (full span) even when the request carried no Range
header, so every plain GET went out as 206 + Content-Range. Chrome
executes a 206 <script>; Firefox fires onload but refuses to EXECUTE
the script — on hosts with no masking edge cache (staging workers.dev)
the injected editor glue never ran: no [KICAD_STATUS] logs, heap 0MB,
'runtime did not initialize (no FS) in 90s' on every Firefox boot.
Prod's cdn.pcbjam.com zone cache normalizes cached hits to 200, which
is why only staging surfaced it; cold prod objects share the bug.
Pass the range option only when the request actually sent a Range.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PmR6goSk7JC17h7fkgGvHG