Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat: generators emit front-matter titles and regenerate reference docs - #27297

Closed
nickvigilante wants to merge 1 commit into
mainfrom
vigilante/docs-553-phase-2b-codercoder-generators-emit-front-matter-titles
Closed

feat: generators emit front-matter titles and regenerate reference docs#27297
nickvigilante wants to merge 1 commit into
mainfrom
vigilante/docs-553-phase-2b-codercoder-generators-emit-front-matter-titles

Conversation

@nickvigilante

@nickvigilante nickvigilante commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

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 # H1 body heading. Once docs pages migrate to front-matter titles, make gen will no longer revert them. The Phase 1 renderer already prefers title: 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 the Command Line landing-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)

  • Front-matter block (---/title:/---) placed at byte 0. The generated-content comment moves below it.
  • Bare # {{ fullName . }} heading removed. fullName values are command paths (e.g. server, agent-firewall), so no quoting is needed.
  • The root command (index page) emits title: Command Line via the atRoot branch, matching its manifest route.

API templates (scripts/apidocgen/markdown-template/)

  • main.dot: per-resource {{= data.tags.section }}# {{= r}} and # Schemas become front matter; the inline data.tags.section prefix (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, so authentication.md migrates like the other generated API pages (round 2, CRF-4).

API postprocessor (scripts/apidocgen/postprocess/main.go)

  • extractSectionName parses title: 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).
  • On failure it names the mode and locates the offending section: the legacy path echoes its first line (round 2, CRF-7) and the front-matter-no-title path appends a compact content preview (round 3, CRF-12). The legacy branch uses strings.CutPrefix (round 2, CRF-8).
  • apiIndexContent: leading # API becomes front matter with title: REST API, matching its manifest route.

Regenerated output

  • docs/reference/cli/ — front-matter titles, no leading H1.
  • docs/reference/api/ — section files + index.md with front-matter titles (including authentication.md).
  • coderd/apidoc/swagger.json and docs/manifest.json are byte-identical to main — this change does not alter API annotations or manifest routes.

docs/reference/api/chat.md is deleted: a stale ChatChats swagger-tag-rename orphan. chats.md is the live file; nothing references chat.md (manifest/links clean). make gen does 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

  • CRF-1/CRF-2 (P2): API and CLI index pages emit title: REST API / title: Command Line, matching their manifest routes.
  • CRF-3 (P3): added main_test.go, a table test for extractSectionName.

Round 2 (panel) — 1 P2, 3 P3, 1 Nit

  • CRF-4 (P2): security.def migrated (above); authentication.md regenerated with front matter. Verified with widdershins + postprocess against the committed swagger.json: same file set, manifest.json/swagger.json unchanged.
  • CRF-5 (P3): docs/support/support-bundle.md no longer links to the removed login.md#login anchor.
  • CRF-7 (P3) / CRF-8 (Nit): parse-error locator + CutPrefix (above), with tests asserting the messages.
  • CRF-6 (P3): unquoted YAML titles are a latent foot-gun; all current values are YAML-safe, so deferred to DOCS-596 for a proper both-generators + read-side fix rather than churning ~200 safe titles.
  • CRF-10 (Note): cli/index.md has two manifest routes (Command Line parent, coder child); pre-existing (manifest.json == main), no change here.

Round 3 (panel) — 1 P3, 1 Note

  • CRF-12 (P3): the front-matter-no-title parse error now appends a compact preview of the offending section (; section starts: %q), so the now-primary front-matter path is locatable in make gen output, not just the legacy path. Tests assert the section content appears in the error.
  • CRF-11 (Note): the legacy # fallback is unreachable during make gen now that all three producers emit front matter; kept as a low-cost defensive guard (still covered by the extractSectionName tests). No code change.

Round 4 (panel) — approved; 1 Nit, 2 Note, all addressed

  • CRF-14 (Note): added TestSectionPreview exercising the >120-rune truncation branch; sectionPreview and extractSectionName are now at 100% statement coverage.
  • CRF-15 (Note): extractSectionName checks scanner.Err() after the blank-skip loop and surfaces it as scanning section: ..., so a line past bufio's token limit no longer masquerades as a missing header. Covered by a ScannerError case.
  • CRF-16 (Nit): trimmed two comments in extractSectionName/sectionPreview that narrated mechanism the code already shows (per AGENTS.md).

Verification

  • go vet and go test ./scripts/apidocgen/postprocess/... pass; extractSectionName and sectionPreview are at 100% statement coverage.
  • Re-running clidocgen confirms docs/reference/cli/index.md leads with title: Command Line; running the API generator confirms authentication.md leads with title: Authentication.
  • MD041 (first-line-must-be-H1) confirmed disabled in .markdownlint.jsonc.

Rebase / CI note

Rebased onto current origin/main and squashed to a single commit with a descriptive subject. swagger.json and manifest.json are unchanged vs main. 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.


This PR was created with AI assistance (Coder Agents).

@linear-code

linear-code Bot commented Jul 16, 2026

Copy link
Copy Markdown

DOCS-553

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Docs preview

Check off each page once it's been reviewed. If a page changes in a later push, its checkbox clears automatically so it gets a fresh look. Pages not yet wired into the docs navigation aren't listed here.

@nickvigilante nickvigilante changed the title feat(docs): generators emit front-matter titles and regenerate reference docs feat: generators emit front-matter titles and regenerate reference docs Jul 16, 2026
@nickvigilante

Copy link
Copy Markdown
Contributor Author

/coder-agents-review

@coder-agents-review

coder-agents-review Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Chat: Review posted | View chat
Requested: 2026-07-22 19:32 UTC by @nickvigilante
Spend: $68.42 / $100.00

Review history
  • R1 (2026-07-20), 2 P2, 1 P3, COMMENT. Review
  • R2 (2026-07-21): 14 reviewers, 1 Nit, 2 Note, 3 P2, 4 P3, COMMENT. Review
  • R3 (2026-07-22): 12 reviewers, 1 Nit, 3 Note, 3 P2, 5 P3, COMMENT. Review
  • R4 (2026-07-22): 11 reviewers, 2 Nit, 5 Note, 3 P2, 5 P3, APPROVE. Review

deep-review v0.9.0 | Round 4 | 9236670..8926709

Last posted: Round 4, 15 findings (3 P2, 5 P3, 2 Nit, 5 Note), APPROVE. Review

Finding inventory

Finding inventory: PR #27297

Findings

# Sev Status Location Summary Round Reviewer Posted
CRF-1 P2 Author fixed (e399b7c) scripts/apidocgen/postprocess/main.go:25 API index front matter title: API diverges from manifest REST API; demotes rendered heading + Algolia lvl1 R1 Netero Yes
CRF-2 P2 Author fixed (e399b7c) scripts/clidocgen/command.tpl:2 CLI index front matter title: coder diverges from manifest Command Line; same demotion R1 Netero Yes
CRF-3 P3 Author fixed (e399b7c) scripts/apidocgen/postprocess/main.go:255 Rewritten extractSectionName front-matter parser has zero unit test coverage R1 Netero Yes
CRF-4 P2 Author fixed (6419a94) scripts/apidocgen/markdown-template/security.def:2 Authentication section still emits # Authentication; authentication.md un-migrated, legacy # fallback load-bearing R2 Melody P2, Razor P2, Zoro P2 Yes
CRF-5 P3 Author fixed (6419a94) docs/support/support-bundle.md:73 Removing page-title H1 orphans the login.md#login fragment link (raw/GitHub surface) R2 Hisoka P3, Pariston P3 Yes
CRF-6 P3 Deferred (DOCS-596) scripts/apidocgen/markdown-template/main.dot:99 Front-matter title emitted unquoted; a future YAML-special char silently diverges 3 consumers R2 Ryosuke P3 (Mafuuu/Chopper/Melody Note) Yes
CRF-7 P3 Author fixed (6419a94); residual as CRF-12 scripts/apidocgen/postprocess/main.go:289 Parse-failure error names neither the section nor the failure mode; caller adds no locator R2 Leorio P3, Chopper P3 Yes
CRF-8 Nit Author fixed (6419a94) scripts/apidocgen/postprocess/main.go:284 Two prefix-strip idioms (CutPrefix vs HasPrefix+[2:]) in one function R2 Gon, Ging-go Yes
CRF-9 Note Author fixed (6419a94, PR body corrected) docs/reference/api/chat.md:1 PR body's chat.md wipe rationale is false; make gen copies back per-file so stale files survive R2 Mafuuu Yes
CRF-10 Note Author contested; panel closed R3 (benign) docs/manifest.json:1688 reference/cli/index.md targeted by two manifest routes (parent Command Line, child coder) R2 Pariston, Ryosuke Yes
CRF-11 Note Author accepted R4 (defensive fallback kept; hard-fail tracked separately) scripts/apidocgen/postprocess/main.go:286 Legacy # fallback now unreachable during make gen (all producers emit front matter); purely defensive after CRF-4 fix R3 Netero Yes
CRF-12 P3 Author fixed (8926709) scripts/apidocgen/postprocess/main.go:282 Front-matter-no-title error names the mode but not the section; incomplete half of CRF-7 on the now-primary branch; test codifies the locator-less message R3 Bisky P3, Leorio P3, Chopper P3 Yes
CRF-13 Nit Author fixed (8926709, squashed with descriptive subject) 6419a94 (commit subject) Commit subject "address round-2 review" states the ritual, not the change R3 Leorio No
CRF-14 Note Open scripts/apidocgen/postprocess/main.go:299 sectionPreview >120-rune truncation branch untested (fn at 80% cov); cosmetic error-preview only R4 Netero Yes
CRF-15 Note Open scripts/apidocgen/postprocess/main.go:260 Blank-skip loop ignores scanner.Err(); a >64KB line would degrade to a misleading "header not found" R4 Chopper Yes
CRF-16 Nit Open scripts/apidocgen/postprocess/main.go:295 Comment verbosity: sectionPreview doc sentence 2 (295) and blank-skip comment (258) narrate mechanism the code shows R4 Gon (P2 downgraded to Nit) Yes

Contested and acknowledged

CRF-9 (Note, chat.md:1) - PR body's wipe rationale

  • Finding: The PR body claimed "the postprocessor wipes and rewrites reference/api/ each run," which is false; make gen runs the generator against a _gen tmpdir and moves files back per-file (Makefile:1361-1367), so stale files survive and are not auto-removed.
  • Author response (R3): Corrected the PR body; it now states make gen runs against a tmpdir and moves files back per-file so stale pages survive, and the chat.md deletion is explicit.
  • Status: Acknowledged/fixed. The corrected PR body matches the verified Makefile behavior.

CRF-10 (Note, manifest.json:1688) - CLI index dual manifest route

  • Finding: reference/cli/index.md is targeted by two manifest routes with different titles (parent Command Line at 1688, self-child coder at 1704). "Front-matter title matches its manifest route" is ambiguous for this page depending on which route the coder.com nav binds.
  • Author defense (R3): The two routes are pre-existing; docs/manifest.json is byte-identical to main, so this PR introduces no change to the route topology.
  • Status: Contested, no panel disposition yet. The author's scope point is factually correct (manifest unchanged), but the finding was raised as a Note/residual-uncertainty about the CRF-2 fix binding, not as a claim this PR introduced the dual route. Panel may confirm the benign outcome (title resolves to Command Line either way) or leave as a coder.com-side confirmation item.
  • Panel closure (R3, benign): Five reviewers (Mafuuu, Pariston, Razor, Melody, Kite) concurred. Under resolveDocTitle precedence (frontmatter wins), cli/index.md renders Command Line regardless of which of the two routes the nav binds, so the CRF-2 fix is robust to the dual route. Pariston (original raiser) withdrew the residual. Only residual is the manifest-sourced sidebar label (coder), unchanged from main. Mafu-san Note: the PR body's universal claim "each page's front-matter title matches its manifest route" is not literally true for this dual-route page; consider qualifying it. Benign, closed.

Round log

Round 1

Netero-only (2 P2 gate the panel). Reviewed against 9862f10..b421f74.
Verified all three findings against the code and the coder.com renderer precedence
(vault: projects/coder.com/docs-title-precedence.md, projects/coder/docs-reference-generators-frontmatter.md).

  • CRF-1/CRF-2: mechanical title divergence verified (head -3 of index pages vs docs/manifest.json
    entries at 1557-1561 and 1688-1692). Renderer precedence frontmatter.title -> manifest route.title
    confirmed live in production via merged coder.com chore: bump @testing-library/user-event from 13.5.0 to 14.1.0 in /site #964/fix: Rename coder to sshd on Windows for VS Code Remote support #974; RAW markdown fetched at request time,
    so the change reaches production on merge. Both renderers hide the body H1, so the pre-PR title came
    from the manifest, not the removed H1. The PR body's "rendered output is unchanged" claim is false
    for these two index pages.
  • CRF-3: no *_test.go under scripts/apidocgen or scripts/clidocgen; extractSectionName derives
    filename, section title, and manifest route title. A regression is self-consistent (idempotent wrong
    output) and would pass the golden make gen diff check.
  • chat.md deletion verified safe: os.RemoveAll(apiPath) (main.go:118, pre-existing) wipes
    reference/api/ each run, and no manifest/doc references remain. PR body justification accurate.

Round 2

Churn guard PROCEED: CRF-1, CRF-2, CRF-3 all author-fixed in e399b7c. Panel (14 reviewers)
verified all three genuinely fixed at the code. First panel review (Netero-only was R1).
Reviewed against a9a1dcc..e399b7c. New: 1 P2, 3 P3, 1 Nit, 2 Note.

Cross-check notes:

  • CRF-4 (P2): three reviewers (Melody, Razor, Zoro) independently traced that security.def
    (included by main.dot:92 via {{#def.security}}) still emits # Authentication. swagger.json
    is OpenAPI 2.0 (securityDefinitions), which widdershins converts to components.securitySchemes,
    so the guard is true and the section is emitted. Empirically confirmed: authentication.md is the
    ONLY docs/reference/api/*.md file not starting with ---, and its content == security.def.
    Ryosuke's Note that the fallback is "unreachable" is WRONG (contradicted by CRF-4); the fallback is
    load-bearing. Mafuuu's claim that authentication.md is "hand-maintained/not generated" is also wrong.
  • CORRECTION to R1: make gen sets APIDOCGEN_DOCS_DIR=$tmpdir (Makefile:1361-1367); os.RemoveAll
    wipes the TMPDIR, not docs/reference/api, then files are mv'd back per-file. So the pipeline does
    NOT wipe docs/, stale files survive, and the PR body's chat.md rationale is false (CRF-9). My R1
    verification and vault edit claiming a direct wipe were wrong; vault re-corrected.
  • CRF-5 (P3): verified login.md first heading is now ## Usage (no #login); support-bundle.md:73
    links to login.md#login. One live in-repo instance of the page-slug-anchor class.
  • CRF-6 (P3): unquoted YAML title; latent (all current tags/command names YAML-safe). Kept P3 over
    Notes: PR introduces the YAML constraint and the failure is silent (CI green, 3 consumers diverge).
  • CRF-7 (P3): Leorio + Chopper converged; caller log.Fatals with no section locator.
  • Event COMMENT (highest is P2; REQUEST_CHANGES reserved for P0-P1).

Round 3

Churn guard PROCEED: 5 addressed (CRF-4,5,7,8,9), 1 contested (CRF-10), 1 deferred with ticket (CRF-6 -> DOCS-596), 0 silent.
New commit 6419a94 touches security.def, support-bundle.md, postprocess/main.go, main_test.go, authentication.md.
Panel round to verify fixes. Reviewed against 99e740b..6419a94.

Cross-check (R3):

  • All round-2 fixes verified genuine by the panel: CRF-4 (all 3 producers emit front matter; authentication.md migrated; every api/cli page starts with ---), CRF-5 (link repointed; page-slug-anchor class fully swept, zero siblings), CRF-7/CRF-8 (mode-named errors + CutPrefix), CRF-9 (PR body corrected).
  • CRF-10 closed benign (5 reviewers). CRF-6 deferred (DOCS-596), not re-evaluated. CRF-11 (Netero) not re-raised.
  • New: CRF-12 (P3, Bisky/Leorio/Chopper) - CRF-7's locator fix reached only the legacy branch (main.go:289); the front-matter-no-title branch (main.go:282), now the primary path after CRF-4, names the mode but not the section, and its two tests codify the locator-less message. Hisoka/Kite rated it Note (latent); kept P3 per tiebreaker and consistency with CRF-7's original P3 (producer-regression guard on the path that matters most; false-confidence test).
  • New: CRF-13 (Nit, Leorio) - commit subject states the ritual not the change (near-zero if squash-merged).
  • Event COMMENT (highest new is P3).

Round 4

Churn guard PROCEED: CRF-12 addressed (8926709, sectionPreview helper on the front-matter-no-title branch + test asserts section content), CRF-11 acknowledged (defensive fallback kept, hard-fail tracked separately), CRF-13 addressed (squashed to a single commit with a descriptive subject). PR rebased onto 9236670. 0 silent.
Reviewed against 9236670..8926709.

Cross-check (R4):

  • CRF-12 verified genuinely fixed by the panel: sectionPreview helper appends ; section starts: %q
    to the front-matter-no-title error (main.go:282); tests assert the section content appears
    (FrontMatterMissingTitle/FrontMatterEmptyTitle); extractSectionName 100% covered. Root cause,
    no new problem. CRF-13 verified (squash, descriptive subject). CRF-11 accepted, CRF-10 benign,
    CRF-6 deferred (DOCS-596) - none re-raised.
  • New (all non-blocking): CRF-14 (Note, Netero; corroborated Hisoka/Bisky/Chopper/Razor) sectionPreview
    truncation branch untested, cosmetic. CRF-15 (Note, Chopper) blank-skip loop ignores scanner.Err();
    a >64KB line degrades to a misleading "header not found" - latent, API-doc lines never approach 64KB.
    CRF-16 (Nit) comment verbosity.
  • Gon rated the comment-verbosity items P2. Downgraded to Nit: comment narration where the code works
    is a style/convention issue (AGENTS.md "describe behaviour not mechanism"), zero runtime/correctness
    consequence; Gon's own note conceded it is "not per-line severity." Keep-argument for higher severity
    (violates a project rule) does not lift a readability nit to P2. Merged the two instances into one Nit.
  • Event APPROVE (downgraded to COMMENT by the integration): all substantive findings resolved across
    4 rounds; only cosmetic Notes + one comment Nit remain, plus the ticketed CRF-6 deferral.
About deep-review

CRF = Coder Review Finding (P0-P4, Nit, Note)

Reviewer Focus
Bisky tests
Chopper ops/errors
Churn-guard change verification
Ging language modernization
Gon naming
Hisoka edge cases
Killua perf
Kite change integrity
Knov contracts
Knuckle SQL
Komugi flake/determinism
Kurapika security
Law decomposition
Leorio docs
Luffy product
Mafu-san process
Mafuuu contracts
Melody dispatch/pairing
Meruem structural
Nami frontend
Netero mechanical checks
Pariston premise testing
Pen-botter product gaps
Razor verification
Robin duplication
Ryosuke Go arch
Takumi concurrency
Zoro shape

🤖 Managed by Coder Agents.

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread scripts/apidocgen/postprocess/main.go Outdated
Comment thread scripts/clidocgen/command.tpl Outdated
Comment thread scripts/apidocgen/postprocess/main.go
@nickvigilante
nickvigilante force-pushed the vigilante/docs-553-phase-2b-codercoder-generators-emit-front-matter-titles branch from b421f74 to e399b7c Compare July 21, 2026 14:42
@nickvigilante

Copy link
Copy Markdown
Contributor Author

/coder-agents-review

Round 1 findings (CRF-1, CRF-2, CRF-3) are all addressed in e399b7c and the threads are resolved:

  • CRF-1: API index emits title: REST API (matches manifest route).
  • CRF-2: CLI index emits title: Command Line via the atRoot branch (matches manifest route).
  • CRF-3: added a table test for extractSectionName.

The branch was also rebased onto current main and consolidated to one commit; swagger.json and manifest.json are byte-identical to main.

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 while authentication.md keeps its H1 (see the P2).
  • The chat.md deletion rationale ("the postprocessor wipes and rewrites reference/api/ each run") is false: make gen runs the generator against a _gen tmpdir and then moves files back per-file (Makefile:1361-1367), so os.RemoveAll hits the tmpdir, not docs/. Stale files are not auto-removed; the explicit deletion in this PR is what removes chat.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.def was not ... authentication.md alone 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.md used to open with # login (anchor #login); it now opens with front matter and its first heading is ## Usage, so #login is gone ... docs/support/support-bundle.md links 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.

Comment thread scripts/apidocgen/markdown-template/main.dot
Comment thread scripts/apidocgen/postprocess/main.go Outdated
Comment thread scripts/apidocgen/postprocess/main.go Outdated
Comment thread docs/reference/api/chat.md
@nickvigilante
nickvigilante force-pushed the vigilante/docs-553-phase-2b-codercoder-generators-emit-front-matter-titles branch from e399b7c to 6419a94 Compare July 22, 2026 14:43
@nickvigilante

Copy link
Copy Markdown
Contributor Author

/coder-agents-review

Round 2 addressed in 6419a94; all inline threads resolved.

  • CRF-4 (P2): scripts/apidocgen/markdown-template/security.def now emits front matter, so authentication.md is migrated like the other generated API pages. Verified by running widdershins + postprocess against the committed swagger.json: same file set, and manifest.json/swagger.json stay byte-identical to main. The "every generated file" claim now holds.
  • CRF-5 (P3): docs/support/support-bundle.md no longer links to the removed login.md#login anchor.
  • CRF-7 (P3) / CRF-8 (Nit): extractSectionName now names the failure mode and echoes the offending section's first line, and the legacy branch uses strings.CutPrefix; error-path tests assert the messages.
  • CRF-6 (P3): unquoted YAML titles deferred to DOCS-596, all current tags/paths are YAML-safe; a correct fix spans both generators + the read side. Happy to pull it in if you'd prefer.
  • CRF-9 (Note): the chat.md rationale was already corrected in the PR body (the body update raced this review).
  • CRF-10 (Note): the two cli/index.md manifest routes are pre-existing (manifest.json == main); no change here.

Branch rebased onto current main.

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.dot resource loop, main.dot Schemas, and security.def), authentication.md is migrated, and every file under docs/reference/{api,cli}/ now leads with ---. The class is closed, not the instance.
  • CRF-5 (P3): the support-bundle.md link dropped the dead #login fragment, and the page-slug-anchor class was swept clean (no remaining <page>.md#<page> self-title links anywhere in docs/).
  • 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.md rationale 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.

Comment thread scripts/apidocgen/postprocess/main.go Outdated
Comment thread scripts/apidocgen/postprocess/main.go
@nickvigilante
nickvigilante force-pushed the vigilante/docs-553-phase-2b-codercoder-generators-emit-front-matter-titles branch from 6419a94 to 8926709 Compare July 22, 2026 19:24
@nickvigilante

Copy link
Copy Markdown
Contributor Author

/coder-agents-review

Round 3 addressed in 89267098 (rebased onto main, squashed to one commit, force-pushed):

  • CRF-12 (P3): the front-matter-no-title parse error now appends a compact preview of the offending section via a new sectionPreview helper: front-matter block has no non-empty "title:" key; section starts: %q. This makes the now-primary front-matter path locatable in make gen output, not just the legacy # path. (Echoing first there was useless, it's always the bare ---, so this uses section content instead.) Tests: the error cases now assert the section content / preview label is present, and the redundant standalone TestExtractSectionNameErrorLocatesSection was folded into the table test.
  • CRF-11 (Note): the legacy # fallback is unreachable during make gen now that all three producers emit front matter; kept as a low-cost defensive guard (still covered by the extractSectionName tests). No code change.

Also addressed the round-3 nits: consolidated the branch to a single descriptive commit (was a ritual address round-2 review subject), and qualified the PR-body claim about front-matter titles matching manifest routes for the dual-route cli/index.md.

All threads from rounds 1-3 are resolved. CI is green on the changed paths: gen, fmt, lint-docs, check-docs, and Go lint all pass. CRF-6 remains deferred to DOCS-596 (unchanged from round 2).

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread scripts/apidocgen/postprocess/main.go
Comment thread scripts/apidocgen/postprocess/main.go
Comment thread scripts/apidocgen/postprocess/main.go Outdated
@nickvigilante
nickvigilante force-pushed the vigilante/docs-553-phase-2b-codercoder-generators-emit-front-matter-titles branch from 8926709 to c9911c0 Compare July 22, 2026 21:22
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).
@nickvigilante
nickvigilante force-pushed the vigilante/docs-553-phase-2b-codercoder-generators-emit-front-matter-titles branch from c9911c0 to f43d029 Compare July 22, 2026 21:24
@nickvigilante
nickvigilante marked this pull request as ready for review July 22, 2026 21:38
nickvigilante added a commit that referenced this pull request Jul 22, 2026
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).
@nickvigilante

Copy link
Copy Markdown
Contributor Author

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 (title + description + state + icon_path); this PR emits title only. Because description/state/icon_path come from manifest.json (available in the API postprocessor, not the widdershins .dot templates), #27246 keeps the templates emitting # {name} and swaps in the front-matter block at write time. A consequence is that it does not need the main.dot/security.def edits made here, and authentication.md migrates through the same uniform path.

Hardening ported from this PR into #27246 in 4959dde0de:

  • extractSectionName now surfaces scanner.Err() instead of masking it as a missing header (CRF-15 parity), and
  • uses strings.CutPrefix for the heading parse (CRF-8).

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):

  • the front-matter title: parsing branch in extractSectionName, and
  • the sectionPreview helper and its front-matter-no-title error path.

Tracking issue DOCS-553 is being marked Done (absorbed by #27246 / DOCS-483).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant