Skip to content

ADR 0144: Site URLs are canonical at the apex and redirects resolve in one hop

Status: accepted

Context

§

The site served /docs, /docs/, and /docs/index.html as duplicate 200 responses, raw Markdown editions carried no indexing policy, and no canonical or redirect machinery existed. That was harmless before publication and dangerous at launch: crawlers could split authority across representations, and a future rename could create a chain if each move were handled locally.

Redirects have two different owners. A moved page knows its own historical addresses, while a section rename has no single destination document that can own the whole structural move. Heading fragments are different again: they never reach the server, so an HTTP redirect cannot preserve a renamed anchor.

Decision

§

The canonical production origin is https://discern.sh. HTML routes use no trailing slash and no .html suffix. HTTP, www, trailing-slash, and index.html variants return 308 to the final apex URL in one response. Every successful HTML page names itself with a canonical link; an explicit .md edition points to the HTML URL with a Link header and carries X-Robots-Tag: noindex, follow.

Destination-owned redirect_from claims feed the shared validated document registry. site/seo.tsx combines that registry with an explicit static map for section moves, derives matching .md redirects, and refuses dead targets, live-route collisions, double claims, chains, and loops. The site has no historical redirects before launch, so both registries begin empty; the slug freeze starts their maintenance obligation.

When a published heading changes, the page retains the old fragment as an explicit alias anchor beside the new heading. Fragment compatibility is page content, not server routing.

Unknown addresses return 404. A 410 is reserved for a deliberately retired URL that has no replacement and must be introduced through an explicit tombstone; the site does not infer gone routes from missing files. There are no tombstones at launch.

Consequences

§
  • A crawler sees one HTML address eligible for indexing for each page and reaches a moved page in one hop, including its Markdown representation.
  • A redirect mistake fails the gate before the handler can serve it.
  • Renaming a public page or heading now carries an explicit compatibility task; deleting a file is never enough.
  • Local development keeps its local origin for variant redirects, while page metadata still names the production canonical origin.
choose openEsc close