# 0056 — Every served URL is node-prefixed, local resources included

Status: accepted (2026-09-06 WEBSERVE grill round 1, releases#272 / #249)

## Context

WEBSERVE turns the loopback docs server into the node's general serving surface: registry
files, adapter docs, message views, and — across the subnet — the same resources of every
other node, proxied over Iroh by the local daemon. Two grammars were on the table: local
resources un-prefixed (`/cspt/file.md`) with a `/n/<node>/…` form only for remote ones, or
one grammar where every resource, local or not, lives under its owning node's name.

## Decision

**One URL grammar: `http://localhost:5474/<node-name>/…` for everything.** A resource on
HFENDULEAM is `/hfenduleam/…` on HFENDULEAM itself and on every other subnet machine; the
local daemon resolves the prefix and proxies when the owner is elsewhere. Bare
`http://localhost:5474/` redirects to `/<local-node>/`. The docs server's existing bare paths
stay reachable as a compatibility alias under the local node prefix.

**Grammar under the prefix (round 2, Q7):** one sub-namespace per facet, so a path says what
it is — `/<node>/f/<name>` registry files, `/<node>/docs/…` the docs site, `/<node>/a/<adapter>/…`
adapter docs, `/<node>/m/<short-id>` message views, `/<node>/bin/…` and `/<node>/install` the
bootstrap surface (LAN listener only, ADR-0059). `/<node>/` itself is an index page listing the
registry — the "what is this node exposing" audit in a browser. A facet added later needs a
prefix ruling; in exchange no two facets can ever collide on a name.

**Scheme (round 2, Q11):** plain `http://` only. Every consumer — a browser, `curl`, an agent's
fetch — already speaks it; `spt fetch` accepts the http URL and a local `<node>/f/<name>`
shorthand it expands itself.

## Alternatives rejected

- **An `spt://` scheme.** Would need a handler registered on every OS and a client on every
  consumer, to buy nothing the http URL does not already carry. Rejected.
- **Un-prefixed local, prefixed remote.** Shorter local URLs, but a URL's meaning then depends
  on which machine it is pasted into: `/cspt/file.md` is one file here and a different one
  there. Rejected: a URL that cannot be pasted between subnet machines is not a link, it is a
  path.

## Consequences

- Every SPT URL is portable by construction; agents and humans exchange them without a
  "which node" rider, which is what #147's message links and #17's FILE_ACCESS_HELPER need.
- Local URLs are longer, and a node rename moves every URL under it — renames are already
  rare and identity-bearing; this adds one more reason to treat them so.
- The node prefix is the only cross-node disambiguator; per-node name collisions are handled
  inside the registry (ADR-0057), never by the grammar.
