Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions docs/evidence/internal-links-2026-08-09.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# Internal page links point at final clean URLs — live-deployment verification

Date: 2026-08-09
Scope: the five public tinystudio.io pages — `index.html` (home) and `audit.html`, `agents.html`, `pricing.html`, `specimen.html` (dogfood finding 996dffe45ef7, audit 20260808T074205Z-msk2fl3n).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include the served confirmation page in the closeout

The scope incorrectly treats these as the site's only public pages: successful HTML signups redirect to /brief-requested in src/worker.js:271-283, and the resulting served page still contains five .html anchors in public/brief-requested.html:29-54. Those links incur the exact 307 hops documented in this receipt, so the claims that this shape is absent from every page link and that the site has zero redirecting internal links are incomplete; fix and probe the sixth page and add it to the guard, or explicitly limit the conclusions to indexable pages.

Useful? React with 👍 / 👎.

This receipt records a real-browser measurement of the deployed site. It is behavior evidence, not a source check, and it does not claim anything about ranking, traffic, or search results.

## What was measured

The leak audit this site sells flags a homepage whose internal links do not
point at the final destination URL: every link that resolves through a
redirect is a redirecting internal link, and search engines value the link at
the redirected address, not at the hop it started from. The audit run
Comment on lines +9 to +12

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the unmeasured search-engine claim.

Line 5 limits this receipt to behavior evidence. Lines 11-12 assert how search engines value redirected links. The recorded checks do not measure that behavior. Remove this sentence or identify it as the audit’s rationale, not as a verification result.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/evidence/internal-links-2026-08-09.md` around lines 9 - 12, Update the
audit description around “search engines value the link at the redirected
address” to remove that unmeasured claim or explicitly label it as the audit’s
rationale rather than a verification result. Keep the documented evidence
limited to the recorded redirect behavior.

20260808T074205Z-msk2fl3n found exactly that fault on this site's own home
page (finding 996dffe45ef7, "Redirecting internal links on home"): before the
fix, `public/index.html` linked its logo, navigation and specimen call-out at
`index.html`, `audit.html`, `agents.html`, `pricing.html` and `specimen.html`
(verified against the parent of the fix commit 44b241c). The deployed worker
serves extensionless twins for all five pages and 307-redirects every `.html`
form to its clean twin — verified live, `curl -sI https://tinystudio.io/audit.html`
returns `307 Location: /audit` — so each of those home links was a
redirecting internal link.

The fix (PR #34, "fix(public): point internal page links at final clean
URLs") changed all five public pages to point every page link at the clean
URL the worker serves (`/`, `/audit`, `/agents`, `/pricing`, `/specimen` —
never at a `.html` file that resolves to it), and added a source-string CI
guard (`scripts/check-site.mjs`, "Internal page links (dogfood 996dffe45ef7)"
section) that fails the build if any of the five pages carries an anchor whose
target is one of the five `.html` page names.
Comment on lines +24 to +29

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Align the CI-guard claim with its implementation.

The receipt says the guard rejects any anchor targeting a .html page name. The supplied scripts/check-site.mjs:1250-1284 implementation reads only href="..." and compares raw values against five exact keys. It does not reject equivalent forms such as single-quoted or unquoted attributes, /agents.html, ./agents.html, or agents.html?x.

Harden the guard with HTML and URL normalization, or narrow this receipt to the exact syntax currently enforced.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/evidence/internal-links-2026-08-09.md` around lines 24 - 29, Align the
“Internal page links” claim with the actual guard in
scripts/check-site.mjs:1250-1284. Either harden the guard to parse anchors
regardless of quote style and normalize leading paths, relative prefixes, and
query strings before checking the five .html page names, or revise the receipt
to state that only exact double-quoted href values are enforced.

Comment on lines +28 to +29

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Qualify the claimed CI coverage for .html links

When a future edit uses a root-relative link such as /audit.html—the same style used by the current clean links—the guard does not fail: scripts/check-site.mjs:1273-1277 compares the raw href against keys like audit.html, so /audit.html, ./audit.html, and absolute same-origin forms all bypass it. This overstates the CI enforcement recorded by the receipt and could let the closed finding regress unnoticed; normalize same-origin hrefs before comparison or narrow this claim to the exact relative forms the guard detects.

Useful? React with 👍 / 👎.


This receipt closes the remaining gap: the live deployment was never measured.
The measurement below verifies the deployed pages in real Chromium.

## Environment

- Node v22, Playwright 1.62.1, Chromium headless (ms-playwright cache).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Make the reproduction method complete.

The receipt records only “Chromium headless” and omits the Chromium revision. The snippets also omit the definitions of url, page, context, and abs, plus the listeners and assertions for console errors, page errors, status, CSP, final URL, and redirect chains.

Include the complete script and browser revision, or rename this section from “Exact verification method” to “Method summary.”

Also applies to: 110-130

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/evidence/internal-links-2026-08-09.md` at line 36, Update the “Exact
verification method” section to include the complete reproduction script,
including definitions for url, page, context, and abs, all relevant listeners,
and assertions for console errors, page errors, status, CSP, final URL, and
redirect chains; also record the Chromium revision alongside the Playwright
version. If the full script and revision cannot be provided, rename the section
to “Method summary.”

- Live target: `https://tinystudio.io/` and its four sibling public pages,
served by the deployed Cloudflare Worker (ASSETS binding; see
`src/worker.js`). All five pages were visited at their final URLs (`/`,
`/audit`, `/agents`, `/pricing`, `/specimen`), the addresses a browser
actually lands on.
- Wait: `domcontentloaded`; every anchor with a non-external, non-`mailto:`,
non-`tel:`, non-hash-only href collected from the loaded document.
- Each internal link target was then probed with `maxRedirects: 0` — a
redirecting link returns a 3xx with a `Location` header, a clean link
returns 200 with no `Location`.
- Console errors and page errors captured per page; HTTP status,
`Content-Security-Policy` presence, final URL and any load-time redirect
chain captured from the served response.

## Results (deployed site, 2026-08-09)

### Per-page load

| Page | HTTP | CSP header | final URL | redirects during load | console errors | internal link probes |
|---|---|---|---|---|---|---|
| index.html (home, `/`) | 200 | yes | `https://tinystudio.io/` | none | none | 5 |
| audit.html (`/audit`) | 200 | yes | `https://tinystudio.io/audit` | none | none | 5 |
| agents.html (`/agents`) | 200 | yes | `https://tinystudio.io/agents` | none | none | 5 |
| pricing.html (`/pricing`) | 200 | yes | `https://tinystudio.io/pricing` | none | none | 6 |
| specimen.html (`/specimen`) | 200 | yes | `https://tinystudio.io/specimen` | none | none | 5 |

### Internal link probes

Every internal link target on every page returned **200 with no `Location`
header** — zero redirecting internal links. The probes, per page:

- homepage (`/`): `/`, `/audit`, `/agents`, `/pricing`, `/specimen`
- audit page (`/audit`): `/`, `/audit`, `/specimen`, `/agents`, `/pricing`
- desk page (`/agents`): `/`, `/audit`, `/agents`, `/pricing`, `/#start`
- pricing page (`/pricing`): `/`, `/audit`, `/agents`, `/pricing`, `/#start`, `/specimen`
- specimen page (`/specimen`): `/`, `/audit`, `/agents`, `/pricing`, `/#start`

(`/#start` is a same-page hash link on the clean address; the probe resolves
the path before `#` to `/` and confirms it serves 200 with no redirect.)

### The `.html` forms the pre-fix home linked at (baseline)

Probed the same way, all five still 307-redirect to their clean twins — the
exact shape the finding flagged, now absent from every page link:

| `.html` form | status | `Location` |
|---|---|---|
| `index.html` | 307 | `/` |
| `audit.html` | 307 | `/audit` |
| `agents.html` | 307 | `/agents` |
| `pricing.html` | 307 | `/pricing` |
| `specimen.html` | 307 | `/specimen` |

In-browser demonstration of what a pre-fix link did: navigating
`https://tinystudio.io/audit.html` in Chromium follows the redirect —
request chain `[307] /audit.html` → `[200] /audit`, final URL
`https://tinystudio.io/audit`.

## Source checks on the current head

Re-verified against the current origin/main head (b3d2b83, "docs(evidence):
close out canonical-URL finding 6631c0ab0454 against current main and live",
merged 2026-08-09) after the subsequent page edits (canonical URLs, sitemap) —
none of which was allowed to regress the guarantee:

1. `npm run check` passes: the "Internal page links (dogfood 996dffe45ef7)"
guard finds no anchor targeting any `.html` page name on any of the five
public pages, and every other site check (meta descriptions, canonical
URLs, structured data, internal links, sitemap) passes too.
2. `npm test` passes: the source checks above plus the heading-hierarchy,
sitemap, agent-worker and agent-UI suites (15/15 UI subtests, all suites
green).

## Exact verification method (reproduce)

1. Requires `playwright` + Chromium (same dependency the CI render-blocking
step installs).
2. For each page, launch a headless Chromium context, capture console/page
errors, then:

```js
const response = await page.goto(url, { waitUntil: "domcontentloaded" });
const hrefs = await page.evaluate(() =>
[...document.querySelectorAll("a[href]")].map((a) => a.getAttribute("href")));
```

3. For every internal href (not external, not `mailto:`/`tel:`, not
hash-only), probe the absolute target with `maxRedirects: 0` and assert
`status === 200` and no `Location` header:

```js
const pr = await context.request.get(abs, { maxRedirects: 0 });
// assert pr.status() === 200 && pr.headers()["location"] === undefined
```

4. Run against `https://tinystudio.io/`, `/audit`, `/agents`, `/pricing`,
`/specimen`. Baseline: probe the five `.html` forms and observe the 307 +
`Location` (this is the shape the finding flagged, now present only on
unlinked addresses).

## Closeout

Nothing further to change: the code-side fix (PR #34) and CI enforcement (the
"Internal page links (dogfood 996dffe45ef7)" guard in `scripts/check-site.mjs`)
are merged in origin/main, `npm run check` and `npm test` pass on the current
head, and the deployed site serves zero redirecting internal links on all five
public pages — including the home page the finding flagged. The receipt now
records the closeout on the current head so the finding cannot be re-opened by
tracker drift.
Comment on lines +139 to +145

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Limit the closeout claim to the measured deployment.

A receipt dated August 9, 2026 and a source guard cannot ensure that the finding “cannot be re-opened by tracker drift.” A later deployment can diverge from the measured deployment. State that the finding was verified at commit b3d2b83 on August 9, 2026, and that CI reduces regression risk.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/evidence/internal-links-2026-08-09.md` around lines 139 - 145, Revise
the closeout statement to limit its claim to the measured deployment: state that
the finding was verified at commit b3d2b83 on August 9, 2026, and describe the
CI guard as reducing regression risk. Remove the assertion that the finding
cannot be re-opened by tracker drift while preserving the documented test and
deployment results.

Loading