Session handover — 2026-07-08 pt2¶
Continues from session-2026-07-08-handover.md (G_det alignment fix). This
session ran ADR-0009 Slice 4a — the matcherGap roll-up into S — after
splitting the bundled Slice 4 into 4a (metric) + 4b (render). One slice,
closed; metric-only, no deploy.
The split (scope decision, user-confirmed)¶
Slice 4 as written bundled two independently-shippable pieces with an asymmetric dependency, so it was split (see ADR-0009 tracker rows 4a/4b):
- 4a —
matcherGapinto S (this session): derivable from datastructural-diff.jsalready tallies; small, pure, deploy-free, always verifiable. - 4b — measured
GenericSectionrenderer (next): a new render surface across both lanes; also closes the CMS-lane silent-drop.genericFallbackRatelives here (structurally 0 until the renderer ships; needs a build-time{sectionId→matcher}sidecar — the capture can't see block identity).
Sequencing rationale: build the meter (4a) before the remediation (4b) — the matcherGap numbers tell us how much GenericSection work 4b actually warrants.
Slice 4a — what changed (where to look)¶
- Code:
lib/structural-diff.js— newsummariseMatcherGap(rows)(per-page, indiffPage) +rollupMatcherGap(pages)(per-site, indiffSite); emits{droppedLive, insertedOurs, propsWithheld, byRole, genericFallbackRate:null}.lib/scorecard.jscarries it intofidelity-scorecard.json'sstructuralblock + a console line. The design invariant: matcherGap is a reported projection of debt already in S, not a second penalty — S is byte-identical before/after. ThecriticalSectionDroppedveto reads the same drop rows, unchanged. - Validate:
lib/structural-diff.validate.mjs— 42 → 53 checks (drop/insert weights,propsWithheldcounts onlyours-missing, site totals,byRole,genericFallbackRate===null). - known-patterns: new entry — a diagnostic that projects debt already inside a score must NOT re-penalise (ask "is X already inside S?" before folding X into S).
- contract / ADR / known-issues:
near-match-scorecard-contract.md§3/§6/§7 + a Step-4a Status block; ADR-0009 tracker split 4a done / 4b planned; known-issues scorecard entry updated (4a done, stalestructural-diff.jsvalidate mention corrected).
Verified¶
node lib/structural-diff.validate.mjs— 53/53;scorecard-gate.validate.mjs— 19/19 (regression: gate untouched).- Re-scored both anchors offline (no re-crawl): S byte-identical (garvanbay 96,
WCP 60.9), verdicts stable (garvanbay SHIP, WCP MANUAL-POLISH). matcherGap
populated: garvanbay
0/0/0; WCP3 dropped (w=2) / 5 inserted / 4 props-withheld,byRole content 1d·5i, ribbon 2d. No drop at role-weight ≥ 1.3 → nocriticalSectionDroppedveto, coherent with MANUAL-POLISH. - Standalone
structural-diff.jsCLI +perceptual-diff.js(alignPage, untouched) both exercised via the full scorecard — G_det still computes. - Regression (Phase 3): N/A for shared primitives — no canonical block touched; the shared file is the metric lib, exercised through all three consumers.
Next priority — Slice 4b (measured GenericSection renderer)¶
The render surface that reduces the debt 4a now measures: a lowest-priority
always-matches GenericSection matcher (lib/matchers/, auto-registers) + a new
canonical block (composes Section/SectionProse/SectionGrid, resembles
content-1/content-2) + translators in both lanes + FcrBlocks + check-renderers
+ loud-report + deploy + verify. Closes the CMS-lane silent-drop
(lib/cms/transformer.js drops matcher:null with no warning) and makes
genericFallbackRate nonzero. Then Slice 6 (calibrate calibration.json).
Carried / open (see known-issues)¶
New residual this session: isJunk misses WCP's heading-bearing "Watch Now"
video-chrome strip (surfaced by matcherGap — a low-impact ribbon drop S already
counted; widen the heading-gated regex) — contract Follow-ups. Plus all prior
carried items: seed thresholds uncalibrated (Slice 6); theme-fidelity.js still
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) unfixed; per-site static lane consumes no capture;
cross-account sharding; brand-detection nondeterminism; noindex launch blocker.