Environments and versioning
Two contours
Section titled “Two contours”| Contour | Branch | Runs where | Purpose |
|---|---|---|---|
| prod | main | The production host, on the nightly schedule | Stable; every change arrives by deliberate promotion |
| dev | dev | A local development stack (Docker: Postgres, Redis, API, web) | Integration; all day-to-day work lands here first |
The flow is one-directional: feature branches merge into dev via small
pull requests; promotion to main is a separate, explicitly-approved step;
deployment to the production host is a separate script run after that. A
hotfix that must land on main directly is immediately forward-ported to
dev in the same session — main is always a subset of dev.
Where it runs
Section titled “Where it runs”Production is a single self-hosted Linux box behind a Caddy reverse proxy,
reachable through a dynamic-DNS name on a non-standard port
(entherium.duckdns.org:8443). That is the base URL in every example on
this portal, and it is the real one — there is no managed API gateway and
no vanity domain in front of it yet. The fleet of destination sites lives
on separate hosts. For a platform at this stage the box is production:
nightly runs, the API, the MCP server and the task board all answer from
it, and its uptime is watched by an external dead-man’s switch.
This documentation is served from two places with the same build: from the
API host under /developers/, and from a Cloudflare Pages mirror. The
mirror is the canonical copy — every page’s canonical and og:url
point there — and it stays up if the box does not. Both copies are rebuilt
from the same commit by the same deploy scripts; when they differ, the
mirror is the newer one.
Versioning — two independent axes
Section titled “Versioning — two independent axes”Axis A: platform modules. Each module (platform, webui, contracts,
services, this documentation site) is versioned independently by SemVer,
derived automatically from Conventional Commits by release tooling — versions
are never bumped by hand. An umbrella platform version tracks the whole.
Axis B: pipeline versions. Collect, Generate and Localize are versioned separately in the pipeline catalog, with immutable per-version code directories and per-contract pins. This axis moves at its own pace — a pipeline can advance several versions within one platform release, and vice versa. See Version lifecycle.
The two axes are deliberately decoupled: a platform deploy does not change which pipeline version the fleet runs, and promoting a pipeline version does not require a platform release.
What a “release” means here
Section titled “What a “release” means here”- Merged to
dev— integrated, gate-checked (lint, types, tests run locally as the merge gate), not yet user-visible. - Promoted to
main+ deployed — running on the production host. - Enabled — the platform’s hard rule: a feature is only called deployed when it is switched on and its effect is observable (a metric, a page, a number). Code behind a disabled flag is explicitly not “deployed” in reports or documentation.