J74: docs pages built into the web root (/docs/<page> per instance) #298

Closed
opened 2026-11-01 18:49:15 +00:00 by kayg · 3 comments
Owner

Owner decision (2026-11-01): docs live in two places. infraternal.com/docs holds the official docs; <instance>/docs (e.g. https://ssh.kayg.org/docs) holds the docs for the version that instance runs. In-app "?" links open the instance's own /docs/<page>.

Job J74 scope: a build step renders the user-facing docs/*.md (start: docs/multiplexer.md + an index) into static HTML inside the web root; in-app links go relative; same output deployable as a static site later (not deployed here).

Owner decision (2026-11-01): docs live in two places. `infraternal.com/docs` holds the official docs; `<instance>/docs` (e.g. https://ssh.kayg.org/docs) holds the docs for the version that instance runs. In-app "?" links open the instance's own `/docs/<page>`. Job J74 scope: a build step renders the user-facing `docs/*.md` (start: `docs/multiplexer.md` + an index) into static HTML inside the web root; in-app links go relative; same output deployable as a static site later (not deployed here).
Author
Owner

Start. Branch docs-pages from origin/dev 65d9861914e8cd4a734d533d64ed1f4ea5c34119.

Findings (no surprises):

  • Bun.markdown.html is built into the pinned bun: no new dependency, 0 bytes added. apps/tracer/test/render-docs-preview.ts already uses it as a test stand-in; I replace that with a real build step.
  • The server (web_assets.rs) already does append_index_html_on_directories(true), so dist/docs/<page>/index.html is served at /docs/<page>/ (and /docs/<page> redirects to it) with the .br/.gz sidecars precompress writes. No server change.
  • transfer-budget.ts counts only .js; the docs are .html/.css in dist/docs/, so the app budget cannot grow. The link constant becomes shorter.

Plan (est. 1.5 h):

  1. apps/tracer/docs-build.ts: explicit page list (multiplexer only; docs/ has no other user-facing page), renders to dist/docs/index.html, dist/docs/<slug>/index.html, one shared docs.css + its own Geist Mono font file. Colours = the sign-in card's ink/paper tokens, following the system scheme; mobile-first, 44 px targets, safe areas. Absolute /docs/... URLs so the same tree works at infraternal.com/docs. bun run docs writes only that tree (docs-dist/) for the static site; build.ts calls the same function before precompress.
  2. MULTIPLEXER_DOCS_URL -> /docs/multiplexer/; drop the mock's docsUrl override and render-docs-preview.ts; mock-server serves index.html for directories (test double, 2 lines).
  3. Playwright: docs.spec.ts (page renders on the production build in ink/paper at 1440x900 DPR2 and 393x852 DPR3, left edges aligned, no horizontal overflow; the in-app ? opens it); startup-demo.spec.ts keeps working.
  4. Gate on dev-02 (verify fast), screenshots on this issue, push.
**Start.** Branch `docs-pages` from origin/dev `65d9861914e8cd4a734d533d64ed1f4ea5c34119`. **Findings (no surprises):** - `Bun.markdown.html` is built into the pinned bun: **no new dependency, 0 bytes added**. `apps/tracer/test/render-docs-preview.ts` already uses it as a test stand-in; I replace that with a real build step. - The server (`web_assets.rs`) already does `append_index_html_on_directories(true)`, so `dist/docs/<page>/index.html` is served at `/docs/<page>/` (and `/docs/<page>` redirects to it) with the `.br`/`.gz` sidecars `precompress` writes. **No server change.** - `transfer-budget.ts` counts only `.js`; the docs are `.html`/`.css` in `dist/docs/`, so the app budget cannot grow. The link constant becomes shorter. **Plan (est. 1.5 h):** 1. `apps/tracer/docs-build.ts`: explicit page list (multiplexer only; `docs/` has no other user-facing page), renders to `dist/docs/index.html`, `dist/docs/<slug>/index.html`, one shared `docs.css` + its own Geist Mono font file. Colours = the sign-in card's ink/paper tokens, following the system scheme; mobile-first, 44 px targets, safe areas. Absolute `/docs/...` URLs so the same tree works at `infraternal.com/docs`. `bun run docs` writes only that tree (`docs-dist/`) for the static site; `build.ts` calls the same function before `precompress`. 2. `MULTIPLEXER_DOCS_URL` -> `/docs/multiplexer/`; drop the mock's `docsUrl` override and `render-docs-preview.ts`; mock-server serves `index.html` for directories (test double, 2 lines). 3. Playwright: `docs.spec.ts` (page renders on the production build in ink/paper at 1440x900 DPR2 and 393x852 DPR3, left edges aligned, no horizontal overflow; the in-app `?` opens it); `startup-demo.spec.ts` keeps working. 4. Gate on dev-02 (`verify fast`), screenshots on this issue, push.
Author
Owner

Finish. Branch docs-pages, head b7f53cea921f6b20a5fffcfc6147e9e7dea9c481 (4 commits on origin/dev 65d986191).

What shipped:

  • apps/tracer/docs-build.ts + docs.css: renders docs/multiplexer.md plus an index to dist/docs/<slug>/index.html (Bun's built-in markdown renderer: no dependency, 0 bytes). Ink/paper follow the system scheme with the sign-in card's colours, the app's type scale and weights, safe areas, no script. build.ts calls it before precompress, so the pages get .br/.gz. bun run docs writes the same tree to docs-dist/ for a static host (every URL starts with /docs/). Not deployed.
  • No server change: web_assets.rs already serves docs/<slug>/index.html for the directory (/docs/multiplexer redirects to /docs/multiplexer/).
  • MULTIPLEXER_DOCS_URL is now /docs/multiplexer/ (same server). The test-only render-docs-preview.ts is gone; the test double serves directory indexes.
  • Tests: test/docs.spec.ts (4 cases: desktop 1440x900 DPR2 and phone 393x852 DPR3, ink and paper): index and page render, left edges of header/title/paragraph/heading/code/table within 0.5 px, no horizontal overflow, no script, no source comments, page colours, type scale 13/16 px, 44 px header target on phone, .br/.gz sidecars exist. startup-demo.spec.ts now also asserts the ? opens this server's /docs/multiplexer/.

Numbers (dev-02, same machine, origin/dev vs branch, transfer-budget.ts):

  • critical gzip 309631 -> 309615 B (-16), brotli 257967 -> 257970 (+3, noise from the changed string)
  • deferred gzip 60748 -> 60743 B (-5), identity 175557 -> 175535 (-22)
  • docs files (not part of the JS budget): index.html 707 B, multiplexer/index.html 7680 B (2399 B br), docs.css 3907 B (1259 B br), font 1 file copied from fonts/maple-mono-nf.

Test results:

  • docs.spec.ts: 4 passed (head b7f53cea9, run 6 on dev-02).
  • startup-demo.spec.ts: 6 passed on the branch (run 5). In two earlier runs under heavy load on dev-02 one or two of the 6 cases timed out waiting for the toast (30 s); unrelated to the docs change, not chased (scope leash). The same spec on unmodified origin/dev failed all 6 in that run (it needs a hand-rendered docs page and the toast never showed), so I did not use it as a baseline.
  • bun test src/canvas/sessions: 50 pass, 7 "errors", identical (7) on unmodified origin/dev.
  • The phone case applies the page's real (pointer: coarse) rule read from the served docs.css, because headless Chromium reports a fine pointer even with touch emulation.

Gate: scripts/verify fast on infraternal-dev-02-std at 6fc2200fd (the later commits only change test/docs.spec.ts), exit 0:

| Rust gate                 | Result       |
| fmt                       | PASS         |
| VT native fmt             | PASS         |
| CLI plugin compile-out    | PASS         |
| clippy                    | PASS         |
| SSH runtime test helper   | PASS         |
| real-binary fixture paths | PASS         |
| test                      | PASS         |
| SSH inode reuse fixture   | PASS         |
| shim process-per-user     | PASS         |
| cargo-deny                | PASS         |
| gate architecture         | PASS         |
| static builds             | PASS         |

followed by the tracer compiler, precompression and bundle transfer budget section (tsc + bun tests passed). No Rust code changed, so the static binary size is unchanged.

For the owner: D315 text in DECISIONS.md still says the docs are "published at infraternal.com/docs/multiplexer"; I did not edit it (owner only). It should now read "served at <instance>/docs/multiplexer/, and published at infraternal.com/docs/multiplexer".

**Finish.** Branch `docs-pages`, head `b7f53cea921f6b20a5fffcfc6147e9e7dea9c481` (4 commits on origin/dev 65d986191). What shipped: - `apps/tracer/docs-build.ts` + `docs.css`: renders `docs/multiplexer.md` plus an index to `dist/docs/<slug>/index.html` (Bun's built-in markdown renderer: **no dependency, 0 bytes**). Ink/paper follow the system scheme with the sign-in card's colours, the app's type scale and weights, safe areas, no script. `build.ts` calls it before `precompress`, so the pages get `.br`/`.gz`. `bun run docs` writes the same tree to `docs-dist/` for a static host (every URL starts with `/docs/`). Not deployed. - No server change: `web_assets.rs` already serves `docs/<slug>/index.html` for the directory (`/docs/multiplexer` redirects to `/docs/multiplexer/`). - `MULTIPLEXER_DOCS_URL` is now `/docs/multiplexer/` (same server). The test-only `render-docs-preview.ts` is gone; the test double serves directory indexes. - Tests: `test/docs.spec.ts` (4 cases: desktop 1440x900 DPR2 and phone 393x852 DPR3, ink and paper): index and page render, left edges of header/title/paragraph/heading/code/table within 0.5 px, no horizontal overflow, no script, no source comments, page colours, type scale 13/16 px, 44 px header target on phone, `.br`/`.gz` sidecars exist. `startup-demo.spec.ts` now also asserts the `?` opens this server's `/docs/multiplexer/`. Numbers (dev-02, same machine, origin/dev vs branch, `transfer-budget.ts`): - critical gzip 309631 -> 309615 B (-16), brotli 257967 -> 257970 (+3, noise from the changed string) - deferred gzip 60748 -> 60743 B (-5), identity 175557 -> 175535 (-22) - docs files (not part of the JS budget): index.html 707 B, multiplexer/index.html 7680 B (2399 B br), docs.css 3907 B (1259 B br), font 1 file copied from `fonts/maple-mono-nf`. Test results: - `docs.spec.ts`: 4 passed (head b7f53cea9, run 6 on dev-02). - `startup-demo.spec.ts`: 6 passed on the branch (run 5). In two earlier runs under heavy load on dev-02 one or two of the 6 cases timed out waiting for the toast (30 s); unrelated to the docs change, not chased (scope leash). The same spec on unmodified origin/dev failed all 6 in that run (it needs a hand-rendered docs page and the toast never showed), so I did not use it as a baseline. - `bun test src/canvas/sessions`: 50 pass, 7 "errors", identical (7) on unmodified origin/dev. - The phone case applies the page's real `(pointer: coarse)` rule read from the served docs.css, because headless Chromium reports a fine pointer even with touch emulation. Gate: `scripts/verify fast` on infraternal-dev-02-std at `6fc2200fd` (the later commits only change `test/docs.spec.ts`), exit 0: ``` | Rust gate | Result | | fmt | PASS | | VT native fmt | PASS | | CLI plugin compile-out | PASS | | clippy | PASS | | SSH runtime test helper | PASS | | real-binary fixture paths | PASS | | test | PASS | | SSH inode reuse fixture | PASS | | shim process-per-user | PASS | | cargo-deny | PASS | | gate architecture | PASS | | static builds | PASS | ``` followed by the tracer compiler, precompression and bundle transfer budget section (tsc + bun tests passed). No Rust code changed, so the static binary size is unchanged. For the owner: D315 text in DECISIONS.md still says the docs are "published at infraternal.com/docs/multiplexer"; I did not edit it (owner only). It should now read "served at `<instance>/docs/multiplexer/`, and published at infraternal.com/docs/multiplexer".
Author
Owner

Closed by the orchestrator during the 2026-11-09 night housekeeping (owner order: "close stale prs/issues"). The work has landed on dev, and the latest note here is a finish or merge note (J387 inventory on #436). Reopen if anything is still missing.

Closed by the orchestrator during the 2026-11-09 night housekeeping (owner order: "close stale prs/issues"). The work has landed on dev, and the latest note here is a finish or merge note (J387 inventory on #436). Reopen if anything is still missing.
kayg closed this issue 2026-11-08 19:04:24 +00:00
Sign in to join this conversation.
No labels
launch-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/infraternal#298
No description provided.