Skip to content

Session handover — 2026-07-08 pt4

Continues from session-2026-07-08-pt3-handover.md (Slice 4b-i — the measured GenericSection renderer). This session ran ADR-0009 Slice 4b-ii — the genericFallbackRate sub-metric + the GenericSection gate veto. One slice: closed, validated, anchor-stable. Metric-only (no render, no deploy).

What changed (where to look)

  • ADR-0009 slice tracker — row 4b-ii flipped Planned → Done 2026-07-08 (decisions/0009-target-output-architecture.md).
  • Build-time sidecar builds/<domain>/section-matchers.json ({order,heading,matcher,type} per emitted block) — lib/cms/transformer.js now returns a manifest; lib/cms/seed-from-build.js collects it per page and writes it alongside seed.json. The only record of which matcher produced each rendered block (the capture sees painted DOM, not block identity).
  • Compute + join lib/structural-diff.jsgenericFallbackRate = Σgeneric/Σblocks from the build counts (genericFallbackCounts / rollupMatcherGap; null when no sidecar — unknown, never a bogus 0). Each ours row tagged oursMatcher via makeMatcherLookup (heading-first, content-order fallback), bridged across the home/index/homepage slug alias by manifestForSlug. S is byte-identical — additive projection, not a penalty (same discipline as Slice-4a matcherGap).
  • Gate veto lib/scorecard-gate.js#collectGenericFallbackVetoes — GenericSection at role-weight ≥ criticalRoleWeight (1.3) → genericFallbackCritical → HOLD, mirroring criticalSectionDropped; wired through lib/scorecard.js. Flag added to lib/calibration.json vetoFlags.
  • Validatestructural-diff.validate.mjs line-161 deferred-null assertion flipped; added rate/counts/join/rollup/alias + additive-S fixtures. scorecard-gate.validate.mjs gained the GenericSection veto fixtures. Both green.
  • known-patterns: new entry — genericFallbackRate is a build fact, not a capture measurement; compute from the sidecar, join only for the veto role, and bridge the home/index slug alias or the homepage silently drops the join.
  • Contract: near-match-scorecard-contract.md §3 / §7 / Status updated (genericFallbackRate + veto shipped; S axis feature-complete for the seed batch).

Verified

  • Both .validate.mjs suites green (new + existing fixtures).
  • Anchor stability (metric-only, no deploy): garvanbay SHIP S=96 composite=94.7 gfr=null (no sidecar — its build is on EC2), byte-identical; WCP MANUAL-POLISH S=60.9 composite=73.7 gfr=0 (sidecar present, 0 fallback used), no new veto. 22 ours rows tagged oursMatcher (join fired, incl. the homepage after the alias fix).
  • Rate>0 + veto proven on real WCP capture by forcing a synthetic GenericSection hero through the real join → gfr=0.031, genericFallbackCritical fires on index/hero/w=1.6 — then reverted (throwaway, per known-patterns "prove the render surface another way").

Bug caught in verification (not review)

The seed keys the homepage home (its pageId); the capture keys it index (garvanbay crawls home, WCP index). A naive manifest[slug] join silently dropped the homepage — the 2×-weighted, hero-bearing page — so a GenericSection hero there would have escaped both the rate and the veto, invisibly (anchors stay green, neither uses GenericSection). Fixed with the same home/index/homepage alias tolerance makeStyleLookup already uses (manifestForSlug), locked by a fixture. This is why the forced-hero proof matters: the no-op-on-samples path hides join gaps.

Next priority — Slice 5 / Slice 6

The S axis is now feature-complete for the seed batch (matcherGap + genericFallbackRate both live; S/T/G_det all gate-ready on artifact grounds, floors still awaiting calibration). Remaining ADR-0009 slices: - Slice 5 — Wix API content plane (media, business info, blog) with provenance in-data. - Slice 6 — batch a 30–50-site sample; human labels; fit calibration.json (the seed thresholds are still fitted:false); bounded-LLM triage; set the manual-polish budget.

Carried / open (unchanged from pt3)

Static-lane GenericSection emit path is wired but not separately built (no local static scaffold; garvanbay's is on EC2) — static lane produces no sidecar, so genericFallbackRate is null there (correct boundary, folds in when Option A lands). Plus all prior carried items: seed thresholds uncalibrated (Slice 6); theme-fidelity.js lacks a .validate.mjs; T re-measures emission not the deployed DOM; imageSide over-fires on media heroes; deployed-site fidelity gaps (garvanbay muted bands, WCP columns/align/FAQ-tone); per-site static lane consumes no capture (Option A); cross-account sharding; brand-detection nondeterminism; noindex launch blocker; CMS FloatingCTA/Social silent-drop (surfaced by 4b-i, still open).