onefrontieronefrontier.ai

docs · platform

docs/architecture_platform.mdrendered from source at build

The platform map

onefrontier.ai — the platform map

|hadron|: ONEF-100 the environment is resolved from the Host header and never baked into a build: one artifact serves dev, stage, and prod, so a page's API address is always its own origin's /api and a browser cannot reach a neighbour's data store by config drift.

|hadron|: ONEF-101 every store is per-box and unreachable from a peer — no shared Postgres, no shared ClickHouse, in any environment. Concurrency is safe because the datastores cannot see each other, not because the code is careful.

|hadron|: ONEF-102 one performs no network call on the child's hot path: the journal append is the only synchronous work, and a full queue drops oldest-first while lifecycle rows are retained, so a slow collector degrades the record and never the launch.

onefrontier.ai is the product front (superneocloud). The foundation's pages are gone; everything under web/ is new. This file is the structural map: the planes, the names, the ports, and the contracts between them. Behavior contracts are the functional_requirements_* documents beside it.

The planes

plane holds lives
the site the static Astro build — product pages, docs, the console door web/, built to web/dist, served by nginx
the api accounts, API keys, sessions, tenancy api/, a Rust container, Postgres beside it
the events what one did: runs, phases, log lines ClickHouse, fed through the box's own hcapi
the binary one — a process wrapper that journals and never blocks one/
the chat the OpenAI-compatible /v1 plane: snapshot-corpus answers, streaming, web search chat/, a Rust cell

The names

One rule produces all of them: the leftmost label under onefrontier.ai is a box, and a label under that is a branch on that box.

hostname environment docroot /api
onefrontier.ai (apex) prod miramore's checkout of the build that box's api
www.onefrontier.ai prod alias 301 → apex —
stage.onefrontier.ai stage the designated stage box that box's api
<box>.onefrontier.ai dev that box's working tree that box's api
<branch>.<box>.onefrontier.ai dev, per worktree that box's worktree that box's api
onefrontier.org the placeholder (Cloudflare Pages, no box) a static page —
www.onefrontier.org placeholder alias 301 → https://onefrontier.org<path> —
onefrontier.net / .io (apex) alias of prod 301 → https://onefrontier.ai<path> —
www.<family> (.net, .io) alias of prod 301 → https://onefrontier.ai<path> (www means the apex) —
<label>.<family> (.net, .io) alias of that label 301 → https://<label>.onefrontier.ai<path> —
<label>.<family> or deeper alias of the same name on .ai 301 → https://<label>.<family→ai><path> — the whole subdomain is kept —

A box exists on the mesh the moment it carries an A record (<box>.onefrontier.ai → its wg0 address); the *.onefrontier.ai wildcard then covers every branch label under it. Adding a dev box is one DNS row and one vhost — never a registry edit.

The TLS caveat, measured. A wildcard certificate covers exactly one label: *.onefrontier.ai matches dev-vm-bl-4.onefrontier.ai but not feat.dev-vm-bl-4.onefrontier.ai. A two-label worktree name therefore needs the per-box lineage — live/<box>.onefrontier.ai, which carries *.<box>.onefrontier.ai — so the branch-preview blocks present that cert, not the apex wildcard. That is a per-box ssl_certificate line, issued once when the box is adopted, and it is the only thing a new box owes beyond its A record.

Without it the branch name still serves under -k and fails verification in a browser: the page loads, the padlock does not. A dev-only surface may accept that, but the choice is stated here rather than discovered later.

The .ai side of the map. This host (dev-vm-bl-4) answers at dev-vm-bl-4.onefrontier.ai at its own address 10.10.0.124, and *.<box>.onefrontier.ai on the host's live lineage certificate covers its branch lane. The zone also carries stage → this box and a * wildcard → the apex box, so an unregistered <label>.onefrontier.ai reaches the apex box at 10.10.0.7 rather than failing to resolve; a registered box therefore beats the wildcard with its own A record, and DNS order is the only thing that decides between them.

The alias rule

An alias maps to the same label on .ai. A family apex is the apex; www is the apex (it has always meant the bare name); every other first label is that label under onefrontier.ai, path and query preserved. The hop is a 301 and the label survives it, so stage.onefrontier.net/launch/ lands on stage.onefrontier.ai/launch/ — the stage, not the apex. Losing the label here would deliver every stage and preview visitor to production.

.net and .io obey the rule; .org does not, because it is the placeholder (deploy/functional_requirements_environments.md §7).

<label> is the one label directly under the family; a name deeper than that (a.b.<family>) keeps its whole name — a.b.onefrontier.net maps to a.b.onefrontier.ai — because the block captures the subdomain and swaps only the family suffix. A wildcard covers exactly one label.

Why the rule is expressible: the cert triple. Each family carries three names on one lineage — <family>, *.<family>, *.<box>.<family> — installed on this host and on miramore. The apex is covered by the first, one label by the second, the branch lane by the third, which is what makes a redirect written against the request label verifiable at all. Measured on this host, live/onefrontier.net lists onefrontier.net, *.onefrontier.net, and *.dev-vm-bl-4.onefrontier.net; .io lists the same triple for its own family.

The consequence. A two-label alias name (a.b.<family>) still needs a cert that covers it, and *.<family> does not. Such a name is redirected to the first label's .ai name, and the browser verifies the handshake only if the request name is one label deep; deeper names serve under -k.

This host is dev-vm-bl-4, at 10.10.0.124.

The environment rule

The frontend calls /api. Relative, always. No PUBLIC_API_URL, no .env.production, no build-time constant. nginx resolves the environment from the Host header, so:

  • a page served from <box>.onefrontier.ai calls <box>.onefrontier.ai/api
  • a page served from the apex calls the apex's /api

One build artifact serves every environment. The /api location proxies to that box's own api container on 127.0.0.1:8301; the api in turn talks only to its own Postgres on 127.0.0.1:5434 and its own ClickHouse on 127.0.0.1:8123.

The ports

service bind container
astro dev server 127.0.0.1:4321 host process (dev only)
api 0.0.0.0:8301 — reached at 127.0.0.1:8301 (the nginx door) and 10.10.0.124:8301 (the mesh) onefrontier-api
chat 127.0.0.1:8302 — the serving host's nginx /v1 door (pending in deploy/) one-chat
postgres 127.0.0.1:5434 onefrontier-postgres
clickhouse http 127.0.0.1:8123 onefrontier-clickhouse
clickhouse native 127.0.0.1:9000 same cell
hcapi (already running) 10.10.0.124:7144 host-control-api

The static build is served by nginx from web/dist; no node process runs on a serving host.

The vendoring rule

No third-party request from any page, ever. Fonts, stylesheets, scripts, icons, images, and every runtime subresource a dependency reaches for are downloaded, pinned, checksummed, and served same-origin under web/public/. Each vendored file carries its upstream URL and version in web/public/vendor/MANIFEST.md.

The CSP stays default-src 'self' on every page, so a hotlink fails loudly at the first load instead of quietly leaking a request. Vendoring the library is not enough: a bundled library that fetches tiles, sprites, or fonts at runtime must have those fetches vendored or disabled. Telemetry inside a dependency is removed by grep, not by vendoring.

The one binary

one sits in front of a command the owner already types:

one sglang serve --model-path Qwen/Qwen3-flash-8B --tp-size 2
one -t handoff sglang serve --model-path …
one python -c 'print(1)'
  • No quoting is required. The binary splits its own argv at the first token that is neither a one flag nor --, then re-execs the remainder verbatim. A shell function would have to re-quote and would break on -c 'print(1)'.
  • Completion passes through. The zsh completion shifts the cursor past one and its flags and calls _normal, so one sglang <TAB> completes as sglang <TAB>.
  • -t <tag> names the run for grouping; default is the command's basename.
  • --fgi files a gitea issue on a failed run through 14x-fgi, handing it the argv and the exit state.
  • ONE_API_URL overrides the collector; the default is http://127.0.0.1:7144, the box's own hcapi, so a client with no environment at all already uploads to itself. *_URL carries the scheme because the default is http and the override is https.

one subsumes handoff

handoff is not a second binary and never will be. It is one's launch mode: one -t handoff sglang serve …. Everything the handoff record designed — the Launchfile stating a tune, the keeper that survives a disconnect, the steering endpoint that composes one delta per attempt, the receipt that outlives the box — lands inside one, on the same journal and the same event vocabulary.

The reverse is not true: one wraps anything, and most runs are not launches. So handoff is a mode, not the parent.

The handoff repo is retired once its behaviour contract has been re-homed into functional_requirements_one.md; until then it is read as design, never as a running system.

The event path

one  --append(1 line)-->  $XDG_STATE_HOME/one/events.jsonl
     --flusher, batched-->  127.0.0.1:7144  (the box's own hcapi)
     --hcapi-->             ClickHouse on that box

one never performs a network call on the hot path. The journal append is O_APPEND, one line, no fsync except at exit. The flusher is a single task on a timer with a bounded queue: a slow collector drops the oldest non-lifecycle batches and keeps every lifecycle row.

The schemas

Postgres — accounts and tenancy

accounts      (id uuid pk, email citext unique, email_verified_at, display_name,
               status, created_at, updated_at)
credentials   (id uuid pk, account_id fk, kind, secret_hash, meta jsonb,
               created_at, last_used_at)
sessions      (id uuid pk, account_id fk, token_hash, ua, ip, created_at,
               expires_at, revoked_at)
api_keys      (id uuid pk, account_id fk, name, prefix, token_hash, scopes text[],
               created_at, last_used_at, revoked_at)

orgs          (id uuid pk, slug unique, name, created_at)
memberships   (org_id fk, account_id fk, role, created_at, pk(org_id, account_id))
projects      (id uuid pk, org_id fk, slug, name, created_at,
               unique(org_id, slug))
environments  (id uuid pk, project_id fk, name, kind, hostname,
               unique(project_id, name))

api_keys stores a prefix for lookup and a token_hash for verification; the raw key is shown once at creation. environments is what makes multi-dev real: a project has one prod, one stage, and N dev, each bound to a hostname.

ClickHouse — the events

events (project_id UUID, env LowCardinality(String), host LowCardinality(String),
        run_id UUID, parent_run_id Nullable(UUID),
        ts DateTime64(6), kind LowCardinality(String), name String, seq UInt32,
        attrs Map(String,String), tags Array(String))
  ENGINE = MergeTree PARTITION BY toYYYYMM(ts)
  ORDER BY (project_id, ts, run_id) TTL toDateTime(ts) + INTERVAL 180 DAY

runs   (project_id UUID, run_id UUID, host String, pid UInt32, tag String,
        argv Array(String), started_at DateTime64(6), ended_at Nullable(DateTime64(6)),
        exit_code Nullable(Int16), signal Nullable(String),
        outcome LowCardinality(String), attempts UInt16, uptime_ms UInt64,
        ver DateTime64(6) MATERIALIZED coalesce(ended_at, toDateTime64(0,6)))
  ENGINE = ReplacingMergeTree(ver) ORDER BY (project_id, run_id)

logs   (project_id UUID, run_id UUID, ts DateTime64(6),
        stream Enum8('stdout'=1,'stderr'=2), line String)
  ENGINE = MergeTree PARTITION BY toYYYYMM(ts)
  ORDER BY (project_id, run_id, ts) TTL ts + INTERVAL 30 DAY

Three tables, three questions: events is what happened, runs is what is happening now, logs is what it said.

kind is a closed set — lifecycle, phase, heartbeat, log, meta — and name carries the specific within it (start, exit, load, …). Adding a phase is a new name; changing kind is a schema change.

Each table sets non_replicated_deduplication_window = 1000, which is the idempotency mechanism for a re-posted batch, not a tuning knob.

The layout

onefrontier/
  web/          the Astro project — pages, components, one stylesheet
  api/          the Rust api crate: accounts, keys, sessions, tenancy
  one/          the one binary crate: argv split, journal, flusher, completion
  events/       the event schema and the ingest contract (its cell lives in docker/)
  docker/       compose cells for the platform
  package/      the open-source launch kit: snipe, qqt, catalog
  launchers/    the house launchers (vast, verda)
  docs/         this map and the behavior contracts
  deploy/       nginx vhosts, the redirect map, up.sh

What is deliberately absent

No shared database. No CDN. No build-time environment. No inbound port on a customer box. No scheduler and no placement engine — those are SNC's, not this platform's.