Cold read of https://bounded.tools, 2026-09-03, against the live deploy (commit 3a4ac1d).
The drift
data/nav.jsonld describes itself as the canonical source, and states the invariant:
build.mjs renders the primary site nav (cross-page links, identical on every page) and the home-only on-page section list from this file, so the two never drift.
index.html:86 and contract/page.ts:36 repeat it. The build does not hold it. build.mjs:56:
for (const f of ["index.html", "404.html"]) {
const p = join(dist, f);
const html = await readFile(p, "utf8");
await writeFile(p, html.replace("<!--SITE-NAV-->", siteHtml).replace("<!--DOC-TOC-->", tocHtml));
}
Two files. contracts.html, ledger.html and map.html are copied verbatim a few lines above with no nav placeholder to fill, and the generated pages (/conformance, /blog/*) carry their own hand-written headers.
What ships
Measured against the live site, four different navigations:
| Pages |
Header |
/, /404 |
Desk, Map, Contracts, Conformance, Ledger, Writing, GitHub |
/conformance |
bounded.tools, Honesty, Proof, Writing, GitHub |
/blog/, /blog/* |
bounded.tools, The bet, Writing, GitHub |
/map, /contracts, /ledger |
no nav at all, only a ← bounded.tools back-link |
Two consequences.
One destination, three names. /#status is "Status" on the home page, "Honesty" on /conformance, and "The bet" on the blog. A reader cannot learn the site's shape, because the shape changes under them.
Most of the site is a cul-de-sac. The full internal link graph of the built pages:
/contracts links only to /.
/ledger links only to / and /ledger.jsonl.
/map links to /, /contracts, /ledger.
/conformance is linked from /, /404, and one blog post. Nothing else reaches it.
So a visitor who lands on /contracts from a search result has one way onward, and the conformance report has no path in from three of the five internal pages.
Why this one matters more than its size
The repo's stated bet is that generated surfaces cannot drift from their source. Here a hand-maintained header drifted from a canonical JSON-LD file that exists specifically to prevent it, and the assertion that it cannot drift is shipped in the served HTML. The gate that would catch it is the one that was never written.
Suggested shape
- Give every page in
dist/ the <!--SITE-NAV--> placeholder and widen the build.mjs loop to every HTML file it emits, rather than a hardcoded pair. The generated pages (gen-conformance.mjs, gen-blog.mjs) should emit the placeholder too and drop their hand-written headers.
- Add a check that fails the build when any page in
dist/ lacks a <nav aria-label="Main"> whose links equal nav.jsonld's site[]. That is the forcing function the comment currently asserts without one.
- Separately: the home page's "Writing." block links one post (
trust-lives-outside-the-page) and not /blog/, so five of six posts are reachable only through the nav item that most pages do not have.
Filed from a cold read, unclaimed and unassigned.
Cold read of https://bounded.tools, 2026-09-03, against the live deploy (commit
3a4ac1d).The drift
data/nav.jsonlddescribes itself as the canonical source, and states the invariant:index.html:86andcontract/page.ts:36repeat it. The build does not hold it.build.mjs:56:Two files.
contracts.html,ledger.htmlandmap.htmlare copied verbatim a few lines above with no nav placeholder to fill, and the generated pages (/conformance,/blog/*) carry their own hand-written headers.What ships
Measured against the live site, four different navigations:
/,/404/conformance/blog/,/blog/*/map,/contracts,/ledger← bounded.toolsback-linkTwo consequences.
One destination, three names.
/#statusis "Status" on the home page, "Honesty" on/conformance, and "The bet" on the blog. A reader cannot learn the site's shape, because the shape changes under them.Most of the site is a cul-de-sac. The full internal link graph of the built pages:
/contractslinks only to/./ledgerlinks only to/and/ledger.jsonl./maplinks to/,/contracts,/ledger./conformanceis linked from/,/404, and one blog post. Nothing else reaches it.So a visitor who lands on
/contractsfrom a search result has one way onward, and the conformance report has no path in from three of the five internal pages.Why this one matters more than its size
The repo's stated bet is that generated surfaces cannot drift from their source. Here a hand-maintained header drifted from a canonical JSON-LD file that exists specifically to prevent it, and the assertion that it cannot drift is shipped in the served HTML. The gate that would catch it is the one that was never written.
Suggested shape
dist/the<!--SITE-NAV-->placeholder and widen thebuild.mjsloop to every HTML file it emits, rather than a hardcoded pair. The generated pages (gen-conformance.mjs,gen-blog.mjs) should emit the placeholder too and drop their hand-written headers.dist/lacks a<nav aria-label="Main">whose links equalnav.jsonld'ssite[]. That is the forcing function the comment currently asserts without one.trust-lives-outside-the-page) and not/blog/, so five of six posts are reachable only through the nav item that most pages do not have.Filed from a cold read, unclaimed and unassigned.