Standalone deployment (Stage 1)
Redline proves itself on its own before any consuming site adopts it, the way
the Markdown Renderer runs its own dashboard and knowledge base at
lcy.fio.sh before YYZ adoption counts as done. This page is the design the
B6 tasks implement.
Why standalone first
Every capability is proven in CI against the mock GitLab and the fixture site.
Nothing yet proves it against real GitLab, real OAuth and the tailnet. YYZ is
the wrong first host: its pages no longer come from its own git checkout. The
root content arrives from the kb-yyz-site-root kb-package at build, and
child pages are fragments rendered at publish by the harvester. Neither carries
build-time history or block ids today (tech debt TD-002 to TD-004 in
kb/lifecycle/tech-debt.md). A standalone host removes those variables: the
content is this repository’s own kb/, in this repository’s own git.
Stages
| Stage | Host | Proves | Gate |
|---|---|---|---|
| 1 | Redline’s own dashboard at yqa.fio.sh, QA at qa-yqa.fio.sh | the three capabilities against real GitLab, OAuth and the tailnet | this plan’s G |
| 2 | YYZ (B5, deferred) | adoption by readers of an evolving knowledge base | B5 plus the thirty-day report |
The kill criterion (scripts/experiment-report.js) measures Stage 2. A
standalone dashboard has too few readers for usage numbers to mean anything.
One deployable: dashboard and API on one origin
The service container serves both the dashboard and the /v1 API, as the
renderer’s single Worker serves its dashboard and HTTP API.
Reader on the tailnet
├─ https://yqa.fio.sh/ dashboard (static) + /v1 API, one origin
└─ https://qa-yqa.fio.sh/ the same image at the verified channel
host nginx → fio-redline:8787 / fio-redline-qa:8787 (Docker)
both → http://glab.fio.sh-server (Docker bridge)
└─ https://glab.fio.sh GitLab, for the OAuth authorize step only
Consequences:
- No CORS and no cross-site cookie for the dashboard: its requests are
same-origin. The CORS and
SameSiterules in network.md still govern other consumers (YYZ in Stage 2). - The dashboard is built once per environment-independent artifact and must not
embed a host name. Components accept a relative
serviceUrl(/) that the browser resolves againstlocation.origin(T6.1). SITES_JSON.fio-redline.allowedOriginslists the environment’s own origin, because browsers sendOriginon same-originPOST.
The dashboard
An Astro site under site/, built from this repository’s kb/:
| Route | Holds |
|---|---|
/ | overview: what Redline is, build identity (CalVer, commit), live service and GitLab state from the store |
/kb/<path>/ | every page under kb/, rendered with block ids, carrying GitRedline and GitChangedSince above the content, GitComments beside it, GitTrackChanges and GitHistoryFooter below |
Markdown renders through unified() with gitHistory({ blocks: true, contentRoots: ['kb'] }).
The document path of a page is its repository path (kb/…/*.md) and the site
id is fio-redline, registered against fridai/fio-dep/fio-redline.
Redline’s own documentation is thereby reviewed with Redline.
The build reads three inputs so tests can point it at the fixture repository:
REDLINE_DOCS_DIR (default kb), REDLINE_SITE_ID (default fio-redline)
and REDLINE_DOCUMENT_PREFIX (default: none, so the document path is the
file’s repository path).
Artifact and environments
Build once, promote the artifact, never rebuild (renderer ADR-0015):
- A CI job
sitebuilds the dashboard with full history (GIT_DEPTH: 0) and keepssite/distas a job artifact. - The existing container job takes that artifact into its build context; the
Dockerfile copies it to
/app/site. The image is the single artifact. - The existing channels carry it:
verifiedautomatically onmain,releasedby a human.
| Environment | Hostname | Tracks | Deployed |
|---|---|---|---|
| QA | https://qa-yqa.fio.sh | :verified | automatically by pull_policy: always on the next up |
| Production | https://yqa.fio.sh | :released | after the manual promotion |
| Development | http://localhost:8787 | working tree | npm run dev:dashboard |
QA stays up after production promotes the same version (renderer ADR-0020): it is the environment where the next release is checked.
Each environment has its own service.env, its own session secret and the
OAuth application’s redirect URI for its host. A GitLab OAuth application
accepts several redirect URIs, one per line, so one application can serve both.
Evidence
Per environment: npm run smoke output from a tailnet device and from off the
tailnet, npm run test:live output against the hostname, the image tag, the
date. For Stage 1 completion: one real merge request on fio-redline touching
kb/, shown inline on QA, and one comment made on QA visible in GitLab under
the commenter’s account. See T6.7.