feat(toilville): emit the lockups and the two new block attributes — 100% copy #119

Merged
peterswimm merged 1 commit from feat/client-emits-new-attrs into main 2026-09-10 20:07:17 +00:00
Owner

The three plugin changes have landed (#374, #375, #376), so the client can stop working around blocks that couldn't express what the design asked for.

was now
four product lockups dropped with an apologetic HTML comment resolve to toilville/product-logo
spelwork's closing band showed one button emits its second action, "Talk to a human"
contact form field read Email emits emailLabel, so it reads "Work email"

The vocabulary's image block carries no height — size is a rendering decision — so the client makes it: 26px in a card, 30px in the Spelwork hero, the only place a lockup heads a page.

Copy coverage is 100% on all five pages

page before now
landing 100.0% 100.0%
rituals 100.0% 100.0%
spelwork 99.0% 100.0%
news 100.0% 100.0%
contact 95.2% 100.0%

Floors raised to give exactly one text node of slack: one miss passes, two fail. That's tighter than it sounds — the denominator is the design's node count, so editing copy moves both sides together and the ratio only falls when the renderer drops something. These floors cannot flap on ordinary copy work.

A gap the copy gate could not see

An <img> is not text, so copy coverage never counted the lockups and would not have caught their loss. I confirmed this rather than assuming it: deliberately re-dropping all four left coverage at 100.0%.

So four lockups were missing from live pages for the entire cycle with every gate green — including the gate I'd have expected to catch it. New test_no_image_is_silently_dropped closes that: any image the client can't resolve now fails, instead of leaving a comment nobody reads. Verified red.

just check green; 292 tests pass.

https://claude.ai/code/session_01Kbzfscp4w5enUrZxMnDt78

The three plugin changes have landed (#374, #375, #376), so the client can stop working around blocks that couldn't express what the design asked for. | was | now | |---|---| | four product lockups **dropped** with an apologetic HTML comment | resolve to `toilville/product-logo` | | spelwork's closing band showed one button | emits its second action, **"Talk to a human"** | | contact form field read `Email` | emits `emailLabel`, so it reads **"Work email"** | The vocabulary's `image` block carries no height — size is a rendering decision — so the client makes it: 26px in a card, 30px in the Spelwork hero, the only place a lockup heads a page. ### Copy coverage is 100% on all five pages | page | before | now | |---|---|---| | landing | 100.0% | 100.0% | | rituals | 100.0% | 100.0% | | spelwork | 99.0% | **100.0%** | | news | 100.0% | 100.0% | | contact | 95.2% | **100.0%** | Floors raised to give exactly **one** text node of slack: one miss passes, two fail. That's tighter than it sounds — the denominator is the *design's* node count, so editing copy moves both sides together and the ratio only falls when the **renderer** drops something. These floors cannot flap on ordinary copy work. ### A gap the copy gate could not see An `<img>` is not text, so copy coverage never counted the lockups and **would not have caught their loss**. I confirmed this rather than assuming it: deliberately re-dropping all four left coverage at 100.0%. So four lockups were missing from live pages for the entire cycle with every gate green — including the gate I'd have expected to catch it. New `test_no_image_is_silently_dropped` closes that: any image the client can't resolve now fails, instead of leaving a comment nobody reads. Verified red. `just check` green; 292 tests pass. https://claude.ai/code/session_01Kbzfscp4w5enUrZxMnDt78
feat(toilville): emit the lockups and the two new block attributes — 100% copy
Some checks failed
PR policy check / policy-gate (pull_request) Failing after 0s
Security Scans / Gitleaks secret scan (pull_request) Successful in 2m45s
Security Scans / Trivy filesystem scan (pull_request) Successful in 2m56s
Test Generator / test (pull_request) Failing after 3m4s
Test Generator / lint-workflows (pull_request) Successful in 2m53s
UDG dist drift gate / dist/ matches dtcg + udg sources (pull_request) Successful in 32s
Test Generator / lint-prose (pull_request) Successful in 52s
Copy coverage / Design copy reaching rendered HTML (pull_request) Failing after 47s
a8bc9f9121
The three plugin changes have landed, so the client can stop working around
blocks that could not express what the design asked for.

  * the four product lockups resolve to toilville/product-logo instead of being
    dropped with an apologetic comment. The vocabulary's `image` block carries
    no height — size is a rendering decision — so the client makes it: 26px in a
    card, 30px in the Spelwork hero, the only place a lockup heads a page.

  * spelwork's closing band emits its second action, "Talk to a human".

  * the contact form emits emailLabel, so the field reads "Work email" as the
    design says rather than the block's default "Email".

Copy coverage is now 100% on all five pages. Floors raised to give exactly one
text node of slack — one miss passes, two fail. That is tighter than it sounds:
the denominator is the DESIGN's node count, so editing copy moves both sides
together and the ratio only falls when the RENDERER drops something. The floors
cannot flap on ordinary copy work.

New gate — an <img> is not text, so copy coverage never counted the lockups and
would not have caught their loss. Confirmed by deliberately re-dropping them:
coverage stayed at 100%. Four lockups were missing from live pages for the whole
cycle with every gate green. Any image the client cannot resolve now fails
instead of leaving a comment nobody reads. Verified red.

Claude-Session: https://claude.ai/code/session_01Kbzfscp4w5enUrZxMnDt78
peterswimm deleted branch feat/client-emits-new-attrs 2026-09-10 20:07:22 +00:00
Sign in to join this conversation.
No description provided.