Skip to content

Session handover — 2026-07-07

Continues from session-2026-07-06-pt4-handover.md (ADR-0009 Slice 2b — design-token capture). This session: designed the joint 2b-band + Slice 3 contract, then drove the first section-style dimension — imageSide — end-to-end on the CMS lane and deployed it to the garvanbay demo. One code commit (ec6bc32) + this wiki commit.

What changed — where to look

  • Joint contract designed first (parallel Fable + Codex passes, blind; near-total convergence). Written up in the new docs/pipeline/section-style-contract.md — the full 5-dimension contract (align / imageSide / columns / density / header-topbar), the capture-in-page decision (no layout.json join), one styleFor lookup, the unlayered-CSS rule, the 2b-band/Slice-3 split, and the imageSide specifics.

  • ADR-0009 Slice 3, imageSide (ec6bc32) — first dimension shipped, CMS lane:

  • lib/section-style.js + .validate.mjs — pure classifyImageSide (media-centre vs text-column-centre → left|right, omit-on-ambiguity), 14/14 locked.
  • lib/capture-section-backgrounds.js — in-page _styleRaw geometry + style.imageSide per section; artifact schemaVersion: 2.
  • makeToneLookupmakeStyleLookup (one lookup, every dimension); type-gated stamp in transformer.js + apply-section-tones.js (identity-known matches only, not gap-tone) drives the existing editable imagePosition field — no new schema/CSS.

  • Deployed + screenshot-verified on the garvanbay demo. The live D1 home teasers were an alternation offset-by-one from live Wix (4/5 mirrored: PAYROLL showed image-left, live is image-right). Fixed via a surgical single-row D1 UPDATE (imagePosition is D1 content, not baked → no rebuild; and a full reseed would have dropped a 10th native block the seed lacks). Re-screenshot confirmed PAYROLL→image-right, MGMT→image-left, matching live.

Verified

  • imageSide classifier is correct, not inverted — settled by side-by-side live-vs-demo screenshots (see new known-pattern "Measured image-side beats the alternation heuristic").
  • Zero-regression: absent signal → block default stands (unit-tested); garvanbay 58 blocks re-stamped with tones identical; WCP re-crawl 0 tone changes by-id (347 matched). Two sites, 0 ambiguous section-style classifications (garvanbay 93 / WCP 395).
  • Both sample sites captured at schemaVersion 2 (garvanbay + WCP). WCP not deployed / not visually side-verified (garvanbay-only ask); harmless regardless — the stamp type-gates to fcr.about.

Real stops resolved (pre-build)

  • Per-site static lane consumes no capture (tone or style) — scope adjusted to CMS lane only (Option A, user-confirmed). Deferred with a reopen trigger; see known-issues.

Next priority

ADR-0009 fan-out on the proven rail — next dimensions in order: alignment → columns → density → header/topbar (docs/pipeline/section-style-contract.md). alignment and columns need new render surfaces (data-align / SectionGrid data-columns, unlayered CSS) and the team-grid/checklist <Section> migration; density needs representative content-band selection (the deferred 2b-band robustness work). Or bring captured styling (tone + style dims) to the per-site static lane when the first static launch is scoped.

Carried/open (see known-issues): per-site static lane capture-consumption deferred; garvanbay demo D1 diverges from seed (native block only in D1 — reseed would drop it); section-band selection deferred (2b-band); brand-detection nondeterminism; $card-sample reliability; cross-account sharding unproven; per-site static @source + noindex blockers.