feat: generators emit front-matter titles and regenerate reference docs - #27297
Conversation
|
/coder-agents-review |
|
Chat: Review posted | View chat Review historydeep-review v0.9.0 | Round 4 | Last posted: Round 4, 15 findings (3 P2, 5 P3, 2 Nit, 5 Note), APPROVE. Review Finding inventoryFinding inventory: PR #27297Findings
Contested and acknowledgedCRF-9 (Note, chat.md:1) - PR body's wipe rationale
CRF-10 (Note, manifest.json:1688) - CLI index dual manifest route
Round logRound 1Netero-only (2 P2 gate the panel). Reviewed against 9862f10..b421f74.
Round 2Churn guard PROCEED: CRF-1, CRF-2, CRF-3 all author-fixed in e399b7c. Panel (14 reviewers) Cross-check notes:
Round 3Churn guard PROCEED: 5 addressed (CRF-4,5,7,8,9), 1 contested (CRF-10), 1 deferred with ticket (CRF-6 -> DOCS-596), 0 silent. Cross-check (R3):
Round 4Churn guard PROCEED: CRF-12 addressed (8926709, Cross-check (R4):
About deep-reviewCRF = Coder Review Finding (P0-P4, Nit, Note)
|
There was a problem hiding this comment.
First-pass review only. These are mechanical findings from Netero; the full review panel has not yet reviewed this PR. The panel will review after these findings are addressed. These are defects worth resolving before the panel spends parallel review time.
The change is small and well-scoped: the generator sources are the only real diff (40 effective additions), the front-matter approach is clean, the extractSectionName rewrite keeps a sensible legacy # fallback, and the idempotency and chat.md-orphan reasoning check out (os.RemoveAll on reference/api/ does wipe and rewrite the directory each run, and no manifest or doc references to chat.md remain).
Severity count: 2 P2, 1 P3.
The two P2s are the same class and they contradict the PR body's central claim that "rendered output is unchanged." It holds for every section and command page (their front-matter title equals the manifest child title by construction), but not for the two index landing pages. The coder.com renderer precedence is frontmatter.title -> manifest route.title, and both renderers hide the body H1 and inject a single heading from the resolved title. So pre-PR these two pages took their rendered title (and Algolia lvl1) from the manifest, not from the removed H1. Post-PR the front-matter title wins and demotes them: REST API -> API and Command Line -> coder. That reaches production on merge, since docs markdown is fetched from mainline at request time.
The P3 is a latent gap, not a live break: the current output is correct, but the rewritten parser now derives every API page's filename, section title, and manifest route title with zero test coverage. As Netero put it, a future regression there produces "wrong-but-idempotent output, so the committed-golden make gen diff check in CI would not catch it."
Note that CI currently shows the title check failing; worth confirming that is unrelated (PR-title lint) before merge.
🤖 This review was automatically generated with Coder Agents.
b421f74 to
e399b7c
Compare
|
/coder-agents-review Round 1 findings (CRF-1, CRF-2, CRF-3) are all addressed in e399b7c and the threads are resolved:
The branch was also rebased onto current |
There was a problem hiding this comment.
Round 2. The three round-1 findings are all genuinely fixed, verified at the code by the panel, not just claimed: the API index emits title: REST API and the CLI index emits title: Command Line via the new atRoot branch (both matching their manifest routes), and extractSectionName now has a real table test that reaches 100% of the rewritten parser. swagger.json and manifest.json are byte-identical to main, so route topology and API annotations are untouched. Nice, tight diff with no scope creep.
One thing to fix before this is done, and two claims in the PR body to correct.
Severity count (new this round): 1 P2, 3 P3, 1 Nit, 2 Note.
The P2 is the one that matters: the migration missed a sibling. Three reviewers independently traced it. security.def (pulled into main.dot via {{#def.security}}) still emits a bare # Authentication, so authentication.md is the single generated API page with no front-matter title. It renders fine today because the manifest title matches and the legacy # fallback still parses it, but that means the fallback is load-bearing for a shipped page, and this PR's own goal ("once docs migrate to front-matter titles, make gen will no longer revert them") fails for exactly this page: any future title: added to authentication.md is overwritten on the next make gen. The fix is a two-line template change plus a regenerate.
Two PR-body claims are inaccurate (both harmless to the outcome, worth correcting):
- "a YAML front-matter
title:block at byte 0 of every generated file" is false whileauthentication.mdkeeps its H1 (see the P2). - The
chat.mddeletion rationale ("the postprocessor wipes and rewritesreference/api/each run") is false:make genruns the generator against a_gentmpdir and then moves files back per-file (Makefile:1361-1367), soos.RemoveAllhits the tmpdir, notdocs/. Stale files are not auto-removed; the explicit deletion in this PR is what removeschat.md. (I got this wrong myself in round 1; Mafuuu caught it.)
The P3s are a real-but-modest dead doc anchor, an unquoted-YAML-title foot-gun the migration introduces, and a parse error with no locator. Leorio on that last one: "That is a doctor saying 'one of your organs is failing' and walking out."
Process is honest: the PR discloses that make gen/make fmt was not run end-to-end and stays a draft until CI is green; markdownlint and the table formatter pass locally on the changed pages.
scripts/apidocgen/markdown-template/security.def:2
P2 [CRF-4] The Authentication section producer still emits a bare # Authentication, so authentication.md is the one generated API page this migration leaves behind. (Melody P2, Razor P2, Zoro P2)
two of three producers were rewritten,
security.defwas not ...authentication.mdalone keeps a legacy# Authentication. The blanket "every generated file" claim is therefore false.
Verified: security.def is included by main.dot:92 via {{? ...securitySchemes }}{{#def.security}}. swagger.json is OpenAPI 2.0 (securityDefinitions), which widdershins converts to components.securitySchemes, so the guard is true and the section is emitted every run. Empirically, authentication.md is the only docs/reference/api/*.md whose first line is not ---, and its content equals security.def.
Consequences: (1) rendered output is unchanged today (manifest title Authentication matches, both renderers hide the body H1), so nothing regresses now; (2) the extractSectionName legacy # fallback is load-bearing for this page, not defensive; (3) this defeats the PR's stated purpose for authentication.md specifically: a future front-matter title: added there is reverted on the next make gen. Fix: replace # Authentication with ---/title: Authentication/---, matching the two main.dot producers, then regenerate.
🤖
docs/support/support-bundle.md:73
P3 [CRF-5] Removing the page-title H1 from every generated CLI/API page deletes the page-slug heading anchor, and one live in-repo link now points at a fragment that no longer exists. (Hisoka P3, Pariston P3)
login.mdused to open with# login(anchor#login); it now opens with front matter and its first heading is## Usage, so#loginis gone ...docs/support/support-bundle.mdlinks to exactly that fragment.
Verified: grep '^#' docs/reference/cli/login.md no longer yields a login heading (first is ## Usage); support-bundle.md:73 links to ../reference/cli/login.md#login. This is a one-instance class in-repo (Hisoka checked all 68 fragment links into reference/cli|api; every other one targets a surviving ##/### heading). Consequence is modest (the dead #login targeted the top of the page, so the reader lands at the top anyway), but it is a broken fragment on the raw/GitHub surface, and pnpm check-docs does not validate cross-file fragments so CI stays green. Fix: repoint the link to a live section or drop the fragment.
🤖
docs/manifest.json:1688
Note [CRF-10] reference/cli/index.md is targeted by two manifest routes with different titles: the parent group route Command Line (line 1688) and a self-referential child coder (line 1704). (Pariston, Ryosuke)
Not re-raising CRF-2 (fixed). resolveDocTitle(attributes, routeTitle) takes a single already-selected routeTitle, so the renderer binds index.md to one of these routes before front matter is consulted. The CRF-2 fix (title: Command Line) is correct if the nav binds to the parent route; if it binds to the coder child, the pre-PR title was coder and the fix changes it to Command Line. Benign either way (Command Line is the better label), and the manifest is byte-identical to main so this PR did not introduce it. Worth a one-line confirmation from whoever owns the coder.com renderer.
🤖
🤖 This review was automatically generated with Coder Agents.
e399b7c to
6419a94
Compare
|
/coder-agents-review Round 2 addressed in 6419a94; all inline threads resolved.
Branch rebased onto current |
There was a problem hiding this comment.
Round 3, fix verification. Every round-2 finding is genuinely fixed at the root, verified by the panel and not just taken from the inventory:
- CRF-4 (P2): all three API section producers now emit front matter (
main.dotresource loop,main.dotSchemas, andsecurity.def),authentication.mdis migrated, and every file underdocs/reference/{api,cli}/now leads with---. The class is closed, not the instance. - CRF-5 (P3): the
support-bundle.mdlink dropped the dead#loginfragment, and the page-slug-anchor class was swept clean (no remaining<page>.md#<page>self-title links anywhere indocs/). - CRF-7 (P3) / CRF-8 (Nit): both errors name the failure mode and the legacy branch echoes the offending line; both prefix strips use
CutPrefix. - CRF-9 (Note): the PR body's
chat.mdrationale is corrected to the verified tmpdir/per-file-move behavior.
swagger.json and docs/manifest.json remain byte-identical to main, so there is no route or API-annotation drift.
CRF-10 (the dual cli/index.md manifest route) is closed as benign: five reviewers concurred that under front-matter precedence the page resolves to Command Line regardless of which route the nav binds, so the CRF-2 fix is robust to it. The only residual is the manifest-sourced sidebar label (coder), which is unchanged from main. One small consistency note: the PR body's universal claim "each page's front-matter title matches its manifest route" is not literally true for this one dual-route page, so consider qualifying it.
Severity count (new this round): 1 P3, 1 Note, 1 Nit.
The one P3 is the other half of CRF-7: the locator was added to the legacy branch, but the front-matter-with-no-title branch, which is now the primary path since every producer emits front matter, still names no section, and its two tests assert only the locator-less message. It is latent today (all producers emit a titled block), so it does not block, but it is exactly the diagnosability CRF-7 set out to provide, on the branch that matters most.
Nit (not inline, no diff line): the commit subject fix(docs): address round-2 review states the ritual, not the change. Leorio: "a reader bisecting to 'why does security.def emit front matter?' lands here and learns only that a review happened." Near-zero impact if this is squash-merged under the (good) PR title.
This PR is essentially ready: the only open code item is the latent P3 above, plus the already-ticketed CRF-6 (DOCS-596).
🤖 This review was automatically generated with Coder Agents.
6419a94 to
8926709
Compare
|
/coder-agents-review Round 3 addressed in
Also addressed the round-3 nits: consolidated the branch to a single descriptive commit (was a ritual All threads from rounds 1-3 are resolved. CI is green on the changed paths: |
There was a problem hiding this comment.
Round 4. CRF-12 is genuinely fixed and the PR has converged. The front-matter-no-title parse error now appends a compact section preview via the new sectionPreview helper, so the now-primary parse branch is locatable in make gen output (not just the legacy # path), and the error-path tests assert the section content actually reaches the message rather than just asserting an error occurred. extractSectionName is 100% covered. The commit is squashed under a descriptive subject (CRF-13), and the PR body now qualifies the dual-route cli/index.md claim.
Everything substantive across four rounds is resolved: CRF-1..CRF-9 and CRF-12 fixed, CRF-10 closed benign, CRF-11 accepted (defensive fallback kept), CRF-13 fixed, CRF-6 deferred with a real ticket (DOCS-596). swagger.json and docs/manifest.json remain byte-identical to main, so there is no route or API-annotation drift.
Approving. The three items below are all non-blocking (2 Notes + 1 Nit) and do not need to hold the merge.
Severity count (new this round): 1 Nit, 2 Note.
One process note on severity: a reviewer rated the comment-verbosity items P2; I downgraded them to a single Nit. Comment narration where the code works is a style/convention issue with no runtime or correctness consequence, and the same reviewer's own note conceded it is "not per-line severity." Bisky on the test suite: "not one of them is the same outfit on the same body."
One thing to confirm before merge that is outside this PR's diff: CI. The PR is a draft pending the gen/fmt check; the front-matter output is idempotent and lint-clean locally, but let the make gen/make fmt CI check go green before merging.
🤖 This review was automatically generated with Coder Agents.
8926709 to
c9911c0
Compare
The CLI and API doc generators emitted a bare "# H1" as the first line of
each generated page. The docs site derives page titles from YAML front
matter, so every `make gen` reverted the front-matter migration on generated
reference pages.
Emit a front-matter `title:` block at byte 0 from all three producers and
drop the bare H1:
- scripts/clidocgen/command.tpl: the root command emits `title: Command Line`
(via an `atRoot` helper); subcommands use the full command path.
- scripts/apidocgen/markdown-template/main.dot: resource sections and Schemas
emit front matter.
- scripts/apidocgen/markdown-template/security.def: Authentication emits
front matter.
- scripts/apidocgen/postprocess/main.go: the API index emits `title: REST
API`; extractSectionName parses the front-matter `title:` key, keeps a
defensive legacy `# ` heading fallback, and returns differentiated,
locatable errors. The missing-title error now includes a compact preview
of the offending section so a malformed block is identifiable from the
`make gen` output.
Regenerate docs/reference/{cli,api}, remove the stale
docs/reference/api/chat.md orphan left by the Chat -> Chats rename, and fix a
dead login fragment link in docs/support/support-bundle.md.
> This PR was created with AI assistance (Coder Agents).
c9911c0 to
f43d029
Compare
extractSectionName now checks scanner.Err() when the first Scan fails, so a section whose first line exceeds bufio.Scanner's token limit reports a scanning error instead of a misleading missing-header error. Switch the heading check to strings.CutPrefix and add a test covering the scanner-error path. Ports the format-agnostic generator hardening from #27297 (CRF-8, CRF-15). The front-matter-parsing branch and sectionPreview helper there are specific to that PR's template-level front-matter emission and do not apply here, where the widdershins templates still emit the "# {name}" heading that the postprocessor reads and swaps. Linear: DOCS-483 > This PR was created with AI assistance (Coder Agents).
|
Superseded by #27246, which we've selected as the prevailing Phase 2 PR. Closing without merging. Why #27246 prevails: it is a superset of this PR. It emits the full per-page metadata set ( Hardening ported from this PR into #27246 in 4959dde0de:
Intentionally not ported (specific to this PR's template-level front-matter emission, so they would be dead code under #27246's postprocessor-swap approach):
Tracking issue DOCS-553 is being marked Done (absorbed by #27246 / DOCS-483). |
Summary
Updates the CLI and API doc generators to emit a YAML front-matter
title:block at byte 0 of every generated file, and removes the bare# H1body heading. Once docs pages migrate to front-matter titles,make genwill no longer revert them. The Phase 1 renderer already preferstitle:from front matter. Each page's front-matter title matches its manifest route title, so rendered output is unchanged; the sole page with two manifest routes,cli/index.md, uses theCommand Linelanding-route title (see CRF-10).Linear: DOCS-553 · parent DOCS-483. Sibling of coder.com PR coder/coder.com#974 (independent — no coordinated merge needed).
Changes
CLI generator (
scripts/clidocgen/command.tpl)---/title:/---) placed at byte 0. The generated-content comment moves below it.# {{ fullName . }}heading removed.fullNamevalues are command paths (e.g.server,agent-firewall), so no quoting is needed.title: Command Linevia theatRootbranch, matching its manifest route.API templates (
scripts/apidocgen/markdown-template/)main.dot: per-resource{{= data.tags.section }}# {{= r}}and# Schemasbecome front matter; the inlinedata.tags.sectionprefix (which expands to an empty string) is removed so front matter leads the written file.security.def: the Authentication section producer emits front matter instead of a bare# Authentication, soauthentication.mdmigrates like the other generated API pages (round 2, CRF-4).API postprocessor (
scripts/apidocgen/postprocess/main.go)extractSectionNameparsestitle:from the front-matter block (skips leading blanks, strips optional YAML quotes) with a legacy#fallback. It returns the same values as before, so split filenames and manifest titles are unchanged. Covered by a unit test (main_test.go).strings.CutPrefix(round 2, CRF-8).apiIndexContent: leading# APIbecomes front matter withtitle: REST API, matching its manifest route.Regenerated output
docs/reference/cli/— front-matter titles, no leading H1.docs/reference/api/— section files +index.mdwith front-matter titles (includingauthentication.md).coderd/apidoc/swagger.jsonanddocs/manifest.jsonare byte-identical tomain— this change does not alter API annotations or manifest routes.docs/reference/api/chat.mdis deleted: a staleChat→Chatsswagger-tag-rename orphan.chats.mdis the live file; nothing referenceschat.md(manifest/links clean).make gendoes not auto-remove stale pages (the generator runs against a tmpdir and moves files back per-file), so the deletion is explicit here.Review follow-up
Round 1 (Netero) — 2 P2, 1 P3, all fixed
title: REST API/title: Command Line, matching their manifest routes.main_test.go, a table test forextractSectionName.Round 2 (panel) — 1 P2, 3 P3, 1 Nit
security.defmigrated (above);authentication.mdregenerated with front matter. Verified with widdershins + postprocess against the committed swagger.json: same file set,manifest.json/swagger.jsonunchanged.docs/support/support-bundle.mdno longer links to the removedlogin.md#loginanchor.CutPrefix(above), with tests asserting the messages.cli/index.mdhas two manifest routes (Command Lineparent,coderchild); pre-existing (manifest.json==main), no change here.Round 3 (panel) — 1 P3, 1 Note
; section starts: %q), so the now-primary front-matter path is locatable inmake genoutput, not just the legacy path. Tests assert the section content appears in the error.#fallback is unreachable duringmake gennow that all three producers emit front matter; kept as a low-cost defensive guard (still covered by theextractSectionNametests). No code change.Round 4 (panel) — approved; 1 Nit, 2 Note, all addressed
TestSectionPreviewexercising the >120-rune truncation branch;sectionPreviewandextractSectionNameare now at 100% statement coverage.extractSectionNamechecksscanner.Err()after the blank-skip loop and surfaces it asscanning section: ..., so a line pastbufio's token limit no longer masquerades as a missing header. Covered by aScannerErrorcase.extractSectionName/sectionPreviewthat narrated mechanism the code already shows (per AGENTS.md).Verification
go vetandgo test ./scripts/apidocgen/postprocess/...pass;extractSectionNameandsectionPrevieware at 100% statement coverage.docs/reference/cli/index.mdleads withtitle: Command Line; running the API generator confirmsauthentication.mdleads withtitle: Authentication..markdownlint.jsonc.Rebase / CI note
Rebased onto current
origin/mainand squashed to a single commit with a descriptive subject.swagger.jsonandmanifest.jsonare unchanged vsmain. If CI's gen/fmt check flags a formatting delta on the generated Markdown, I'll push a fixup. Kept as a draft until CI is green.