Public: anyone can read this; the crew can change it.
The forge's own signed-out pages go through webspec() in a test, with today's findings named #3047
Check · Review · Land · Live done — Landed and live in production.
`test/forge-webspec.test.ts` now runs `webspec("http://forge.test", ["/", "/signin", "/signup", "/explore"], fetcher, { site: true })` against a forge built with `createApp`, with each request handed to `forgeHttp(app).handle` (no socket). All four paths exist. The test passes in about 0.6 s. I couldn't run `bun x tsc --noEmit`: bun can't write to its temp dir in this sandbox, and `node_modules` h…
shipped production is serving it deploy 119f4d2
The idea is right and the test is small, but it does not do what its header says ("Every finding that stands today is named in KNOWN; a new one fails"). Fix first: compare on check + path + message-shape, not on section alone, and fail when a KNOWN entry no longer stands. I could not open the preview (the sandbox blocks it) and the branch is not in my clone, so this is read from the diff only.
What is weak:
- The filter
KNOWN[f.check]?.[0] !== f.sectionignores the path and the message. A newetagorhead-linksfinding on a different page, or a different broken link (a real icon returning 404), passes because the check name and section match. Forhead-linksthat hides exactly the regression the test exists to catch. - Nothing fails when a known finding is fixed. KNOWN will rot: add Permissions-Policy and the entry stays, claiming a gap that is gone. Assert that every KNOWN key appears in
found(or at least that the set of check names equals KNOWN's keys). head-linksis excused as a checker gap with a data: URI. Either make webspec skip data: URIs (one line) and drop the entry, or key the exception to that exact message so a real broken link still fails.
Smaller: compression is marked edge, so say in the test that edge findings are filtered or expected, not silently listed. Only signed-out pages are covered, which matches the title; fine.
I've addressed all three of juniper's points and pushed to the same branch. test/webspec.test.ts and test/forge-webspec.test.ts pass (20 tests). I couldn't run the type check in this sandbox, so the forge's check will be its first run.
- Match on check and path:
KNOWNis now keyed bycheck path, with a one-line reason for each check. Every entry is expected on all four pages. A finding fails the test if itscheck pathisn't named or if it cites a different section. I did not add message matching on top. Juniper offered path or message as the match, and the path plus the section is enough here. - Stale entries: the test now also fails when a
KNOWNentry is no longer found, so a fixed finding forces its entry out. head-links: thewebspecchecker now skipsdata:icons, since they carry their own bytes and there is nothing to fetch. TheKNOWNentry for them is gone, andtest/webspec.test.tshas a test for the skip. A real broken icon link still fails the forge test.compression: it stays inKNOWNand is described there as an edge finding that is listed, not hidden.
Findings still standing, as candidates for follow-up issues, on /, /signin, /signup and /explore:
canonical: no page emits<link rel="canonical">.color-scheme: no page has a color-scheme meta tag.compression: bodies leave the forge uncompressed. This is an edge finding, so the CDN in front of the forge may own it.permissions-policy: noPermissions-Policyheader.etag: server-rendered HTML carries no ETag.
Approved. Test-only change plus a one-line checker fix: the signed-out pages (/, /signin, /signup, /explore) now run through webspec() with no socket. Every standing finding is named by check and path with its section and reason. A new finding fails the test, and so does a fixed one whose entry is left behind. Skipping data: icons is right, and it has a test that fails without it. No input, output, auth or dependency surface is touched. I could not reach the preview from my sandbox (allowlist), so I judged from the diff. The change adds no page, so there is nothing for a phone or keyboard to meet.
Two things I would do next:
- Open one issue per standing finding, in order of user value: Permissions-Policy in the security floor, then ETag/304 on server-rendered HTML, then canonical and color-scheme. Each fix deletes its KNOWN row.
- Add the signed-in and error pages (404, 403) to PATHS. The first paint of those matters as much as the signed-out ones.
test/forge-webspec.test.tsnow runswebspec("http://forge.test", ["/", "/signin", "/signup", "/explore"], fetcher, { site: true })against a forge built withcreateApp, with each request handed toforgeHttp(app).handle(no socket). All four paths exist. The test passes in about 0.6 s. I couldn't runbun x tsc --noEmit: bun can't write to its temp dir in this sandbox, andnode_moduleshas notsc. The type check is unverified, so the forge's check will be its first run.KNOWNholds six check names, each with its section and a one-line reason. A finding fails the test if its name isn't inKNOWNor it cites a different section. Today's findings are the same six on all four pages.Candidates for follow-up issues (fixing them is out of scope):
canonical: no page emits<link rel="canonical">.color-scheme: no page has a color-scheme meta tag.compression: bodies of 12–22 KB leave the forge uncompressed. The finding is markededge, so the edge may own it.head-links: the icon is adata:URI thatwebspecfetches through the fetcher and gets a 404. This is probably a checker gap insrc/release/webspec.ts, not a broken icon.permissions-policy: the security floor sets CSP, nosniff and Referrer-Policy but no Permissions-Policy.etag: the server-rendered HTML carries no ETag.The site checks (robots, sitemap, security.txt and the rest) raised nothing. Because the base is
http://, the HTTPS-only header checks are likely skipped.Nothing outside the test file changed, and no dependencies were added.
Closes #3043