Why /api is relative
The platform contract — one artifact, every environment
What this file is. The behavior contract for the platform half of the
environment story: one build artifact, a relative /api, per-box stores, and the
vendoring rule. Its sibling is deploy/functional_requirements_environments.md,
which owns the serving half — which server_name answers which name, from which
docroot, behind which cert lineage.
Every requirement is a check that can pass or fail. The map is
docs/architecture_platform.md.
1 · One artifact, every environment
- The frontend calls
/api, relatively. No page carries an absolute API origin, aPUBLIC_API_URL, or any other build-time environment constant. Check:grep -rn 'PUBLIC_API\|https://onefrontier.ai/api' web/srcreturns nothing. - nginx resolves the environment from the
Hostheader. The sameweb/distbuild serves the apex, the stage box, and every dev box; only the request's hostname differs. Check: the sameweb/distserved under two differentserver_names returns byte-identical HTML, and each HTML body's API calls are relative. - A page's API address is its own origin. A page fetched from
<box>.onefrontier.aireaches<box>.onefrontier.ai/api, which proxies to that box's api container. Check:curl -sk --resolve <box>.onefrontier.ai:443:10.10.0.124 https://<box>.onefrontier.ai/api/healthanswers from that box.
2 · Per-box stores
- No shared database. The api's
ONEF_DATABASE_URLpoints at127.0.0.1; the ClickHouse DSN points at127.0.0.1. Neither names a peer. Check:grep -rn '10\.10\.' docker/ deploy/up.sh | grep -i 'postgres\|clickhouse'returns no datastore address. - A dev box can be destroyed without consequence. Dropping and recreating
the postgres and clickhouse volumes on one box leaves every other box's data
intact, and
deploy/up.shre-seeds the dropped one. Check:docker volume rmon one box, thendeploy/up.sh, thencurl /api/healthisokand the schema is present.
3 · The vendoring rule
- No third-party request from any page. Fonts, stylesheets, scripts, icons,
images, and every runtime subresource live under
web/public/. Check:grep -rhoE 'src="https?://[^"]+' web/distreturns nothing. - The CSP is
default-src 'self'on every page, so a hotlink fails at the first load instead of leaking quietly. script-src 'none'sitewide, except the console page, which allows'self'andconnect-src 'self'for its live/api/healthpill. Check: every page's meta CSP isscript-src 'none'except/console/.- No inline
style=attribute anywhere — the CSP isstyle-src 'self', so an inline style is silently dropped and the layout degrades with no error. Check:grep -rn 'style=' web/srcreturns nothing. - Every vendored file is declared.
web/public/vendor/MANIFEST.mdnames each file's upstream URL and version. Check: every file underweb/public/vendor/appears in the manifest.
4 · The build
- The site is a static build with no runtime dependency.
npm run buildproducesweb/dist; no node process runs on a serving host. - The kit's documents are rendered from the repository at build, never
copied. An edit to
package/README.mdchanges the site on the next build. Check:web/src/data/docs.tsnames asourcepath for every doc, andweb/src/lib/kitdocs.tsreads it. - Every internal link resolves. Check:
python3 web/scripts/check-links.pyreportsbroken internal references: 0.
Acceptance
A change to the build or the platform passes when:
- One
web/distserves the apex and a dev box, and each page's API calls are relative. deploy/up.shon a clean box brings up postgres, clickhouse, and the api, and the site's title renders athttps://<box>.onefrontier.ai/.web/distcontains no absolute API origin, no inlinestyle=, and no third-partysrc=.- The console page's status pill reads
/api/healthfrom its own origin. - Every kit doc page renders the repository's own markdown.