ADR 0114: mint local file URLs through harn files
Date: 2026-08-24 Status: Accepted
Context
Section titled “Context”ADR 0047 added an isolated host for standalone
HTML. The server already supports the useful URL:
http://harnery-files.localhost:<port>/<repo-path>. Agents still had to assemble
that URL themselves. They often used the dashboard’s /files?path=... overlay
instead, which wraps HTML in viewer chrome and is the wrong link when the
operator wants to use the document as a page.
The port is configurable through a flag, HARNERY_WEB_PORT, or project config.
Any instruction that shows a fixed port can drift from the running dashboard.
Alternatives considered
Section titled “Alternatives considered”- Keep URL construction in agent instructions. Rejected because instructions cannot resolve the live port or reliably encode path segments.
- Add
harn web url. Rejected because embedding hosts can replace Harnery’swebcommand. A portable subcommand would disappear in those hosts. - Send every file to the isolated files origin. Rejected because Markdown, code, PDFs, and media have better renderers in the dashboard viewer.
- Require the caller to choose a mode every time. Rejected because the common split is stable: HTML is a page, while other files use the viewer.
Decision
Section titled “Decision”Add harn files url <path>. It accepts a repo-relative path or an absolute path
inside the coord root, resolves the canonical file, and refuses missing files,
directories, and paths outside that root.
The default mode is extension-aware:
.htmland.htmprinthttp://harnery-files.localhost:<port>/<encoded-repo-path>.- Other extensions print
http://localhost:<port>/files?path=<encoded-repo-path>.
--raw and --viewer override the default. --port and --coord-root match
the dashboard’s web settings. Before printing, the command fetches
/api/coord-root from the selected dashboard and compares its opaque digest
with the canonical coord root. It refuses the URL if the dashboard cannot prove
that it serves the same repository. --no-verify lets callers construct a URL
without that check. The command prints only the URL to stdout, which keeps it
suitable for chat replies and shell composition.
The managed agent instruction block tells agents to call the command whenever they hand an operator a local file link. It also says that localhost links are only useful when the operator shares the machine.
Result
Section titled “Result”The CLI, documentation, and agent instructions now share one URL contract. The
web client’s server-side fallback also uses the canonical default port 4276
instead of the retired 9000 value.
On 2026-08-30, two links minted from one host repository opened against a dashboard rooted in another checkout. Both the viewer and isolated files origin reported that valid top-level paths were ambiguous. The URL command had proved the file existed under its own coord root but had not checked the process on the configured port. It now compares repository identities before printing and does not send an absolute path over HTTP. A failed check leaves stdout empty.