Skip to content

Session handover — 2026-07-07 pt5

Continues from session-2026-07-07-pt4-handover.md (scorecard Steps 0–2). This session shipped scorecard Step 3 — the hurdle/veto GATE (the pt4 next-priority): the three axes now produce an actual decision, verdict: ship | manual-polish | hold. One code+docs commit (3faf73b) + this wiki commit.

What changed — where to look

  • Code: pure gate lib/scorecard-gate.js (contract §4 ladder + collectStructuralVetoes — hero/primary-CTA dropLive at weight ≥ 1.3 → HOLD); versioned lib/calibration.json (seed-2026-07-07, fitted: false — τ_ship 85 / τ_hold 60 / floors S70·T80·G55; axis weights moved here as single source); lib/scorecard.js enforces the vetoes and stamps verdict/composite/thresholds/calibrationVersion into fidelity-scorecard.json; first gate validate script lib/scorecard-gate.validate.mjs (19 checks, green). Side-fix: lib/fidelity-harness.js standalone report renamed to fidelity-harness.json — it was clobbering the scorecard artifact.
  • Contract (near-match-scorecard-contract.md): Step 3 status section + build-order row; follow-ups updated (gate covered by validate; structural-diff/theme-fidelity still not).
  • ADR-0009: Slice 4 tracker row extended with Step 3.
  • known-patterns: one durable entry — a hurdle+floor gate can carry an arithmetically dead floor; check each floor's reachability against the composite weights (found because a naive S-floor fixture was unwritable: under seed weights, composite ≥ 85 already implies S ≥ 70).
  • known-issues: scorecard entry now "Steps 0–3 of 6", with an explicit warning that seed thresholds are hand-set — verdicts rank/queue, but don't trust τ_ship for unsupervised shipping until Slice 6 fits calibration.json.

Verified

  • node lib/scorecard-gate.validate.mjs — 19/19 (veto-beats-composite, floor demotion, partial-axes-can-never-ship, boundary , structural-veto collection, seed-value lock).
  • Both sites re-scored offline against the pt4 capture artifacts (no re-crawl): garvanbay SHIP (93.2, floors met), WCP MANUAL-POLISH (72.7, S=59.9 fails the S-floor) — the sanity anchor holds; the structural veto correctly fires on neither (WCP's drops are content/ribbon weight, checked before locking the rule).
  • Regression check: N/A — no shared canonical surface touched (new pure modules + the scorecard CLI; partialComposite export preserved).

Next priority — Slice 4 (GenericSection + matcher-gap into S), then Slice 6

With the gate live, the scorecard is structurally complete for two axes of work: Slice 4 (measured GenericSection fallback; genericFallbackRate + matcherGap into S; scorecard becomes the gate) and Slice 6 (30–50-site batch → human labels → fit calibration.json; the fitted thresholds replace the seed ones and fitted flips true). Before G_det's floor is trusted as a gate input, the G_det outlier triage (garvanbay hero 33%, WCP FAQ 25% — real divergence vs crop artifact) from the contract follow-ups is still the cheap prerequisite. The second track (more deployed sites through capture→scorecard to grow the labelled sample) remains open and is now more valuable — every new site gets a verdict for free.

Carried / open (see known-issues)

Seed thresholds uncalibrated (Slice 6); scorecard Steps 4–5 pending; G_det real-vs-artifact triage; .validate.mjs still missing for structural-diff.js/theme-fidelity.js (gate is covered); T re-measures emission not the deployed DOM; deployed-site gaps the scorecard surfaced (garvanbay muted bands not painting; WCP columns/align/imageSide) unfixed; per-site static lane consumes no capture; plus all prior carried items (cross-account sharding, brand-detection nondeterminism, noindex launch blocker, …).