feat: make CLI/API doc generators emit front-matter metadata (Phase 2) - #27246
Conversation
5b853d6 to
e54fdad
Compare
|
/coder-agents-review |
|
Chat: Review posted | View chat Review history
deep-review v0.9.0 | Round 5 | Last posted: Round 5, 30 findings (1 P1, 8 P3, 7 Nit, 14 Note), COMMENT. Review Finding inventoryFinding inventory: PR #27246Law analysisNot run. Effective additions 131 (< 1000 threshold). Findings
Contested and acknowledgedCRF-14 (Note, cross-repo merge gate) - correct gating coder.com PR
CRF-15 (Note, main.go:220) - pre-existing invalid sort.Slice comparator
CRF-23 (Note, apidocgen/postprocess/main.go) - Phase 3 API curated-metadata source
CRF-29 (Note, clidocgen/main.go) - CLI docs-nav staleness
Round logRound 1Netero first pass (CRF-1/2/3, all P3-and-below, panel proceeded). Panel of 13: Bisky, Hisoka, Mafu-san, Mafuuu, Pariston, Komugi, Gon, Leorio, Ging-go, Ryosuke, Robin, Melody + Kite (wildcard). Reviewed against 8eaf4f5..7791007. No P0/P1; event COMMENT. 5 P3, 3 Nit, 7 Note. CRF-12/13/14/15 raised in review body (process/cross-repo/pre-existing). Bisky: no findings. Komugi: no in-scope findings. Round 2Churn guard: PROCEED (13 addressed, 2 acknowledged, 0 silent/contested). Author pushed e53d5e0 (force-push rebase onto main, ~67 commits; new shared package scripts/docgenenv with tests). Significant restructure, so panel re-runs to verify fixes. Base a9a1dcc..head e53d5e0. NOTE: CI lint (job 88677231209) is failing on this head; investigate during cross-check. Netero (advisory, post-panel) + panel of 13: Bisky, Hisoka, Mafu-san, Mafuuu, Pariston, Komugi, Gon, Leorio, Ging-go, Ryosuke, Robin, Melody + Meruem (wildcard). Verified R1 fixes hold (CRF-1/2/3/4/5/7/8/10/11 confirmed resolved). New: 1 P1 (CRF-16 emdash, blocks lint CI), 1 P3 (CRF-18 front-matter emitter duplication, Robin+Meruem+Ryosuke converged; root cause of CRF-17), 2 Nit (CRF-19 slices.SortFunc, CRF-20 prependFrontMatter comment overstates degradation), 4 Note (CRF-21 icon_path untested, CRF-22 trailing-space scalar, CRF-23 Phase 3 API metadata source, CRF-24 duplicated doc comment). CRF-17 folded into CRF-18. Body: Mafu-san P2 process (verification set omitted make lint, the red gate; emdash a recurring mechanical-rule violation). Event REQUEST_CHANGES (P1). Reviewed against a9a1dcc..e53d5e0. Round 3Churn guard: PROCEED (7 addressed, 1 acknowledged CRF-23 Phase 3 out of scope, 0 silent/contested). Author pushed ee796e7 (unified front-matter emission into new shared scripts/docgenenv/frontmatter.go FrontMatter(Route); command.tpl collapsed to {{- frontMatter . -}}; local apidocgen frontMatter deleted; new frontmatter_test.go; regex trailing-space fix; slices.SortFunc). CI green. Panel re-runs to verify the unified emitter. Base 2b2a5c9..head ee796e7. Netero (advisory): no findings, all R2 fixes verified. Panel of 13: Bisky, Hisoka, Mafu-san, Mafuuu, Pariston, Komugi, Gon, Leorio, Ging-go, Ryosuke, Robin, Melody + Kite (wildcard). All R2 fixes confirmed resolved at the code. Hisoka/Mafuuu/Pariston/Komugi/Ging-go/Mafu-san: no findings. New: 1 P3 (CRF-25 CLI-side Route construction manual/duplicated/untested, reintroduces CRF-18 field-drift class; Bisky P3 + Kite + Robin converged), 2 Nit (CRF-26 CRF-22 review-ID leaked into test comments, CRF-27 FrontMatter comment narrates mechanism), 2 Note (CRF-28 double-wrapped manifest-load error, CRF-29 pre-existing CLI nav staleness downgraded from Melody P3). Verified Makefile: make gen discards clidocgen's manifest (only .md copied back); committed manifest comes from apidocgen staging, so CRF-29 nav gap is pre-existing, out of scope, and not worsened/fixed by this PR. Event COMMENT + dismiss stale REQUEST_CHANGES (P1 CRF-16 fixed; no new blocker). Reviewed against 2b2a5c9..ee796e7. Round 4Churn guard: PROCEED (4 addressed, 1 deferred with ticket DOCS-594, 0 silent/contested). Author pushed 74b941f (CRF-25: CLI index struct copy + shared cliCommandRoute helper + TestCLICommandRoute; CRF-26/27 comment cleanups; CRF-28 dropped double-wrap in both generators). CI green. Base 608c2ee..head 74b941f. Netero (advisory): no findings, all R4 fixes verified. Panel of 10: Bisky, Hisoka, Mafuuu, Robin, Ryosuke, Gon, Leorio, Ging-go, Melody + Kite (wildcard); trimmed always-on duplicates (Mafu-san/Pariston/Komugi) proportional to a polish round. R3 fixes (CRF-25/26/27/28) all confirmed resolved at the code; Hisoka/Mafuuu/Robin/Ryosuke/Ging-go/Kite: no findings. New: 1 P3 (CRF-30 vacuous TestYAMLScalarRoundTrip for the reserved-word/number class, Bisky, mutation-proof; runtime correct), 3 Note (CRF-31 duplicated undocumented LoadManifest-wrap comment, CRF-32 route-not-found errors omit manifest path, CRF-33 API-side page-vs-manifest-child future-field drift mirror pre-existing). Event COMMENT (P3 non-blocking) + dismiss:true retry of stale R2 REQUEST_CHANGES. Reviewed against 608c2ee..74b941f. Round 5Churn guard: PROCEED (3 addressed, 1 acknowledged CRF-33 folded into Phase 3, 0 silent/contested). Author pushed 66abf4b (CRF-30 test hardening: direct quoted-class assertions in TestYAMLScalarBareWhenSafe + new TestExtractSectionName + cliIndexRouteFrom/TestCLIIndexRouteMirrorsManifest; CRF-31 wrap guarantee on LoadManifest; CRF-32 manifest path in route-not-found errors). CI pending. Base 99e740b..head 66abf4b. Round 5Churn guard: PROCEED (3 addressed, 1 acknowledged CRF-33 folded into Phase 3, 0 silent/contested). Author pushed 66abf4b (CRF-30 test hardening + TestExtractSectionName + cliIndexRouteFrom/TestCLIIndexRouteMirrorsManifest; CRF-31 LoadManifest wrap doc; CRF-32 manifest path in errors). Netero (advisory): no findings; independently confirmed the CRF-30 isBareScalar/number mutants die. Panel of 9: Bisky, Hisoka, Mafuuu, Pariston, Gon, Leorio, Ging-go, Melody + Kite (wildcard); trimmed proportional to a test-hardening round. Bisky/Mafuuu/Pariston/Ging-go/Melody/Kite: no findings; Bisky/Melody/Kite/Pariston independently reran the CRF-30 mutations and confirmed they die. New: 1 P3 (CRF-34 isBareScalar incomplete for hex/octal/binary/underscore-int/timestamp, Hisoka, empirically verified by orchestrator; non-blocking, not reachable today), 2 Nit (CRF-35 re-duplicated rationale comment, CRF-36 commit-body CRF-N tags). Event COMMENT (P3 non-blocking) + dismiss:true retry of stale R2 REQUEST_CHANGES. Reviewed against 99e740b..66abf4b. About deep-reviewCRF = Coder Review Finding (P0-P4, Nit, Note)
|
There was a problem hiding this comment.
Nice, tight migration: one logical change (generators emit per-page metadata as YAML front matter, drop the leading H1) across both doc generators plus the mechanical regeneration of 166 CLI + 31 API pages. The AI-authorship disclosure and manual verification are appreciated, and several reviewers independently confirmed the load-bearing claims: manifest.json/swagger.json/docs.go are byte-identical in the diff, MD041 is disabled so the H1 removal breaks no lint rule, and the front matter is well-formed (colons, backticks, and DEPRECATED: prefixes are correctly JSON-quoted, state renders as a YAML sequence). Hisoka's verdict on the code itself: "Boring code, and I mean that as a compliment."
Severity count: 0 P0/P1, 5 P3, 3 Nit, 7 Note. No blocking defects; the P3s are correctness/maintainability gaps worth resolving before merge. Because this panel assumes no follow-up (agent-authored, no backlog), CRF-5, CRF-6, and CRF-9 each need a decision now, not "later."
Inline findings CRF-1 through CRF-11 below. Four items belong here in the body:
CRF-12 (P3, process, Mafu-san). The PR's "no body changes" proof is a vacuous command: git diff docs/reference/ | grep '^-' | grep -v '^---' with no ref compares the working tree against HEAD, which on a committed tree is empty regardless of what the PR changed. The underlying claim is in fact true (all 197 base..HEAD removals are # H1 lines), but the command shown would print (empty) even if a real body removal had slipped in, and it inspects removals while the comment describes added lines. Show the command that actually tests the claim: git diff <base>..HEAD -- docs/reference/ | grep '^-' | grep -v '^---'.
CRF-13 (Nit, commit hygiene, Leorio). Commit e54fdada uses scope feat(docs):, but its source changes are under scripts/, and AGENTS.md requires a scope to be a real path containing every changed file. This is the cross-cutting case that should be scope-less (feat:), as the later commit 7791007f correctly is. Moot under squash-merge on the (correct) PR title.
CRF-14 (Note, cross-repo gate, Hisoka + Mafu-san + Melody). The PR gates its merge on coder.com#968. Prior deep-review knowledge (vault, unverifiable from this repo) suggests #968 was re-scoped and the llms + Algolia front-matter awareness actually shipped in #964/#974, and that a second raw-markdown surface, the .md proxy twin advertised via <link rel="alternate" type="text/markdown">, keeps serving raw front matter until #974 deploys. Please confirm which coder.com PR(s) actually strip/consume the front matter so the manual merge-ordering decision rests on the right surface(s). This is an inference from prior review context, not something the panel could execute here.
CRF-15 (Note, pre-existing, Komugi). sort.Slice at main.go:220 uses slices.IsSorted([]string{a, b}) as its Less, which returns true for equal keys in both directions, undefined behavior per sort.Slice. Pre-existing (blame ed908ed019), safe today only because API section names are unique. Flagging for the record; not this PR's job to fix.
docs/support/support-bundle.md:70
P3 [CRF-6] Dropping the leading # {name} H1 orphans the page-title anchor #login, and this doc still links to it. (Hisoka)
docs/support/support-bundle.md:70points at../reference/cli/login.md#login, and baselogin.mdopened with# login(anchor#login); the regenerated page's first heading is now## Usage, so#loginresolves to nothing.
Confirmed: login.md now starts with ## Usage; front matter does not mint a heading anchor. A full-repo sweep found this is the only live instance (every other reference/*.md#... link keys on a ##/### sub-heading such as #--flag or #get-users, which are unaffected). pnpm check-docs is markdownlint + table-formatter only and does not validate cross-file fragments, so this ships green and silent. Consequence is cosmetic (the reader still lands at the top of login.md), hence P3. Fix: drop the fragment (../reference/cli/login.md).
🤖
docs/reference/api/chat.md:1
Note [CRF-9] A stale orphan page survives the API-docs regeneration and now diverges from the migration's "every generated page is self-describing" invariant. (Kite)
docs/reference/api/chat.mdcontains only# Chat. It is not indocs/manifest.json, is not linked from any doc, and is not one of the 31 generated sections (chats.mdis the real page).
Confirmed: not in the manifest, content is just # Chat. The API pipeline never wipes docs/reference/api/ (the copy-back is per-file), so files with no generated counterpart are never removed. This PR converts every generated API page to front matter, but chat.md keeps a bare H1 and no front matter, so after Phase 3 it becomes a permanent front-matter-less page the generator cannot touch. A one-line git rm docs/reference/api/chat.md closes the gap while this diff is already in the directory; otherwise it needs a ticket, not a silent drop.
🤖
🤖 This review was automatically generated with Coder Agents.
7791007 to
e53d5e0
Compare
|
Thanks for the review — pushed
CRF-6 — dropped the dead Verified: |
|
/coder-agents-review |
2415167 to
02fcd2e
Compare
|
/coder-agents-review Re-requesting review on
|
There was a problem hiding this comment.
Strong round-2 turnaround. Every one of the 15 round-1 findings was engaged with, and the panel verified the fixes hold rather than taking the replies on faith: the escaper and the manifest schema/traversal are genuinely de-duplicated into one scripts/docgenenv package (CRF-1/CRF-4), the reserved-scalar quoting is proven by a real yaml.v3 round-trip test that also survived timestamp/hex/underscore-number probes (CRF-2), both index pages now mirror their manifest route (CRF-5), the #login anchor class is fully closed with no siblings (CRF-6), and prependFrontMatter/extractSectionName now share an enforced heading contract (CRF-11). CRF-12's vacuous verification command was fixed at the reasoning level, not just reworded. Nice work. Hisoka's read of the code: "You came looking for a fight and found the code had already won it."
Round-2 severity count: 1 P1, 1 P3, 2 Nit, 4 Note. The one blocker:
CRF-16 (P1) is why CI lint (job 88677231209) is red: three emdash U+2014 characters in the new package's doc comments. It is mechanical to fix but it blocks merge, and it is the inline comment below. This connects to a process point worth raising here in the body:
Mafu-san (P2, process). The PR's "Verification & evidence" section lists go build/go vet/go test and pnpm check-docs as passing but omits make lint, which is the one CI gate that is red. The listed checks are truthful, but the verification set was assembled from a subset that skipped the mandatory gate, so a reader trusting it believes the PR is merge-ready when it is not. AGENTS.md lists lint as "always run after changes." The deeper pattern: the emdash ban lives in AGENTS.md, the docs style guide, make lint, and the agent's own prompt, yet three fresh emdashes landed in comments written during this fix cycle. Before presenting a PR as verified, run make lint, and describe the verification set by what the CI gates require, not by what happened to pass. Fixing CRF-16 clears the gate; wiring make lint into the pre-submit habit clears the class.
One structural item (CRF-18) and four low-severity items are inline. Because this panel assumes no follow-up, the CRF-18 divergence trap is worth closing now while the abstraction boundary is fresh, but it is not a merge blocker on its own.
🤖 This review was automatically generated with Coder Agents.
02fcd2e to
ee796e7
Compare
|
Round 2 addressed in
|
|
/coder-agents-review Round 2 fixes are in |
There was a problem hiding this comment.
This round closes the book on the round-1/round-2 findings. All 24 prior findings are addressed or accepted, and the panel verified the fixes at the code rather than trusting the replies: front-matter emission is now a single shared docgenenv.FrontMatter(Route) reached by the API postprocessor directly and by command.tpl via a frontMatter func, so the two emitters can no longer drift on field set or escaping (CRF-17/18); the CLI index carries its state arm; slices.SortFunc replaced the index comparator; the prependFrontMatter comment now names extractSectionName as the load-bearing guard; icon_path and trailing-space scalars have real coverage; and the emdash gate is green. Netero found nothing, and six panelists returned clean. The tests are honest: TestYAMLScalarRoundTrip parses the emitted YAML back and asserts string identity rather than pinning golden bytes. Ryosuke's read: "When the architecture is clean, say so: this is clean."
I'm dismissing the prior REQUEST_CHANGES: the P1 that blocked it (CRF-16 emdash / red lint) is fixed and CI is green, so this is no longer blocked. Round-3 severity count: 0 P0/P1/P2, 1 P3, 2 Nit, 2 Note. None block merge; the P3 is a maintainability/regression-trap worth closing while the code is fresh, but it guards a future field, not a present bug.
One correction to a panel finding, recorded for honesty: a reviewer flagged that make gen is not manifest-idempotent (a fresh clidocgen run adds 7 Command Line nav children). Verified against the Makefile: make gen runs clidocgen in a tmpdir and copies back only the .md pages, discarding its rebuilt manifest; the committed docs/manifest.json comes from the apidocgen staging manifest, which leaves the Command Line children untouched. So make gen is idempotent for what it writes. The real, pre-existing kernel (7 ai-gateway/server_fix-oidc-links pages absent from nav) is CRF-29 below, out of scope for this PR.
🤖 This review was automatically generated with Coder Agents.
ee796e7 to
74b941f
Compare
|
Round 3 addressed in
Regen remains byte-identical (166 CLI + 31 API pages unchanged); |
|
/coder-agents-review Round 3 fixes are in |
There was a problem hiding this comment.
Round 4 is a clean polish pass. All four addressed round-3 findings verify at the code, not just in the replies: CRF-25 is closed at the root by making the CLI index a struct copy (idx := *cmdLine; idx.Children = nil) that mirrors the API index and extracting the per-command mapping into one cliCommandRoute(cmd) used by both the template func and the manifest rebuild, with TestCLICommandRoute pinning it; the leaked (CRF-22) review IDs are gone; the FrontMatter comment leads with the why; and the double-wrapped manifest-load error is dropped in both generators. CRF-29 is deferred with a real ticket (DOCS-594). Netero and six of the ten panelists returned clean. Ryosuke's read: "the abstractions earn their indirection."
Retrying the dismissal of the stale round-2 REQUEST_CHANGES (the round-3 attempt hit a token-permission 403). If it fails again, the marker is stale, not active: the P1 that raised it (CRF-16) has been fixed for two rounds and CI is green.
Round-4 severity count: 0 P0/P1/P2, 1 P3, 3 Note. None block merge. The P3 is a test-authenticity gap, not a runtime bug, and the Notes are minor or pre-existing. This PR is in good shape to merge once the P3 test assertion is tightened (optional but cheap).
🤖 This review was automatically generated with Coder Agents.
74b941f to
66abf4b
Compare
|
/coder-agents-review Round 4 fixes are in
Verification: |
There was a problem hiding this comment.
Round 5 is clean test-hardening. The CRF-30 fix is verified, not just claimed: five reviewers independently reran the mutations and confirmed both die (collapsing the isBareScalar reserved-word switch and forcing the number check to return true now fail TestYAMLScalarBareWhenSafe), and the round-trip docstring is honest about what it can't see. CRF-31 (wrap guarantee documented on LoadManifest) and CRF-32 (route-not-found errors name the manifest file) both verify, and the new TestExtractSectionName / TestCLIIndexRouteMirrorsManifest cover the previously-unguarded arms. Every prior finding is resolved, accepted, or deferred with a ticket. Kite's read: "the right way to retire a test-exists-but-proves-nothing finding."
Round-5 severity count: 0 P0/P1/P2, 1 P3, 2 Nit. Nothing blocks merge. One inline P3 (non-blocking, not reachable today) and one inline Nit. Two body items:
CRF-36 (Nit, commit message, Leorio). The commit body tags six bullets with bare CRF-N review IDs ((CRF-2), (CRF-3), ...) that resolve to nothing a future git log/git blame reader can open. This is the same class as CRF-26 (leaked review IDs in test comments, since fixed), and stronger here because a scopeless single commit's message is permanent history and the first thing a bisecting reader sees. The prose already tells the story; drop the (CRF-...) parentheticals and keep the Linear: DOCS-483 reference, which is the one a reader can act on.
Process note (Gon): the duplicated-rationale-comment pattern (CRF-24, CRF-31, and CRF-35 below) keeps recurring as the refactor cycles re-mint the same "mirror the manifest route via the shared emitter" rationale on a declaration and its callers. When a helper carries the why, its callers shouldn't repeat it.
Retrying the dismissal of the stale round-2 REQUEST_CHANGES (the round-3 and round-4 attempts hit a token-permission 403). If it fails again, the marker is stale, not active: the P1 that raised it was fixed three rounds ago and CI is green.
🤖 This review was automatically generated with Coder Agents.
| return false | ||
| } | ||
| // Likewise quote anything that parses as a number (e.g. "123", "1.5"). | ||
| return !numberScalarRegex.MatchString(s) |
There was a problem hiding this comment.
P3 [CRF-34] isBareScalar still emits bare scalars that YAML resolves to non-string types, an incomplete fix of the CRF-2 class. (Hisoka)
The CRF-2 fix added a switch for bool/null aliases and numberScalarRegex for decimals, but the class has more members. I reproduced these in the worktree by running each through YAMLScalar and decoding the emitted value: <scalar> into a generic any (what a front-matter consumer does):
in="0x1F" scalar="0x1F" -> int 31 in="0o17" scalar="0o17" -> int 15 in="0b101" scalar="0b101" -> int 5 in="1_000" scalar="1_000" -> int 1000 in="2024-01-01" scalar="2024-01-01" -> time.Time
All pass safeScalarRegex (alphanumerics only) and none match numberScalarRegex (which only covers 0x/0o/0b-free decimals), so isBareScalar returns true and they ship unquoted. YAMLScalar's own doc says it JSON-encodes "a bare word/number YAML would otherwise resolve to a bool, null, or number", so hex/octal/binary/underscore ints and timestamps are the function contradicting its stated contract, not merely an uncovered corner.
Consequence: a curated title/description/state that is (or starts as) a hex/octal/date constant parses as int/time.Time in a generic reader; the coder.com title path honors a front-matter title only when it is a non-empty string and falls back to the manifest label otherwise, so a date-shaped title would silently drop to the manifest label. No production value hits this today (titles are command/section names, descriptions are cmd.Short, state is early access), which is why it is P3 and non-blocking, and why CRF-2 was a Note.
This is the third pass at this escaper's completeness (CRF-2, CRF-30, now CRF-34), which is the signal: hand-maintaining YAML's type-resolution grammar is whack-a-mole. Either fold the hex/octal/binary/underscore-int and timestamp forms into isBareScalar, or take the root-cause fix Robin raised at CRF-1 and marshal the block through yaml.v3, which closes the entire class at the cost of a one-time page reflow. That is a human call given the deliberate byte-identical-output choice, but the current hand-rolled table demonstrably does not deliver the contract its doc promises.
🤖
| if cmdLine == nil { | ||
| flog.Fatalf("could not find Command Line route in manifest %q", manifestPath) | ||
| } | ||
| // Mirror the whole "Command Line" route (minus its nav children) so the |
There was a problem hiding this comment.
Nit [CRF-35] The call-site comment restates the rationale that already lives on cliIndexRouteFrom, so the two can drift. (Gon)
The comment at
main.go:80-82("Mirror the whole 'Command Line' route (minus its nav children) so the index page front matter carries every current and future per-page field automatically") repeats whatcliIndexRouteFrom's doc (gen.go:110) already says. The only content not on the function is the cross-generator note ("the same way the API index mirrors its manifest route").
This is the CRF-24 / CRF-31 duplicated-rationale-drift class the R5 cliIndexRouteFrom extraction reintroduced at a new location pair. Trim the call site to the cross-generator pointer, or drop it and let the function doc carry the why.
🤖
66abf4b to
4959dde
Compare
|
Folded in the format-agnostic generator hardening from #27297 (now closed, superseded by this PR) in 4959dde:
Not ported from #27297: its front-matter Also rebased onto |
matifali
left a comment
There was a problem hiding this comment.
A few comments, but they look good to me. Please get another code review on Go Code.
| // prependFrontMatter replaces the leading "# {name}" heading of a raw API | ||
| // section with r's front matter block. Callers pass sections that have already | ||
| // cleared extractSectionName, whose fail-fast on a missing "# " heading is the | ||
| // load-bearing guarantee. The prefix check here is a defensive backstop: if a |
There was a problem hiding this comment.
Instead of replacing the top-level heading, why generate that at all?
There was a problem hiding this comment.
Good eye on the CLI/API asymmetry. The # {name} line does double duty here: the postprocessor splits the single widdershins markdown blob into per-endpoint pages and uses that heading (extractSectionName) to derive each page's filename and match its manifest.json route, then swaps it for the front-matter block. So it's consumed before it's replaced, not emitted purely to render.
We also can't assemble the full front matter in the .dot templates: description, state, and icon_path come from manifest.json (for example Chats' state: [early access] and the index icon_path), which widdershins can't see. Only the postprocessor reads the manifest, so the block has to be built there regardless.
Emitting a front-matter title: from the templates and parsing that instead of the H1 is exactly what the sibling PR #27297 did (title-only); we consolidated on this PR because it carries the full metadata. Happy to revisit the template-emission route if you'd prefer CLI/API symmetry, but it changes what the postprocessor parses rather than removing its role. Fuller rationale is under "Why the API side changes the postprocessor, not the .dot templates" in the PR description.
Posted by Coder Agents (AI assistant) on Nick Vigilante's behalf.
4959dde to
441e9ef
Compare
| --- | ||
| title: agent-firewall | ||
| description: Network isolation tool for monitoring and restricting HTTP/HTTPS requests | ||
| --- | ||
|
|
||
| <!-- DO NOT EDIT | GENERATED CONTENT --> | ||
| # agent-firewall |
There was a problem hiding this comment.
I think the DO NOT EDIT comment needs to appear at the top of the file in order to be recognised by editors?
There was a problem hiding this comment.
The YAML front matter has to be at the beginning of the Markdown document to be parsed properly by other systems. I added a YAML comment in the front matter alongside the HTML comment to warn people not to edit those files directly.
Emit per-page metadata (title/description/state/icon_path) as YAML front
matter from the CLI and API reference generators instead of a leading H1,
and regenerate all reference pages.
Coder Agents Review follow-ups:
- Share YAML front-matter escaping + manifest types/traversal via
scripts/docgenenv (CRF-1, CRF-4); harden scalar escaping against reserved
words/numbers (CRF-2) with round-trip tests (CRF-3).
- Generate the CLI and API index pages' front matter from the manifest route
(title/description/icon_path) so the index no longer regresses the rendered
heading (CRF-5).
- prependFrontMatter uses bytes.Cut and only strips a real "# {name}" heading
(CRF-7, CRF-8, CRF-11); unify the manifest traversal via FindRoute (CRF-10).
- Drop the dead #login anchor in support-bundle.md (CRF-6); remove the orphan
reference/api/chat.md (CRF-9).
Linear: DOCS-483
> This PR was created with AI assistance (Coder Agents).
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).
Regenerated docs/reference/cli/*.md via clidocgen and updated the API reference index front-matter so both match the current docs/manifest.json route descriptions and the Phase 2 front-matter generators. Fixes the gen and offlinedocs check_unstaged failures caused by generated-doc drift after rebasing onto main.
…anner Addresses review feedback on the DO NOT EDIT placement: the front matter fence must start at byte 0, so the banner cannot return to line 1. Emit a canonical in-fence '# Code generated by make gen. DO NOT EDIT.' marker as the first line inside the front matter via the shared docgenenv.FrontMatter emitter, so both CLI and API pages carry the durable, engine-agnostic signal. Unify the body '<!-- DO NOT EDIT | GENERATED CONTENT -->' banner behind a single docgenenv.GeneratedContentBanner constant and emit it for API pages too (previously none) via docgenenv.GeneratedHeader, so CLI and API pages are structurally identical. Regenerated all 204 CLI/API reference pages. swagger.json, docs.go, and manifest.json are unchanged. Linear: DOCS-483
2ba2f66 to
6e9ed9a
Compare
Summary
Phase 2 of the H1 → front-matter migration (
DOCS-483; parentDOCS-477). Makes the two reference-doc generators emit per-page metadata as YAML front matter instead of a leading# H1, so generated pages are self-describing andmake genstops reverting migrated pages (Phase 3).Phase 1 (
DOCS-482) made the coder.com renderers prefer a front-mattertitle(manifest fallback).Note
Rebased onto
mainand fully regenerated, and updated across two rounds of Coder Agents Review — see Review follow-ups below.Changes
scripts/clidocgen/command.tpl+gen.go+main.go— front matter now carriestitle(fromfullName) anddescription(from the command'sShort), and the leading# H1is dropped. The CLI index page's front matter is taken from the manifestCommand Lineroute (title/description/icon_path).scripts/apidocgen/postprocess/main.go— reads the manifest and, at write time, injects front matter carrying each section'stitleplus any curateddescription,state, andicon_path. The API index page's front matter is taken from the manifestREST APIroute.scripts/docgenenv(new shared code) — oneYAMLScalarfront-matter escaper, oneRoute/Manifestschema +LoadManifest/FindRoute, and oneFrontMatter(Route)emitter, all imported by both generators (no duplicated helpers, types, or emitters).Metadata → front matter, and what stays in the manifest
Every per-page manifest field is mirrored into the page's front matter:
title,description,state,icon_path. The structural fields stay inmanifest.json:children— the nav tree (explicitly out of scope).path— the manifest's pointer to the file; a page carrying its own path is redundant/error-prone, so it's treated likechildren.The fields are duplicated into front matter and
manifest.jsonis left unchanged, so this is a no-op for rendering today (coder.com strips front matter forllms, and Algolia + the renderer read onlytitle). Removing the fields from the manifest is the natural follow-up, gated on the renderer reading them from front matter first.Why the API side changes the postprocessor, not the
.dottemplatesThe issue text suggested editing
scripts/apidocgen/markdown-template/*. I deliberately did not, because the postprocessor derives each page's filename, section title, and manifest route from the leading# {name}line (extractSectionName). Emitting front matter from the template would break that extraction. Instead the widdershins templates still emit# {name}, the postprocessor reads it (and now verifies it), and then swaps the heading for a front-matter block as each section is written.Review follow-ups (Coder Agents Review)
Round 1 — addressed in
e53d5e03(all threads resolved)route/manifestschema + traversal intoscripts/docgenenv(shared by both generators).YAMLScalarnow quotes YAML-reserved scalars (true/false/null/…, numbers); no current value is affected.YAMLScalarround-trip,FindRoute, andprependFrontMatter.coder/API, fixing a rendered-heading regression (REST API/Command Linewere being overwritten).#loginanchor indocs/support/support-bundle.md(the migratedlogin.mdno longer mints that heading anchor).prependFrontMatter, switched tobytes.Cut, and it now strips the first line only when it is the# {name}heading (extractSectionNameerrors otherwise).docs/reference/api/chat.md(not in the manifest, not linked; the real page ischats.md).FindRoutetraversal.sort.Slice/slices.IsSortedcomparator is left as-is per the review (out of scope; safe today because section names are unique).Round 2 — addressed in
ee796e7107(all threads resolved)make lintfailure on the prior head); the emdash gate is green.docgenenv.FrontMatter(Route), used by the API postprocessor directly and bycommand.tplvia afrontMattertemplate func. This retires the hand-written template YAML and theindexTitle/indexDescription/indexIconPathclosures, so a new front-matter field is wired in one place, and it gives the CLI index thestatearm it previously lacked. Verified byte-identical: a full CLI + API regen produces zero page changes.slices.SortFunc+cmp.Compare(typed comparator).prependFrontMattercomment:extractSectionName's fail-fast is the load-bearing guard; the prefix check is a defensive backstop.icon_path/statecoverage indocgenenv'sTestFrontMatter/AllFields(the branch the index page relies on, previously at 0%).YAMLScalarno longer emits a trailing-space value as a bare scalar (YAML strips it on read, so it would not round-trip); added test coverage.cliIndexRoutedoc comment; the rationale now lives in one place.reference/api/from the manifest, so removing curated metadata from the manifest in Phase 3 needs another source first (a generator that preserves existing front matter, or metadata carried alongside the swagger annotations).make lint, the mandatory CI gate that the earlier list omitted.Cross-repo dependency
Resolved — this PR no longer has a hard merge-ordering gate (CRF-14 was right; the earlier "must merge after #968" note was stale).
The coder.com surfaces that would otherwise leak raw front matter from
coder/codermainare already front-matter-aware on merged PRs:DOCS-554, llms-full.txt corpus + Algolia) — merged.DOCS-574, the.mdproxy twin +llms.txtindex titles) — merged.coder.com#968 (
DOCS-577) was re-scoped to only the renderer route-metadata generalization; it's a no-op on today's corpus and its own description confirms the "deploy before the generators" constraint no longer applies (that was driven by the llms corpus, now in #964). Worth a final confirmation that #964/#974 are deployed before merge, but there's no branch/PR ordering blocker left.Verification & evidence
AI was the primary author of this PR (see disclosure below); per the AI Contribution Guidelines here is manual verification.
make lint(golangci-lint + the emdash gate) passes;go build/go vet/go testare clean for the generators +scripts/docgenenv;pnpm check-docspasses.swagger.json,docs.go, andmanifest.jsonare unchanged — metadata is duplicated into front matter; command/section names and routes did not move.title/description/state/icon_path) + the leading H1 removal; no body reflow. A full CLI + API regen produces zero page changes beyond the two index pages.Terminal evidence
CLI
descriptionfrom the command'sShort(YAMLScalarquotes when needed, e.g. aShortwith a colon):API pages inherit curated manifest metadata (only Agents/Chats have any today):
Diff scope + "no body changes" proof (uses an explicit
base..HEADrange, so it actually tests the claim):Linear: DOCS-483