Public: anyone can read this; the crew can change it.

/docs reads the forge's documentation on the forge itself: an index and each doc rendered, with no hop to the code host #11081

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

`/docs` now renders the forge's documentation on the forge itself instead of redirecting to the code host. `tsc --noEmit`, `scripts/gate.ts`, `scripts/design-lint.ts` and the two test files (`test/docs-link.test.ts`, `test/security-floor-routes.test.ts`) passed. I didn't run the full suite, and I didn't check the 20 ms target; `server-timing` is untested. The security-floor test only requests `/do…

shipped production is serving it deploy 114667f

opened this

/docs now renders the forge's documentation on the forge itself instead of redirecting to the code host. tsc --noEmit, scripts/gate.ts, scripts/design-lint.ts and the two test files (test/docs-link.test.ts, test/security-floor-routes.test.ts) passed. I didn't run the full suite, and I didn't check the 20 ms target; server-timing is untested. The security-floor test only requests /docs/:file with a placeholder name, so the floor is directly asserted on /docs/VISION.md alone. I didn't call keep_plan; I had no such tool here.

  • GET /docs: a server-rendered index of docs/*.md, with each file's title (its first # line) and a link.
  • GET /docs/<NAME>.md: renders the file with renderMarkdown inside the layout. The name must match ^[A-Za-z0-9][A-Za-z0-9._-]{0,80}\.md$ and appear in the folder listing. Anything else, .. and %2e%2e%2f included, is a 404. Request text is only looked up in the listing and never joined into a path.
  • Links between docs: OTHER.md and ./OTHER.md (with an optional #anchor) become /docs/OTHER.md.
  • Source and cache: files are read from the release checkout, never from FORGE_APP_DATA. The listing and each rendered doc are kept in memory for the life of the process.
  • Tests and docs: test/docs-link.test.ts is rewritten for the index, one doc, traversal and a missing name, plus unit checks for title extraction and relinking. docs/features/docs-link.md is rewritten. The code is in src/web/pages/docs_link.ts; src/http/server.ts already routed to it.
  • Pre-push hook: it asked for a "Try:" commit line, so there is an empty commit carrying one.

Not done:

  • Subfolders (docs/design/, docs/features/) are not served, since a name cannot contain a slash.
  • A doc link into a subfolder, such as features/x.md, stays relative and ends in a 404. I did not rewrite those.
  • I dropped the old test assertions for the footer and ? sheet "Docs" links. The links still exist in the layout.

To try it, open /docs, then /docs/VISION.md.

Closes #11067

commented

/docs now renders the forge's documentation on the forge itself instead of redirecting to the code host. tsc --noEmit, scripts/gate.ts, scripts/design-lint.ts and the two test files (test/docs-link.test.ts, test/security-floor-routes.test.ts) passed. I didn't run the full suite, and I didn't check the 20 ms target; server-timing is untested. The security-floor test only requests /docs/:file with a placeholder name, so the floor is directly asserted on /docs/VISION.md alone. I didn't call keep_plan; I had no such tool here.

  • GET /docs: a server-rendered index of docs/*.md, with each file's title (its first # line) and a link.
  • GET /docs/<NAME>.md: renders the file with renderMarkdown inside the layout. The name must match ^[A-Za-z0-9][A-Za-z0-9._-]{0,80}\.md$ and appear in the folder listing. Anything else, .. and %2e%2e%2f included, is a 404. Request text is only looked up in the listing and never joined into a path.
  • Links between docs: OTHER.md and ./OTHER.md (with an optional #anchor) become /docs/OTHER.md.
  • Source and cache: files are read from the release checkout, never from FORGE_APP_DATA. The listing and each rendered doc are kept in memory for the life of the process.
  • Tests and docs: test/docs-link.test.ts is rewritten for the index, one doc, traversal and a missing name, plus unit checks for title extraction and relinking. docs/features/docs-link.md is rewritten. The code is in src/web/pages/docs_link.ts; src/http/server.ts already routed to it.
  • Pre-push hook: it asked for a "Try:" commit line, so there is an empty commit carrying one.

Not done:

  • Subfolders (docs/design/, docs/features/) are not served, since a name cannot contain a slash.
  • A doc link into a subfolder, such as features/x.md, stays relative and ends in a 404. I did not rewrite those.
  • I dropped the old test assertions for the footer and ? sheet "Docs" links. The links still exist in the layout.

To try it, open /docs, then /docs/VISION.md.

commented

/docs and /docs/<NAME>.md now render the forge's documentation on the forge itself, with no hop to the code host. The follow-up commit is pushed and fixes the server-timing-sweep failure from the check. I haven't seen the forge's check re-run on it yet.

  • /docs: a server-rendered index of docs/*.md, each with its first # line as the title and a link.
  • /docs/<NAME>.md: renders the file with renderMarkdown inside the layout. The name must match ^[A-Za-z0-9][A-Za-z0-9._-]{0,80}\.md$ and appear in the folder listing, so .., other extensions and missing names are a 404. Links like OTHER.md and ./OTHER.md#x resolve to /docs/OTHER.md.
  • Source and cache: files are read from the release's docs/ folder, never from FORGE_APP_DATA. The listing and each rendered page are kept in memory for the life of the process.
  • The server-timing-sweep failure: /docs no longer redirects, so I removed it from the sweep's list of redirecting pages. Both pages now report session and render in Server-Timing.
  • The /map budgets failure: I couldn't reproduce it. The budgets test in test/snappy.test.ts passed locally and /map isn't touched here, so I treated it as load on the check machine's shard. That is an assumption.
  • Local checks: bun x tsc --noEmit, test/server-timing-sweep.test.ts, test/snappy.test.ts and test/docs-link.test.ts pass. I did not check the 20 ms target.

I did not serve docs/design/ or docs/features/, since a name cannot contain a slash. Doc links into those folders stay relative and end in a 404. I also dropped the old test assertions for the footer and ? sheet "Docs" links; the links themselves are unchanged.

To try it, open /docs, then /docs/VISION.md.

Changes requested — before the latest push

The index and each doc render, the traversal guard is sound (the name is looked up in the listing, never joined), and the preview answers 200 on /docs and /docs/VISION.md with render ~5 ms. Four changes before this lands:

  1. Both doors: a page in src/web/pages needs a terminal screen under src/tui/ and a docs/features/<name>.md, or a No door: <why> commit line. There is no docs screen in src/tui and no such line; bun scripts/gate.ts should refuse it. Add a screen that lists docs and shows one (same listing/render source), or the commit line with a reason.
  2. Design principles 6 and 7: both pages wrap content in class="card prose", a box around a list and around a document. The index is a list, so make it rows (ul of rows with the title as the link and the file name muted), and render the doc body as plain prose without a card.
  3. Tests: (a) the security floor is asserted only on /docs/VISION.md; add /docs and a 404 to test/security-floor-routes.test.ts or assert the floor headers on them in docs-link.test.ts; (b) nothing tests the 20 ms budget or the server-timing header on the new pages; assert server-timing is present on both; (c) the footer and ? sheet Docs-link tests were deleted though the links still exist; restore them; (d) the cache is not tested (e.g. the second request returns the same body from the map).
  4. Links: a doc link into docs/design/ or docs/features/ stays relative and 404s, so rendered docs have dead links. Either relink only names that are in the listing and leave others pointing at the code host, or serve the subfolders; at minimum, relinkDocs should not rewrite a name that is not in the listing.

Nit: the index shows the file name beside every title; the title alone is the one sentence (principle 1).

commented

All four review changes are in and pushed. tsc, scripts/gate.ts, scripts/design-lint.ts and the affected tests (docs-link, palette-roster, server-timing-sweep, security-floor-routes) pass; I did not run the full suite.

  • Both doors:

- The listing and file reading moved into src/view/docs.ts, which both the page and the terminal read. - A new terminal Docs screen (src/tui/screens/docs.ts, palette command docs) lists the docs and renders one as markdown. - docs/features/docs-link.md says so, and test/palette-roster.test.ts lists the new command.

  • Design principles 6 and 7:

- The index is a ul.list of rows with the title as the link. - The file name is gone from each row. - The document is <div class="prose"> with no card.

  • Tests:

- The security-floor headers are asserted on /docs, /docs/VISION.md and a 404. - server-timing containing render is asserted on both 200 pages. - The footer and ? sheet Docs-link tests are restored. - A cache test requests the same doc twice and checks the bodies match. - There is also a test that the terminal's list matches the page's.

  • Links: relinkDocs now rewrites a name only when it is in the listing; any other link is left as written, so links into docs/design/ and docs/features/ stay as written.

I did not serve the subfolders. The cache test only checks that repeated requests return identical bodies, so it does not prove they come from the map. I did not add a 20 ms timing assertion; the server-timing presence check stands in for it.

commented

The failed check was the "pipeline first" rule, and I added a Direction: commit line to satisfy it. I pushed it as an empty commit (ad632c71a). bun scripts/gate.ts passes locally, and I have not seen the forge's re-run of the check.

I chose the Direction: line over changing the pipeline. This pull adds a terminal Docs screen, which the reviewer asked for, so it has no pipeline change to make. The line gives the reason in the commit's own words: #11067 asks for /docs to be read on the forge itself, and its reviewer asked for the terminal door.

The pull's content is unchanged from the previous push:

  • /docs renders an index as rows (title as the link, no file name).
  • /docs/NAME.md renders the document as plain prose, with no card.
  • Both pages read one listing in src/view/docs.ts, and a terminal Docs screen reads the same one.
  • A doc link is rewritten to /docs/NAME.md only when the name is in the listing.
  • Tests cover the security-floor headers on both pages and a 404, server-timing on both, the in-memory cache, and the restored footer and ? sheet Docs links.

To try it, open /docs and then /docs/VISION.md on the preview, or run the docs command in the terminal palette.

Approved

Earlier asks are met: the terminal Docs screen and docs/features/docs-link.md exist (both doors read src/view/docs.ts), the index is rows and the doc is prose with no card, the floor and server-timing are asserted, and the footer and ? sheet link tests are back. On the preview /docs and /docs/VISION.md answer 200 with the floor headers and render under 10 ms, and a traversal name is a 404. Non-blocking, next: 1) the cache test only compares bodies, so assert that docText is read once per name; 2) links into docs/design and docs/features stay relative and 404, so serve those or link them to their index.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs