Skip to content

Rewrite the homepage, and wire the legibility gate that holds it (#219) - #220

Merged
bdelanghe merged 6 commits into
mainfrom
claude/homepage-rewrite
Aug 21, 2026
Merged

Rewrite the homepage, and wire the legibility gate that holds it (#219)#220
bdelanghe merged 6 commits into
mainfrom
claude/homepage-rewrite

Conversation

@bdelanghe

@bdelanghe bdelanghe commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Closes #219. Your copy landed as the page, and your instrument wired into the build that protects it.

Hero (the problem, the move, one allow/deny transcript) → What's here (three repos, a line each) → Status, graded (three grades, the six claims folded into them) → If you want to go deeperWho.

before after
index.html words 1,516 460
Coleman-Liau grade 13.2 11.4
FOCUS_SECTION_TOO_LONG 3 sections 0
restatement pairs (site-wide) 19 7
remaining "jargon" 11 terms delanghe, brooklyn, polyform

Those last three are proper nouns. Every actual term of art — Sigstore, Fulcio, OIDC, GHCR, OCI, in-toto, SLSA, DSSE, ed25519 — is off the page.

The gate

The deterministic half runs in the hermetic phase directly after gen-markdown.mjs, because the projection is what it reads: the words a stranger gets, with the markup gone.

the rewrite:   PASS — hero 91w · 4 sections · 3 acronyms
the live page: FAIL (6) — 20× "door", 11× "room", 10× "guest",
               "Flagship", "At scale", 21 acronyms against a budget of 10

The judged half (scripts/legibility/coldread.feature) is not wired. Its own header says why and the pipeline entry repeats it: a flaky proxy in the inner loop rots trust in the gate around it. Deploy-time only, and a green judge run is not the human test.

Mutation-tested through the real build, not against a copy: swap "a named bundle of permissions" for "a room of doors the guest holds", rebuild, and the build stops at the legibility step naming all three words. (My first attempt at this reported a red build that was actually the catalog staleness check failing earlier in prebuild — the gate had never run. Re-verified properly.)

Two changes to the instrument as delivered

Flagged rather than buried, since you said to resist extending it — neither of these is an extension.

The sentence rule split on terminal punctuation only, so it ran straight through blank lines: six seam rows with no full stop between them measured as one 59-word sentence. A false positive about the instrument, not a finding about the page, and it would fire on any page with a short unpunctuated list. Blank lines now split first. A sentence does not span a paragraph break, so this is the sentence rule measuring sentences.

The hero budget reads "words before the first ---", and the markdown projection emitted no --- at all — so every page measured as 100% hero and failed by 300 words. Fixed in the projector, not the gate: a <header> that is a direct child of <main> is the hero, and markdown's only way to say "the hero ended" is a thematic break. The alternative was putting an <hr> in the page so the markdown would have one — adding visual furniture to satisfy a gate, which is the exact dishonesty these gates exist to catch.

What moved in the page, and why it moved rather than being suppressed

Eighteen scripts read index.html. Most kept working. These didn't:

gen-seams spliced the capability-seam grid into a homepage card that no longer exists → moved to /map.

gen-registry spliced a three-tile count summary into #graph. /map already renders the same numbers with the whole registry underneath, so the second renderer goes rather than moving: two renderers for one dataset is the drift this project argues against. The script keeps its data duties, and sync-registry.yml now checks the seed and the page that renders it.

check-outline asserted "at least one .seams__head on index.html" — an assertion about the homepage's shape, not about the component, so moving a card to the page it belongs on failed the gate with nothing regressed. Presence is now global across surfaces, and map.html joins the surfaces checked, so /map's outline is under contract for the first time.

content/marketing.feature pinned micro-copy that is gone. Scenarios deleted alongside the copy they described; leaving them red or loosening them to pass would both be worse.

content/grounding.json gains two phrasings — the two ENFORCED claims kept their meaning and changed their wording. Same evidence, restated; not a new assertion.

Dropped on purpose

The room/door/guest hero figure · the bet and model sections · the in-page self-check demo (~100 lines of JS the page itself labelled "a demo, not proof") · the two provenance cards · the conformance battery paragraph and its seven acronyms · everything the homepage restated about /desk, /contracts, /conformance and /ledger.

Those pages stay in the site nav on every page. The homepage just stops saying them again.

All six claims in integrity/claims/claims.jsonld survive, folded under their grade. The single-source floor holds at 25 ≥ 22.

Two things I changed in your copy

"Every deploy is keyless-signed" → "Each deploy". The upstream honesty lane reads a bare absolute as an unscoped coverage claim and rejected exactly that shape earlier tonight.

The hero transcript is three lines per case, not the one-liner. .code wraps rather than scrolls — deliberately, so a <pre>'s min-content can't inflate the page on a phone — so a line that doesn't fit breaks mid-clause. The one-liner broke at "keeper holds git-" at 390px. Measured at 390 / 768 / 1280: nothing wraps now.

Two things worth your call

/desk isn't linked from the homepage. You said you were excited about Front Desk; the copy doesn't mention it. Still one click away in the nav. Say the word and it's a paragraph in "go deeper".

Dead CSS is still there. .hero__panel, .claims, .seams__* are unused by the homepage now, but styles.css is shared with five pages and deleting shared rules on inspection alone is how you break four of them. Separate pass with a usage check.

Sequencing

This branch now contains #218 (the markdown projection) — the gate reads its output, so they had to travel together. #218 can be closed as superseded, or merged first; either way this merges cleanly.

#216 is independent and still worth landing: its .provenance CSS becomes dead once this merges (the cards are gone), but the card-inset gate it adds is the durable half and still guards .card on /map, /desk, /contracts and /conformance.

Verified locally

Run the way CI runs them — node build.mjs plus the four brand tools from a clone of brand at the installed version:

  • npm run check (23 gates) ✓
  • npm run legibility — PASS; and red through the full build on an injected metaphor ✓
  • gen-markdown --check
  • brand meta / content (24/24 copy scenarios) / coverage --colors / a11y
  • axe-gate — 13 pages, 0 serious/critical ✓
  • a11y-heuristic — 0 errors ✓
  • structure-audit ✓ (baseline re-blessed; check-outline is the independent invariant that makes re-blessing safe, and it passes)
  • rendered sweep at 390 / 768 / 1280: no horizontal overflow, no wrapped code lines

The gate proves the page didn't regress. It cannot prove the page lands — that's still one outside human, and nothing here changes that.

claude added 3 commits August 21, 2026 01:55
"Also we repeat ourselves a lot the pages should project into markdown
we could read those." Two asks, and the second is why the first matters.

THE PROJECTION. HTML is a bad medium for reading your own writing. A diff
on index.html is markup with sentences buried in it, and the rendered page
is laid out to persuade rather than to be legible. There was no way to
read what this site SAYS without a browser or a grep.

Now every page has a .md at the same route — /index.md, /map.md,
/desk.md, /blog/*.md — listed in llms.txt and covered by the signed
whole-site manifest. One rule, two cases: a page authored in markdown
serves its SOURCE (projecting the built HTML back would create a second
copy of every post to keep in sync, which is the exact failure this
change is about); every other page is projected from its BUILT html, so
the generated regions are in it.

The projection is also committed under content/pages/ and drift-checked,
like every other projection here. That is the half that pays off in
review: a copy change shows up as a prose diff next to the markup one.

The stamp region is dropped from the projection. It is rewritten on every
build, so carrying it into a committed file would make that file stale the
moment anything else merged — and dropping it makes the projection a pure
function of the source, which is what lets --check mean anything.

THE MEASUREMENT. The obvious check — find sentences that appear twice —
finds almost nothing: 2% of sentences repeat verbatim, and most of those
are nav chrome. That number is reassuring and wrong. This site repeats
itself by RESTATEMENT. The homepage says, in three places:

  "Every claim on this page is graded against the running code."
  "Every claim here is graded against the running code."
  "A solo project — every claim on this page graded against the code
   that backs it."

Three phrasings, no two identical. So the comparison is over content
words: strip stopwords and short words, take the set, score pairs by
Jaccard overlap. It reads the markdown, not the HTML, so it sees the
words a reader sees and nothing about markup.

  19 restatement pairs — 8 within a page, 11 across pages.

Ratcheted, not a cliff. That count is real and large; failing the build
on it today would block every unrelated change, and a gate nobody can go
green against gets switched off. The committed baseline is a ceiling: a
change may not add repetition, and --update lowers it when a change
removes some.

A missing baseline is refused rather than silently written. That happened
once here: `npm run check` ran before the projection existed, saw only
the five blog posts, and wrote a ceiling of 4 that the next run then
"regressed" against. A ratchet that picks its own starting point from
whatever it saw first is worse than none.

Both gates are mutation-tested in their lane before either is trusted —
edit the projection, prove the drift check goes red; lower the ceiling,
prove the ratchet goes red. Rule 3: a gate's own claim about itself is
not evidence.

NOT IN SCOPE: cutting the repetition. This lands the instrument and
records the number. What to cut is editorial and should be decided while
looking at the list, not bundled into the change that produced it.

The projection also surfaced something worth fixing separately: the
room/door/guest definitions are marked up as styled spans rather than a
description list, which is why they need a special case here to avoid
reading as "rooma named bundle of doors".

Closes #217
cell(): a pipe ends a GFM table cell, so it has to be escaped — but the
text reaching cell() has already been through esc(), which escaped its
backslashes. `.replace(/\|/g, "\\|")` was therefore correct only by
accident: an escaper that handles `|` but not `\` is wrong on its own
terms, and re-running a backslash pass would double what esc() emitted.
It now walks the string once, consuming a backslash together with
whatever it escapes, so a bare pipe from a code span or a link
destination — neither of which goes through esc() — is escaped exactly
once and an already-escaped one is left alone.

check-repetition: `<!--[\s\S]*?-->` left an UNTERMINATED comment in
place, and its body was then counted as prose. `(?:-->|$)` is both the
complete pattern and the more correct one — swallowing to end-of-file is
what an unterminated comment actually means.

Nothing here renders as HTML, so neither was an injection. Both were
still real defects in code whose whole job is to be exact about text.
New copy, replacing the page wholesale. Hero (the problem, the move, one
allow/deny transcript) → What's here (three repos, a line each) → Status,
graded (three grades, the six claims folded into them) → If you want to
go deeper → Who.

  focus-budget, index.html:  1516w → 460w · grade 13.2 → 11.4
  all three FOCUS_SECTION_TOO_LONG warnings: cleared
  remaining "jargon": delanghe, brooklyn, polyform — proper nouns

WHAT MOVED, AND WHY IT MOVED RATHER THAN BEING SUPPRESSED.

gen-seams spliced the capability-seam grid into a homepage card that no
longer exists. The seams move to /map — the page about what exists, and
where the six narrowest, most concrete entries belong anyway.

gen-registry spliced a three-tile count summary into #graph. /map already
renders the same numbers as tiles, with the whole registry underneath, so
the second renderer goes rather than moving: two renderers for one dataset
is the drift this project argues against. The script keeps its data duties
— refresh the seed from each package's bounded.*, and validate it — and
sync-registry.yml now checks the seed and the page that renders it.

check-outline asserted "at least one .seams__head on index.html". That is
an assertion about the homepage's SHAPE, not about the component: moving a
card to the page it belongs on failed the gate with nothing regressed.
Presence is now global across surfaces, and map.html joins the surfaces
checked — so /map's outline is under contract for the first time.

content/marketing.feature pinned micro-copy that is gone. Scenarios are
deleted alongside the copy they described; leaving them to fail, or
loosening them to pass, would both be worse.

content/grounding.json gains two phrasings. The two ENFORCED claims kept
their meaning and changed their wording — "fail CI on drift" became "fail
the build on drift" — so the grounded phrase follows the claim. Same
evidence, restated, not a new assertion.

DROPPED ON PURPOSE: the room/door/guest hero figure; the bet and model
sections; the in-page self-check demo (~100 lines of JS the page itself
labelled "a demo, not proof"); the two provenance cards; and everything
the homepage restated about /desk, /contracts, /conformance and /ledger —
those stay in the site nav on every page, the homepage just stops saying
them again.

All six claims in integrity/claims/claims.jsonld survive, folded under
their grade. claim-provenance and claim-broker are no longer single-sourced
tokens: the new wording does not carry their grounded phrases, so they are
inline body prose like the two aspirational claims already were. The
single-source floor still holds at 25 ≥ 22.

One word is not Bobby's. "Every deploy is keyless-signed" reads to the
upstream honesty lane as an unscoped coverage claim — it did reject the
same shape earlier tonight — so it says "Each deploy". Flagged for review.

The hero transcript is three lines per case, not the one-liner it was
drafted as. `.code` wraps rather than scrolls, deliberately, so a <pre>'s
min-content cannot inflate the page on a phone; a line that does not fit
therefore breaks mid-clause. Measured at 390/768/1280: no line wraps now.

Closes #219
claude added 2 commits August 21, 2026 03:08
Bobby's instrument, landed. Deterministic half runs in the hermetic
phase directly after gen-markdown.mjs, because the projection is what it
reads: the words a stranger gets, with the markup gone.

  the rewrite:   PASS — hero 91w · 4 sections · 3 acronyms
  the live page: FAIL (6) — 20× "door", 11× "room", 10× "guest",
                 "Flagship", "At scale", 21 acronyms against a budget of 10

The judged half (scripts/legibility/coldread.feature) is NOT wired. Its
own header says why, and the pipeline entry repeats it: a flaky proxy in
the inner loop rots trust in the gate around it. It runs at deploy, and a
green judge run is not the human test.

TWO CHANGES TO THE INSTRUMENT AS DELIVERED, both flagged rather than
buried.

1. The sentence rule split on terminal punctuation only, so it ran
   straight through blank lines: six seam rows with no full stop between
   them measured as one 59-word sentence. That is a false positive about
   the instrument, not a finding about the page, and it would fire on any
   page with a short unpunctuated list. Blank lines now split first. Not
   an extension — a sentence does not span a paragraph break, so this is
   the sentence rule measuring sentences.

2. The hero budget reads "words before the first ---", and the markdown
   projection emitted no --- at all, so every page measured as 100% hero
   and failed by 300 words. Fixed in the PROJECTOR, not the gate: a
   <header> that is a direct child of <main> is the hero, and markdown's
   only way to say "the hero ended" is a thematic break. The alternative
   was putting an <hr> in the page so the markdown would have one — adding
   visual furniture to satisfy a gate, which is the exact dishonesty these
   gates exist to catch.

Mutation-tested through the real build, not against a copy: swap "a named
bundle of permissions" for "a room of doors the guest holds", rebuild, and
the build stops at the legibility step naming all three words. (First
attempt at this reported a red build that was actually the catalog
staleness check failing earlier in prebuild — the gate had not run at all.
Re-verified.)

Repetition ratchets 19 → 7 pairs on the back of the rewrite. Two remain
within a page, five across pages.

The gate proves the page did not regress. It cannot prove the page lands.
That is still one outside human, and this changes nothing about that.
@bdelanghe bdelanghe changed the title Rewrite the homepage: 1,516 words to 460 (#219) Rewrite the homepage, and wire the legibility gate that holds it (#219) Aug 21, 2026
Comment thread scripts/legibility/check.mjs Fixed
Two overclaim errors from the upstream copy gate, both on new copy, both
correct.

"Here, EVERY privileged action goes through one gate instead."

That is the thesis sentence, and it asserts universal present-tense
coverage that the Status section three screens down contradicts in its
own words: git writes are "tested end to end, but opt-in today", and prx
and claude-box "converging onto guest-room" is graded Aspirational. The
page was claiming in the hero what it grades as unfinished below. Now:
"Here, privileged actions go through one gate instead." Same sentence,
no quantifier, and it stops disagreeing with the page it sits on.

"CI proves it on every commit" — the Enforced grade's definition, an
absolute with no source in its block. The rule allows either scoping or a
link, which is why "Each deploy is keyless-signed and recorded in a public
log — provenance.json, Rekor, and this build's entry" passes: the sources
are right there. This one has nowhere to point without adding furniture,
so it scopes instead: "A check proves it, and the build fails without it."

CODEQL, on the delivered check.mjs: `<!--[\s\S]*?-->` left an unterminated
comment in place, so its body would be counted as prose and every budget
would then be measuring an authoring note. Completed to `(?:-->|$)`. Third
change to the instrument, same character as the other two — not an
extension, a rule doing what it says.

Still PASS at hero 90w · 4 sections · 3 acronyms, and the live page still
FAILs on all six documented counts.
@bdelanghe
bdelanghe marked this pull request as ready for review August 21, 2026 13:47
@bdelanghe
bdelanghe merged commit c7dceb8 into main Aug 21, 2026
23 checks passed
@bounded-systems-front-desk bounded-systems-front-desk Bot moved this from Todo to Done in Front Desk Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Rewrite the homepage: 1,516 words to 460

3 participants