Session handover — 2026-07-12 pt5¶
The ADR-0010 build landed — slices A (Wix media client) and B (video migration via the API) — and the hero video now renders (ADR-0009 Slice 5b), closing the "getting an asset ≠ rendering it" gap ADR-0010 named. Then an asset reconciliation (new, slice E) measured what we've pulled against what the site actually shows, and reclassified a "cosmetic" known-issue into the next slice.
What shipped (code + data; one worker redeploy, two surgical D1 writes)¶
-
Wix media client — ADR-0010 slice A. Committed
apps/cms/scripts/wix-api.mjs: auth (wix-site-idonly), cursor paging, by-id index, pureparseMediaRef/pickVideoUrl/originalNameOf, 22-check network-free--selftest. The site id is derived, not hand-entered — every rendered Wix page carriesmetaSiteId=<uuid>, so it comes from the crawl and is committed tosites/<site>.jsonc(see ADR-0010 §"Site id"). The by-id match is a straight stem comparison: the API's fileidis the id in our scraped basename. -
Hero video acquired — slice B.
transform-seed-images.mjsgained a video branch (scrape id → API MP4 → R2), retiring the Slice 5b URL reconstruction. WCP's hero →r2:…/vid-20251205-wa0007-73c39f8f.mp4(video/mp4, 3.96 MB,x-amz-meta-original-name: VID-20251205-WA0007.mp4); the key stem is the API's real filename, so provenance is sourced, not derived.asset-migration-gaps1 → 0. Idempotent. -
Hero video RENDERS — ADR-0009 Slice 5b (known-patterns "A Wix hero carousel's VIDEO slide is captured as its POSTER"). Measured live first: the video IS slide 8 of the 8-frame carousel (Wix paints a video slide as its poster still until the player mounts — which is why our capture enumerated it as an image). So the video's ref replaces its own poster at its own index; no new field, 8 slides stay 8.
hero-4renders a video-extension slide as<video>, held for its own duration (a 23s clip in a 4.5s image slot was its own bug). Poster↔video joined by media id via the API'sposters[], through the same lossynormaliseStemthat built the R2 keys. WCP home plays the video live (worker48441217, surgical D1slideshowUrlspatch — never a reseed). garvanbay rendershero-4with zero slide-branch usage → provably inert. -
Asset reconciliation — slice E. New
apps/cms/scripts/asset-reconcile.mjsjoins Wix pool → R2 → seed → deployed HTML and buckets every asset. Findings in known-issues; the headline is that "pulled but not rendered" is 1 object (the poster we deliberately replaced) — but the deployed-HTML scan found 276 loud-fail placeholders across all 24 WCP pages.
Wiki changes¶
- ADR-0010 — slices A/B/E marked
Done; amendment:
listFilesis ROOT-FOLDER-scoped (WCP root 94 vs true library 392) → the pool issearchFiles; new §"Site id". - ADR-0009 — Slice 5 tracker: hero video done, acquisition and render (append-mostly).
- known-patterns.md — three new entries: the carousel video
slide (captured as its poster);
listFilesreturns one folder; a reconciliation is only as honest as its join key. - known-issues.md — hero-video entry deleted (fixed);
the WCP
logo?"cosmetic" note reclassified into "276 loud-fail placeholders" - a new asset-reconciliation entry; an unexplained R2-throughput data point added to the existing deferred throughput issue.
Three numbers I got wrong before reporting them¶
Recorded because the process is the lesson (known-patterns "join key"): the
reconciliation first said 91-of-94 library files were "never pulled" (wrong join key —
display name vs media id), then still lied because the pool was root-only, then
reported 349 "empty image slots" that included every legitimate absence (a hero with
no video). Each was audited in both directions and corrected before it reached the
report. The trustworthy answer to "what is broken on the page" came from measuring
the deployed HTML (ui-missing-*), not from the seed.
State¶
Committed to master this session-end: apps/cms/scripts/wix-api.mjs (new),
apps/cms/scripts/asset-reconcile.mjs (new), transform-seed-images.mjs (video
branch + linkVideoSlide), upload-image.mjs (video content-types + uploadAsset
with a provenance override — image keys byte-identical, proven over 190 corpus
filenames and against live R2), packages/components-v3/…/hero-4.astro (video slide +
per-slide dwell), apps/cms/seed/waterfordcountypainters.json,
apps/cms/sites/waterfordcountypainters.jsonc (wix_site_id), the wiki + this
handover. Live writes: WCP worker redeployed (48441217); WCP D1 patched twice,
surgically (hero videoUrl, then slideshowUrls) — 12 blocks preserved each time,
no reseed (a reseed would revert the capture-invisible SERVICE AREAS CTA); 1 MP4
uploaded to R2. No garvanbay change (worker untouched). Side effect worth knowing:
upload-image.validate.mjs does live PUTs — running it uploaded 30 wfpainters
objects genuinely missing from R2 (benign; immutable keys).
Next session (priority order)¶
- LogoStrip src capture gap — user-directed next slice. 237
fcr.logo-stripitems carry an item count and nosrc, painting 276 placeholders across all 24 WCP pages. The logos are real and on live (Terra Spirits, Portarlington RFC, Hennessy Feeds, Coffey Engineering, Dairy Direct, Enterprise Ireland…) — so they are unfilled, not phantom, and this is a capture-plane gap (likely JS-rendered, invisible to the static matcher — same class as the topbar email/location miss). One fix clears all 276. Fold in the deadfcr.business.imageUrllogo (/assets/logos/…→ R2; breaksog:image+ JSON-LD). Re-runasset-reconcile.mjsafter, and re-readat-source-never-pulled(298) — the residual is a capture-coverage signal. - ADR-0010 slice C — image provenance enrichment (API filenames/dimensions/alt
replacing derived basenames), now that
searchFilesgives the true pool. - garvanbay
wix_site_id— absent (crawl inputs live only on EC2), so the reconciliation skips its Wix pool. One line insites/garvanbay.jsonc. - Section-style density dimension + Slice 6 calibration (fit
lib/calibration.json; promote hero-variant/scrim/textTone to scored dims).