Skip to content
internal/resolution
On this page

Answering whether every reference a build emitted -- links, canonicals, sitemap entries, feed links -- resolves to a file the build itself actually wrote.

#internal/resolution

#internal/resolution

Package resolution answers whether every reference a build emitted resolves to a file it wrote.

The build derives every address from the address package, and the test suite walks a built tree asserting that each emitted reference lands on an emitted file. This package is that assertion as a user-facing check: one lint code, LINK001, over the output directory.

Five kinds of reference are covered, which is every kind the build emits:

- document-relative href/src attributes in the pages themselves, - the absolute rel="canonical" link on each page, - the absolute data-share-url addresses the share control offers, - the entries of every sitemap, - the entry links of the Atom feed.

The last four are absolute URLs, so they are checked against the site's configured base: an absolute URL that points into this site must name a page this build wrote, and one that points elsewhere is not ours to verify. A share address is a reference like any other -- it is handed to a reader to open -- so a control that offers an address the build did not write fails here rather than 404ing for whoever it was shared with.

#Two rules that are not about existence

A reference that decides where a CLICK goes -- an -- must be document-relative, so neither of these is allowed:

- /blog/hello/, origin-absolute, which resolves only when the site is served from an origin root and names nothing under a mount; - https:///blog/hello/, absolute against the site's own base, which is worse because it WORKS: on a preview, a mirror or any other mount the click silently leaves the tree the reader is looking at and lands on production. The file-existence half of this package can never see it -- the page it names really is there.

Absolute is right for metadata, which says where a page lives in the world: the canonical, the share addresses, sitemap entries and feed links, all checked above and none of them somewhere a click goes.

#A built tree can be older than its sources

Nothing invalidates a build output, so a page there carries whatever the last build rendered. A check run after a source doc comment changed is reading the old rendering, and a reference only that rendering named says nothing about the sources being checked -- it is an error no source edit can clear, and the whole tree's verdict misleads in both directions. [CheckProjectOutputResolution] takes the pages' current sources for that reason: a reference inside the content region of a page whose source no longer carries it is skipped. Page chrome, and any page whose source the caller does not have, are checked as they always were.

#LintCode

Go go
const LintCode = "LINK001"

LintCode is the lint code every unresolvable reference is reported under.

#Reference

Go go
type Reference struct

Reference is one internal reference a page writes: the attribute that carried it and the reference itself, unescaped.

#ReferenceTarget

Go go
func ReferenceTarget(pageRel, ref string) (string, bool)

ReferenceTarget resolves ref, written on the page at pageRel, to an output path.

The second result is false when the reference addresses nothing on its own: an empty value, or a bare fragment.

#SiteRelativePath

Go go
func SiteRelativePath(url, baseURL string) (string, bool)

SiteRelativePath is the output-relative path an absolute url names.

The second result is false when the URL is not this site's -- an external link, or a URL with no base to measure it against.

#PageReferences

Go go
func PageReferences(pageHTML string) []Reference

PageReferences returns every internal reference pageHTML writes.

Internal means "addressed within this site": a fragment, an empty value and every off-site scheme are dropped, so what is left is either a document-relative reference or an origin-absolute one -- which is a defect this package reports, not a reference to follow.

Go go
func NavigationReferences(pageHTML string) []string

NavigationReferences returns every pageHTML writes, unescaped.

These are the references a click follows, which is the set the mount-relative rule governs. Assets (src, a stylesheet link) are not here: they are fetched by the page rather than navigated to, and the assembly re-points some of them at site-level files after the graft.

#RewriteNavigationReferences

Go go
func RewriteNavigationReferences(

RewriteNavigationReferences returns pageHTML with every value the rewrite function answers for replaced by what it answered.

rewrite is handed each reference as it is written in the attribute, and returns the replacement plus whether it has one; a false second result leaves the attribute exactly as it was, escaping included.

It is here, rather than beside its caller, so that the repair a tree gets and the rule this package enforces read the same elements: an is what a reader clicks, and anything that rewrites those has to recognise them the way the check does or the two drift apart.

#ExternalReferences

Go go
func ExternalReferences(pageHTML string) []string

ExternalReferences returns every absolute http(s) URL pageHTML references.

This is the other half of PageReferences: what this package cannot verify against the emitted tree, because it names somebody else's server. Whether those still answer is the outbound check's question.

Origin-only resource hints are not references in that sense and are dropped before the scan -- see originOnlyRels.

#CheckOutputResolution

Go go
func CheckOutputResolution(

CheckOutputResolution checks every emitted reference in outputDir against what the build wrote, returning one LintCode diagnostic per unresolvable reference.

exemptElements names the elements whose content this build does not answer for: a region written from an assembled site's own data addresses that site, which the project carrying the region never writes, and the assembly's pass over the whole tree is the only place those references can be resolved.

outputDir is the build output directory; a directory that holds no HTML is not a built site and yields no diagnostics. baseURL is the site's configured base URL, used to tell this site's absolute URLs (canonicals, sitemap entries, feed links) from everyone else's.

mountPrefix is the path segments the site serves this output under ("alpha/"), empty when the output root is the served root. A mounted build's output is one subtree of a site it cannot see: its pages address the site level by climbing out of the output root, and its posts are grafted OUT of the subtree to the site root, so neither side's references resolve within this directory. Those are left to the assembly's own pass over the whole tree, which is the only place they can be answered. What still applies here applies everywhere: no reference a reader clicks may be origin-absolute or absolute against the site's base.

#CheckProjectOutputResolution

Go go
func CheckProjectOutputResolution(

CheckProjectOutputResolution is [CheckOutputResolution] for a tree whose pages' current sources are at hand.

currentSources maps an output-relative page path ("api/index.html") to that page's current resolved Markdown. Nothing invalidates a built tree, so its pages carry whatever the last build rendered: after a source doc comment changes, the built page still shows the old rendering, and a reference only that rendering named is not evidence about the sources being checked. A reference inside the content region of a page whose current source would not emit it is therefore skipped -- the built body predates its source. Every reference the page chrome writes, and every page with no source here, is checked as it always was.

What the source would emit comes from [html.SourceRefs], which runs the source's own references through the rewrite the renderer applies, so the comparison is between two emitted hrefs rather than between an href and the Markdown that produced it.

More tools from this site

  • claudestream Drive Claude Code from Python: run it as a subprocess and read its output as typed events, with async and sync sessions, sandbox policies, and tools you define in Python
  • claudewheel A TUI Claude Code Launcher that lets you have more than one profile, manage sessions lifecycle, pick the exact CC version, model to use (even older unlisted ones), pick which GitHub account to use, etc.
  • dirstat Fast, single-binary directory statistics CLI: every file under a tree grouped by format, with counts, sizes, and lines of code, as a colored terminal table or as JSON
  • fastware A batteries-included ASGI framework: msgspec JSON, a managed Granian server, dependency injection, SSE, WebSockets, auth, and a test client
  • go-toml-edit Zero-dep TOML editing library for Go with comment preservation
  • howmuchleft The fastest Claude Code statusline: context window, 5-hour, and weekly limit usage as three customizable gradient bars, rendering in about 6 ms
  • orxtra
  • pgdesign
  • predraw Declarative rendering pipeline: describe a scene in JSON and get SVG, PNG and WebP out, with light and dark style tokens, reusable components and text converted to path outlines
  • reposummary Turn a git repository's history into a Markdown journal: pick a time window or revision range and get a readable digest of what changed, optionally narrated by an LLM
  • rlsbl Release orchestration and project scaffolding CLI that bumps versions, validates a structured JSONL changelog, tags only the commit CI verified, and publishes to npm, PyPI, Go and more
  • safegit git wrapper CLI that gives each commit its own temporary index and retries ref updates on conflict, so concurrent agents share one repository
  • saferm Command-line replacement for rm that archives every deletion with a mandatory reason and the context it ran in, so deleted files can be listed, inspected and restored
  • strictcli
  • stricttest An always-on test-isolation floor: a pytest plugin and a Go env-hygiene module that make a test suite structurally unable to reach real credentials, the real HOME, the network, or the development repository.
  • wesktop A Python framework that turns an ASGI web app into a desktop application, serving it from a local Granian server and displaying it in a native OS window via pywebview
Search