doc: generate the ## Declarations sections of the standard library pages #32

Closed
opened 2026-10-05 21:07:12 +00:00 by orion · 5 comments
Collaborator

Goal

The ## Declarations section of every docs/standard-library/<package>.md page is written by hand next to the hand-written prose, so a signature on a page can drift from std/ (the Uri page, for one, shows Uri where the source says Self and omits compare). Generate the signature blocks from the model of torb doc and keep them in sync with a check. The prose between the blocks stays hand-written.

Design point

  • docs/contributing/research.md, principle 4 "Nothing is written twice by hand": the standard-library declarations "will be generated by milestone 8's torb doc".
  • docs/ROADMAP.md, the torb doc paragraph (the point linked in "Source" below; it is a milestone 8 item).
  • docs/tooling/torb-doc.md: the model (compiler/src/reference/model.trb, DocumentedItem) already carries, per public construct, the kind, the name, the signature as the source's own text, and its members. No new model field is needed.

Design (decided by the loop, see the comment below)

  • New subcommand torb docs declarations [root] [--standard-library <path>] [--check], next to docs index and docs skill. It reads the documentation tree, builds the model of the package a page names (title: std/<name>, kind: package) with the existing referenceOf walk, and rewrites the generated blocks. Without --check it writes; with --check it writes nothing and reports every page whose blocks differ (the gate form, like docs index --check).
  • Markers: a line <!-- torb:declaration: <Name> --> directly above a trb fragment fence marks that fence as generated. The generator replaces the fence with: the construct's signature (the model's text, without public), its non-private members one per line, indented, and the headers of the extend blocks of the package that target it. Everything outside the marked fences is untouched byte for byte, and a marker whose name is not a public construct of the page's package is a problem naming the page and the line.
  • One marker per construct (so Authority and Host under one ### heading get two markers). The ### heading and the prose below stay as they are.
  • All pages with a ## Declarations section are migrated: <!-- torb:declaration: --> markers added by the migration, blocks regenerated, skills/ regenerated.

Acceptance criteria

  • torb docs declarations docs rewrites the marked blocks from the model; torb docs declarations docs --check exits non-zero and names the page and the construct when a block differs, a marker names nothing, or the package does not check; it writes nothing.
  • Unit tests in compiler/tests/documentation.test.trb (or a new documentation-declarations.test.trb): a block is regenerated byte for byte, text outside the markers is untouched, an unknown name is a problem, a stale block is reported by --check, two markers under one heading both work.
  • Every docs/standard-library/<package>.md page with a ## Declarations section has a marker above each of its signature fences, and torb docs declarations docs --check is clean on main after the PR.
  • sh tools/gates.sh a runs docs declarations --check as a gate (tools/gates.sh, beside docs index --check), and its time is reported; if it adds more than 40 s to tier A, it shares the std check with the existing doc --check --no-run std gate instead of running a second one.
  • The sentences that say the section is written by hand are updated: docs/standard-library/index.md ("What belongs here"), docs/contributing/checks.md ("The declarations of a package page"), docs/contributing/adding-a-page.md (std package template), docs/tooling/torb-doc.md ("Related"), and the usage listing in docs/contributing/checks.md Synopsis and compiler/src/documentation/command.trb.
  • torb docs skill docs skills output regenerated and committed (--check clean).
  • torb docs check docs stays clean (the generated fences are trb fragment, which only lex).

Seed

No seed impact: a new torb docs subcommand, no syntax, no new native, no flag the bootstrap uses, no std name the compiler looks up by string. The gate runs with the freshly bootstrapped torb, never the seed. Compiler change in compiler/src/documentation/, so the implementer is opus/high per the loop contract.

Size and dependencies

One PR, two Conventional Commits:

  1. feat(docs): torb docs declarations generates the signature blocks of std pages (command, tests, gate, the sentences about the command in docs, skills regenerated). With no markers in the pages yet, the new check is trivially clean.
  2. docs(std): generate the declarations of the standard library pages (markers on every page, blocks regenerated, skills/ regenerated).

Depends on nothing open: torb doc and its model are built, and the work is independent of the VM/IR and of tools/registry. If the implementer finds that the model needs a new field or that commit 2 does not fit one reviewable diff, split it into linked issues instead of growing the PR.

Source

Moved from the planning lists of the docs; the design record stays the specification.

## Goal The `## Declarations` section of every `docs/standard-library/<package>.md` page is written by hand next to the hand-written prose, so a signature on a page can drift from `std/` (the `Uri` page, for one, shows `Uri` where the source says `Self` and omits `compare`). Generate the signature blocks from the model of `torb doc` and keep them in sync with a check. The prose between the blocks stays hand-written. ## Design point - `docs/contributing/research.md`, principle 4 "Nothing is written twice by hand": the standard-library declarations "will be generated by milestone 8's `torb doc`". - `docs/ROADMAP.md`, the `torb doc` paragraph (the point linked in "Source" below; it is a milestone 8 item). - `docs/tooling/torb-doc.md`: the model (`compiler/src/reference/model.trb`, `DocumentedItem`) already carries, per public construct, the kind, the name, the signature as the source's own text, and its members. No new model field is needed. ## Design (decided by the loop, see the comment below) - New subcommand `torb docs declarations [root] [--standard-library <path>] [--check]`, next to `docs index` and `docs skill`. It reads the documentation tree, builds the model of the package a page names (`title: std/<name>`, `kind: package`) with the existing `referenceOf` walk, and rewrites the generated blocks. Without `--check` it writes; with `--check` it writes nothing and reports every page whose blocks differ (the gate form, like `docs index --check`). - Markers: a line `<!-- torb:declaration: <Name> -->` directly above a `trb fragment` fence marks that fence as generated. The generator replaces the fence with: the construct's signature (the model's text, without `public`), its non-private members one per line, indented, and the headers of the `extend` blocks of the package that target it. Everything outside the marked fences is untouched byte for byte, and a marker whose name is not a public construct of the page's package is a problem naming the page and the line. - One marker per construct (so `Authority` and `Host` under one `###` heading get two markers). The `### ` heading and the prose below stay as they are. - All pages with a `## Declarations` section are migrated: `<!-- torb:declaration: -->` markers added by the migration, blocks regenerated, `skills/` regenerated. ## Acceptance criteria - [ ] `torb docs declarations docs` rewrites the marked blocks from the model; `torb docs declarations docs --check` exits non-zero and names the page and the construct when a block differs, a marker names nothing, or the package does not check; it writes nothing. - [ ] Unit tests in `compiler/tests/documentation.test.trb` (or a new `documentation-declarations.test.trb`): a block is regenerated byte for byte, text outside the markers is untouched, an unknown name is a problem, a stale block is reported by `--check`, two markers under one heading both work. - [ ] Every `docs/standard-library/<package>.md` page with a `## Declarations` section has a marker above each of its signature fences, and `torb docs declarations docs --check` is clean on `main` after the PR. - [ ] `sh tools/gates.sh a` runs `docs declarations --check` as a gate (`tools/gates.sh`, beside `docs index --check`), and its time is reported; if it adds more than 40 s to tier A, it shares the std check with the existing `doc --check --no-run std` gate instead of running a second one. - [ ] The sentences that say the section is written by hand are updated: `docs/standard-library/index.md` ("What belongs here"), `docs/contributing/checks.md` ("The declarations of a package page"), `docs/contributing/adding-a-page.md` (std package template), `docs/tooling/torb-doc.md` ("Related"), and the usage listing in `docs/contributing/checks.md` Synopsis and `compiler/src/documentation/command.trb`. - [ ] `torb docs skill docs skills` output regenerated and committed (`--check` clean). - [ ] `torb docs check docs` stays clean (the generated fences are `trb fragment`, which only lex). ## Seed No seed impact: a new `torb docs` subcommand, no syntax, no new native, no flag the bootstrap uses, no std name the compiler looks up by string. The gate runs with the freshly bootstrapped `torb`, never the seed. Compiler change in `compiler/src/documentation/`, so the implementer is opus/high per the loop contract. ## Size and dependencies One PR, two Conventional Commits: 1. `feat(docs): torb docs declarations generates the signature blocks of std pages` (command, tests, gate, the sentences about the command in docs, skills regenerated). With no markers in the pages yet, the new check is trivially clean. 2. `docs(std): generate the declarations of the standard library pages` (markers on every page, blocks regenerated, `skills/` regenerated). Depends on nothing open: `torb doc` and its model are built, and the work is independent of the VM/IR and of `tools/registry`. If the implementer finds that the model needs a new field or that commit 2 does not fit one reviewable diff, split it into linked issues instead of growing the PR. ## Source - [ROADMAP.md, `torb doc`](https://git.torb.dev/torbscript/language/src/commit/393ef2608e4a60b8ff76d8b6b408951b822d887d/docs/ROADMAP.md#L105) _Moved from the planning lists of the docs; the design record stays the specification._
Author
Collaborator

[loop:torbscript] intake: in scope (author orion, label loop). Generates the ## Declarations sections of docs/standard-library/ from the torb doc model with a sync check; tooling and docs, regenerates skills/, no seed impact expected. Related to the docs issue on public constructs (#31). Release freeze for 0.1.0 (2026-10-06) holds new PRs, next: refine (queued)

[loop:torbscript] intake: in scope (author orion, label loop). Generates the `## Declarations` sections of `docs/standard-library/` from the `torb doc` model with a sync check; tooling and docs, regenerates `skills/`, no seed impact expected. Related to the docs issue on public constructs (#31). Release freeze for 0.1.0 (2026-10-06) holds new PRs, next: refine (queued)
Author
Collaborator

[loop:torbscript] decided by the loop: command shape, markers, scope of the generated block

  • Command, not torb doc flag. The pages live in the documentation tree and the other generated parts (docs index, docs skill) are torb docs subcommands with a --check gate form, and docs check already takes --standard-library. A new torb docs declarations follows that convention instead of teaching torb doc about docs/.
  • Markers per construct, prose untouched. The pages interleave hand-written prose with the signature fences, and some ### headings hold two constructs (Authority, Host). Replacing only the marked fence keeps every explanation and needs no page restructuring; a whole-section generator would have deleted the prose.
  • Full public surface, as the model states it. The model shows a construct with all its non-private members and the source's own signature text (so Self, no public). The hand-written blocks were curated and had drifted (omitted compare, wrote Uri for Self); one rule that the source decides is what removes the drift. Longer blocks for the largest types (e.g. Option) are the accepted cost; the prose stays the place that explains.
  • Package resolved from title: std/<name> of kind: package pages. No new front-matter field; function-types.md and prelude.md get markers only where a name resolves to a public construct of their package, otherwise they keep a plain fence.
  • Gate cost measured in forge CI, not guessed. The check needs the checked std/ (about half a minute, same as doc --check --no-run std). The criterion fixes the threshold (40 s on tier A) and the fallback (share the check) so the implementer decides with numbers.
  • Not an owner question: internal docs tooling, no public statement, no cost, no published contract changes (the generated blocks are documentation text, torb doc's JSON format is untouched).
  • Not dependent on open VM/IR or tools/registry work (checked against the open issue list: the torb doc issues #234, #235, #236 touch the renderer and the registry worker, not the model or docs).
[loop:torbscript] decided by the loop: command shape, markers, scope of the generated block - **Command, not `torb doc` flag.** The pages live in the documentation tree and the other generated parts (`docs index`, `docs skill`) are `torb docs` subcommands with a `--check` gate form, and `docs check` already takes `--standard-library`. A new `torb docs declarations` follows that convention instead of teaching `torb doc` about `docs/`. - **Markers per construct, prose untouched.** The pages interleave hand-written prose with the signature fences, and some `###` headings hold two constructs (`Authority`, `Host`). Replacing only the marked fence keeps every explanation and needs no page restructuring; a whole-section generator would have deleted the prose. - **Full public surface, as the model states it.** The model shows a construct with all its non-private members and the source's own signature text (so `Self`, no `public`). The hand-written blocks were curated and had drifted (omitted `compare`, wrote `Uri` for `Self`); one rule that the source decides is what removes the drift. Longer blocks for the largest types (e.g. `Option`) are the accepted cost; the prose stays the place that explains. - **Package resolved from `title: std/<name>` of `kind: package` pages.** No new front-matter field; `function-types.md` and `prelude.md` get markers only where a name resolves to a public construct of their package, otherwise they keep a plain fence. - **Gate cost measured in forge CI, not guessed.** The check needs the checked `std/` (about half a minute, same as `doc --check --no-run std`). The criterion fixes the threshold (40 s on tier A) and the fallback (share the check) so the implementer decides with numbers. - **Not an owner question:** internal docs tooling, no public statement, no cost, no published contract changes (the generated blocks are documentation text, `torb doc`'s JSON `format` is untouched). - Not dependent on open VM/IR or `tools/registry` work (checked against the open issue list: the `torb doc` issues #234, #235, #236 touch the renderer and the registry worker, not the model or `docs`).
Author
Collaborator

[loop:torbscript] refine: requirements written (new torb docs declarations command with per-construct markers and a --check gate; two commits; no seed impact; no dependency on open VM/IR or registry work), next: implement

[loop:torbscript] refine: requirements written (new `torb docs declarations` command with per-construct markers and a `--check` gate; two commits; no seed impact; no dependency on open VM/IR or registry work), next: implement
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261009 until 2026-10-09T07:28Z

[loop:torbscript] claim implement by session:loop-torbscript-20261009 until 2026-10-09T07:28Z
Author
Collaborator

[loop:torbscript] implement: PR #243 open, CI success, worker usage ~450k tokens, next: waiting (review by the merge gate argus)

[loop:torbscript] implement: PR #243 open, CI success, worker usage ~450k tokens, next: waiting (review by the merge gate argus)
argus closed this issue 2026-10-09 02:44:45 +00:00
Sign in to join this conversation.
No labels
loop
ready
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
torbscript/language#32
No description provided.