feat: production run — Q61 ramp, /404/, CloudFront router, cutover runbook
Build and deploy / build-and-deploy (push) Failing after 4s

Five items of Pouya's production run, 2026-09-01.

Q61 — scroll-padding-top becomes a max() ramp on `10lh - 83px`, with the
plain calc() first as the fallback for engines without `lh`. Hidden focus
stops under minimumFontSize=32: 290 of 1,455 -> 0, control build still
290. Default settings byte-identical (0 differences over 352 page-widths x
17 fields). The 12 residual cells at minimumFontSize=16/20 are pre-existing
and unchanged-or-better; reported, not widened, per instruction.

Intake backend + CloudFront — docs/09-cutover-runbook.md is the
copy-paste sequence for admin execution: every command followed by its
verification and expected output, rollback per part, and Part 10 is Q60's
TTL test. infra/cloudfront/router.js is the trailing-slash function
(30-case suite; 8 fail against the pre-review version, incl. a
protocol-relative open redirect). infra/cloudfront/configure.mjs is
dry-run-by-default and idempotent. scripts/intake-env.mjs emits the six
Lambda env vars from src/data/site.ts.

Four launch blockers found by reading the running system:
  - handler.mjs wrote pk/sk; the live table's key is submissionId with no
    sort key, so every submission would have failed validation silently
  - the Lambda invoke permission is scoped to the old route path
  - 22 of 23 pages 403 without the router function
  - there was no 404 page; src/pages/404.astro adds it

Claims audit (D20 cutover pass) — five gloss over-reaches corrected on
/practice/energy/, /practice/insurance/ (x2), /practice/technology/ and
/med-arb/. Three findings left open for Pouya: Q62, the /med-arb/ gloss,
and Q60.

Q62 — one frozen-tripwire pattern added under the freeze's own breach
exception, with a probe and four negative fixtures. check:claims exits 1
until the false /legal/privacy/ sentence is corrected, so both deploy
paths are blocked by a mechanism rather than by memory.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Md3GndFqWPzK78xAoebsg5
This commit is contained in:
Pouya Lajevardi
2026-09-02 06:52:20 -04:00
co-authored by Claude Opus 5
parent ca1c2524e1
commit bd282aa47d
30 changed files with 3256 additions and 143 deletions
+87 -17
View File
@@ -495,9 +495,13 @@ Not a polish pass. A build requirement.
⚠️ **It is not a claim about anything outside that grid, and "no document
overflow" is not "no accessibility defect".** Three known cases sit outside it
deliberately. The **fallback-metrics case** below needs the webfonts blocked and
a seventh nav item. The **focus-obscuring case** below is an **open WCAG 2.2
SC 2.4.11 (AA) failure**`AGENTS.md` Q61 — and document overflow cannot see it
at all, because nothing overflows: the header simply covers what has focus. And a
a seventh nav item. The **focus-obscuring case** below was a **WCAG 2.2
SC 2.4.11 (AA) failure**, now **fixed and closed**`AGENTS.md` Q61 — and it is
the sharpest illustration of the warning above: **document overflow could not see
it at all**, because nothing overflowed. The header simply covered what had
focus, on 290 of 1,455 stops, while every zero in the table above stayed a zero.
A residual at `minimumFontSize=16` and `=20` remains, is pre-existing, and is
likewise invisible to this grid. And a
**footer nav label** still overruns its own column by 24 px at 640 px under
minimum font size with 7.7 px of clearance, again with zero document overflow.
None of the three is contradicted by the zeros above, and none of them is
@@ -1034,9 +1038,10 @@ Not a polish pass. A build requirement.
97 → 199.4 px inside a header at 0 → 228.6 px, `position: sticky`,
`inset-block-start: 0px`, background `rgb(250, 247, 242)` — opaque cream.
**THE RECOMMENDED FIX IS MEASURED AND DELIBERATELY NOT IMPLEMENTED — Q61.** Two
candidates exist, and the second is better on the exact ground that deferred the
first.
✅ **FIXED AND CLOSED — Q61 RULED *fix now*, 2026-09-01. Candidate B SHIPPED.**
Two candidates existed, and the second was better on the exact ground that had
deferred the first. The measurements below are the pre-fix state; the acceptance
sweep that closed it is at the end of this block.
*Candidate A, round 1:* a third gate term `calc((15px - 1ch) * 100000)`,
un-sticking the header under the setting while leaving `inset-block-start: 0px`
@@ -1076,20 +1081,85 @@ Not a polish pass. A build requirement.
font file changes nothing, and the fallback-metrics caveat that deferred
candidate A does not apply to B at all.
**Why B is still not implemented, and none of these is a measurement gap.**
`10lh - 83px` is two fitted constants — the difference from A is that a `max()`
ramp degrades by pixels if they are off, where A's `* 100000` step flips
**What was said against B before it shipped, and what the sweep did with each.**
`10lh - 83px` is two fitted constants — the difference from A being that a
`max()` ramp degrades by pixels if they are off, where A's `* 100000` step flips
stickiness the wrong way. **The first declaration is load-bearing:** an engine
without `lh` support drops the whole `max()` as invalid and `scroll-padding-top`
falls back to `var(--space-4)` = 16 px, which is *worse* than today. It needs the
full 1,408-cell sweep plus the fallback-metrics and seven-item cases. The focus
probe behind all of this is **Chrome-only**. And **D19 caps the review at two
rounds**, so a header change made now would ship without review — the precise
failure mode the cap exists to prevent. **The findings are the premise and the
cost; the fix is Pouya's ruling.**
falls back to `var(--space-4)` = 16 px, which is *worse* than no fix — so it is
written first, as a plain declaration, and must stay there. The focus probe is
**Chrome-only**, which is still true and is a limit on the evidence rather than
on the fix. The two remaining objections were discharged by measurement:
**`docs/06` carries this as an OPEN item again**, restored from the `[x]` this
session had written, and the decision is `AGENTS.md` **Q61**.
**THE ACCEPTANCE SWEEP — 777 cells over 37 settings, plus the focus walk.**
Per cell: navigate, kill transitions *before* any root-size change, set the
root, `location.hash = 'main'`, then read how much of `#main` sits behind the
header. The cell count is asserted, so a silently-truncated grid cannot pass.
| setting | before | after |
|---|---|---|
| root style 9..32 (504 cells) | 0 | 0 |
| `defaultFontSize` 9 / 12 / 16 / 20 / 24 (105) | 0 | 0 |
| `minimumFontSize=9`, `=12` (42) | 0 | 0 |
| `minimumFontSize=16` (21) | 6 cells, max 52 px | **6 cells, max 52 px** |
| `minimumFontSize=20` (21) | 12 cells, max 64 px | **6 cells, max 14 px** |
| `minimumFontSize=24` (21) | 15 cells, max 75 px | **0** |
| `minimumFontSize=32` (21) | 15 cells, max 174 px | **0** |
| fonts blocked (21) | 0 | 0 |
| fonts blocked + `minFont=32` (21) | 15 cells, max 174 px | **0** |
| **total** | **63 of 777** | **12 of 777** |
**The focus walk, which is the criterion itself: 290 entirely-hidden stops of
1,455 → 0.** Same grid (6 pages × 5 widths ≥ 1056 px, 30 cells, 344
header-internal stops skipped), hit-tested with `elementFromPoint`. **The
pre-fix tree was rebuilt in a git worktree and put through the identical probe:
it still reports 290** — footer 254, `#main` 36, geometry candidates 333 against
the fixed build's 43. That control is what makes the 0 a result rather than a
hope: both modes reading 0 with identical step counts is the shape `CLAUDE.md`
warns *ends* a check instead of starting one.
**Default settings unchanged: 0 differences over 352 page-widths × 17 fields =
5,984 comparisons**, full-page geometry fingerprint included, positive control
detecting exactly 1 injected difference.
⚠️ **AND THE FIRST ATTEMPT AT THAT COMPARISON REPORTED 4,224 DIFFERENCES.** It
keyed rows on `page`/`width`; this harness names them `url`/`w`, so every row
collapsed onto one map entry and was compared against an arbitrary single row.
It was caught only because the result was *uniformly bad*. **The fix is not the
corrected field names — it is that the comparison now asserts the key fields
exist and are unique before comparing anything.**
⚠️ **ONE COLUMN OF THE SWEEP WAS MEASURING NOTHING, AND TWO METRICS
DISAGREEING IS WHAT SURFACED IT.** A summary column reported
`min(scroll-padding-top headerH)` of **71.89 px** on root-style rows whose
`covered` read **0**. Cause: `insetBlockStart` is **900 px** in those rows —
the header is `position: sticky` and **not pinned**, because that is exactly how
the saturating `clamp()` gate un-sticks it. Comparing the offset to the header
height is meaningless where the header is not pinned. `covered` — real geometry
after a real hash navigation — is the valid metric. **A `position` of `sticky`
is not the same fact as "the header is pinned", and any future probe that
compares an offset against a header height has to read
`inset-block-start` too.**
**THE 12 REMAINING CELLS ARE PRE-EXISTING, REDUCED, AND DELIBERATELY NOT
FIXED.** `minimumFontSize=16` leaves 52 px of `#main` behind the header on
`/about/` and `/contact/` at 1280, 1440 and 1920 px; `=20` leaves 14 px on the
same six. Every one is unchanged or better than before the fix and none is new.
**Why the ramp cannot see them, which is the part worth keeping:** the setting
*floors* computed sizes, so at `minimumFontSize=16` the root is genuinely 16 and
`1lh` on `<html>` is 18 px — identical to the default — while the header grows to
**149.38 px** because the **sub-16 px** type (the 11 px tagline, the 14 px
eyebrow and nav) is floored up. **The ramp reads a quantity the setting did not
move.** Closing it needs a different measurement — `1lh` taken from an element
that carries the small type, or a floor on the header — which is a header change
with site-wide reach. Pouya's instruction on this step was *"if the sweep
surfaces anything beyond this one declaration's blast radius, stop and report —
do not widen"*, so it is reported: `docs/06` carries it as its own item. It is
**not** an SC 2.4.11 failure, which is about a component *entirely* hidden.
**`docs/06`'s item is ticked and carries the figures.** The decision was
`AGENTS.md` **Q61**, now closed.
⚠️ **AND ONE MORE LATENT CASE, AT THE DEFAULT TEXT SIZE — NO READER SETTING
INVOLVED: FALLBACK FONT METRICS PLUS THE SEVENTH NAV ITEM.** With every `.woff2`