Queue-North-Website/scripts
null 0d575f2977 feat(build): the copy is checked before a single page is built from it
src/data is prose in a data structure, and nothing checked it. The long-form
service pages make that dangerous in a specific way: their copy arrives as an
owner-approved markdown sheet that MIXES DIRECTIONS TO THE WEBSITE MANAGER INTO
THE COPY. "Do not promise that every number is always portable." "Keep this
factual:" "Place an official 8x8 Work screenshot beside this section." Those
lines look exactly like copy, and publishing one puts an internal instruction on
a customer-facing page.

scripts/lib/content.js decides whether the content layer is publishable, and
prerender.js runs it before rendering anything, so every build enforces it: the
pre-commit hook, npm run verify, and the Docker image build. It refuses a
website-manager direction, an em dash, a U+FFFD, markdown or an HTML tag left in
a string, an unknown block type, a section id that is not letter-first, unique
and free of the layout's own ids, a section that does not open with its direct
answer (unless it declares kind list or faq), a FAQ question with no answer, a
link to a route or fragment that does not exist, an image whose src is missing
from public/ or has no alt or no dimensions, and the missing benefits or
idealFor list that the short layout maps without checking. A description over
160 characters is a note, not a failure: owner-approved copy is published as
written.

scripts/lib/routes.js is now the one route list. prerender.js built its own
while src/routes.jsx built the router's, and nothing compared them: a route in
one and not the other is never prerendered, so the server answers it with
404.html while the site's own navigation links to it. entry-server.jsx exports
the router table so the build can compare the two.

Proven by mutation, seventeen of them, each expecting exactly one finding and
getting it: unknown block type, FAQ answer removed, answer moved below its list,
duplicate id, digit-leading id, link to /services/contact-centre,
#no-such-section, missing image file, image without dimensions, image without
alt, em dash, a manager direction, markdown bold, U+FFFD, an HTML tag, missing
h1, empty section. Both generated content modules pass unmutated. Against a real
build: an em dash added to industries.js failed npm run build naming the field,
and a /pricing route added to src/routes.jsx failed it naming the route.

Closes #230.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 04:43:01 -05:00
..
lib feat(build): the copy is checked before a single page is built from it 2026-09-10 04:43:01 -05:00
verify.d security: the scanner never ran its private-key pattern, and verify never saw dist 2026-09-10 04:23:39 -05:00
backup.sh chore: adopt template scripts and git hooks, retire phase-versioning 2026-08-18 01:18:20 -05:00
check-env.sh security: the scanner never ran its private-key pattern, and verify never saw dist 2026-09-10 04:23:39 -05:00
deploy.sh fix(deploy): stop two ways this tooling would have broken production 2026-08-18 03:33:20 -05:00
doc-triggers.py chore: adopt template scripts and git hooks, retire phase-versioning 2026-08-18 01:18:20 -05:00
docker-test.sh chore: add docker-push.sh, docker-test.sh, npm scripts, bump v0.5.0 2026-05-14 01:18:44 -05:00
forgejo-issue.py chore: adopt template scripts and git hooks, retire phase-versioning 2026-08-18 01:18:20 -05:00
healthcheck.sh fix(infra): queuenorth.com is the production origin, and it is this deployment 2026-08-18 02:08:12 -05:00
preflight.sh fix(infra): queuenorth.com is the production origin, and it is this deployment 2026-08-18 02:08:12 -05:00
prerender.js feat(build): the copy is checked before a single page is built from it 2026-09-10 04:43:01 -05:00
qa-browser.mjs fix(ui): header CTA clipped at iPad portrait, and reCAPTCHA cut off at 320px 2026-08-18 04:05:37 -05:00
release.sh fix(deploy): stop two ways this tooling would have broken production 2026-08-18 03:33:20 -05:00
restore-check.sh chore: adopt template scripts and git hooks, retire phase-versioning 2026-08-18 01:18:20 -05:00
secrets.sh security: the scanner never ran its private-key pattern, and verify never saw dist 2026-09-10 04:23:39 -05:00
status.sh chore: adopt template scripts and git hooks, retire phase-versioning 2026-08-18 01:18:20 -05:00
validate-content.js feat(build): the copy is checked before a single page is built from it 2026-09-10 04:43:01 -05:00
verify.sh chore: adopt template scripts and git hooks, retire phase-versioning 2026-08-18 01:18:20 -05:00