Skip to content

docs(spec): fence the endpoint listings on the automation and package API reference pages - #16961

Merged
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-15440-fence-endpoint-listings
Sep 8, 2026
Merged

docs(spec): fence the endpoint listings on the automation and package API reference pages#16961
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-15440-fence-endpoint-listings

Conversation

@claude

@claude claude Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Fixes #15440

api/automation-api and api/package-api published their endpoint listing as a run-on line. Both module docblocks captioned a listing with @example Endpoints and then wrote the rows as ordinary prose lines. Consecutive non-blank lines are one markdown paragraph, and the docs site loads no remark-breaks, so every soft break rendered as a space: nine rows on one page and eight on the other arrived as a single sentence with the author's column alignment collapsed away.

Both listings are now fenced at the source, exactly as the neighbouring api/odata and api/metadata docblocks already fence theirs, and the two reference pages are regenerated from them.

Clause-②: no
Fencing a listing changes rendering only. No accept set moves, no export is added, no schema arm, bound or behaviour changes — the page gains the line breaks it always meant to have. This is the boundary test triage wrote on the card, and the diff stays inside it: no schema, no .describe() string, no renderer, no remark plugin.

Premises, re-measured on this branch's base rather than inherited

Base f36eef55d. All five held.

  1. @example Endpoints occurs in exactly two files — packages/spec/src/api/automation-api.zod.ts:16 and packages/spec/src/api/package-api.zod.ts:19. Measured repo-wide, not just under packages/. That is the completeness bound: there is no third page.
  2. automation-api.zod.ts:16-25 — nine consecutive unfenced rows. Reproduced.
  3. package-api.zod.ts:19-27 — eight, identical shape. Reproduced.
  4. remark-breaks appears nowhere in the repo; apps/docs/source.config.ts adds exactly one remark plugin, remarkMermaid.
  5. content/docs/references/api/odata.mdx fences its listing under the same kind of caption and renders as a block — the positive control.

The defect, measured by a markdown parser rather than asserted

Parsed with the workspace's own mdast-util-from-markdown, the description block of the generated page. Before, the caption and every row are one paragraph node:

automation-api.mdx BEFORE      package-api.mdx BEFORE
  paragraph lines 8-17           paragraph lines 7-15

After, the caption is its own paragraph and the rows are a code node — the same two-node shape the odata control has:

automation-api.mdx AFTER       odata.mdx (control, untouched)
  paragraph lines 8-8            paragraph lines 38-38
  code      lines 9-19           code      lines 39-48

Compiled the rest of the way to HTML and applied the whitespace collapsing a browser performs, the BEFORE listing is one 598-character line reading Endpoints GET /api/automation — List flows GET /api/automation/:name — Get flow POST …, alignment gone. The AFTER is a caption paragraph followed by a preformatted code block that browsers do not collapse.

Not the renderer

renderFileDescription is untouched. It preserves the source's own line layout deliberately, and a renderer-side rule that guessed which prose runs are really tables is exactly the shape-sniffing its header rejects. The generated pages come from pnpm --filter @objectstack/spec gen:docs; neither page was hand-edited, and both carry the AUTO-GENERATED banner.

That claim is not taken on trust. Ablation: with the fix committed, the two fence lines were deleted from the generated page alone, leaving the source fenced. The mutation was proven on disk (fence count 3 to 1; blob hash differs from the HEAD blob) before the gate ran.

leg check:docs evidence
mutated exit 1 names content/docs/references/api/automation-api.mdx (out of date)
restored exit 0 228 generated files in sync with packages/spec

Restoration was proven by hash equality against the HEAD blob and an empty git diff HEAD for that path — not by a checkout's exit code. So the green above is a measurement: the gate is live and would catch a page that is not the generator's own output.

Changeset — both halves, because half 1 alone gives the wrong answer here

Half 1, is the changed path inside files[]? packages/spec's files[] carries src/**/*.zod.ts. Measured with npm pack --dry-run --json rather than read off the glob: the tarball has 1854 entries and both changed paths are among them, with a discriminating control — src/api/automation-api.ts, scripts/build-docs.ts and vitest.config.ts are all absent, so the list is not simply matching everything. YES.

Half 2, is the changed text present in what ships? Packed for real and read back out of the tarball: package/src/api/automation-api.zod.ts contains the fenced listing verbatim, fence lines included. YES — via the src/ copy.

Worth recording that half 2 answers differently for the other shipped tree: the changed text is not in dist/. A module-level docblock does not survive the declaration build — searched the built dist/ for the docblock's own first line Automation API Protocol (absent) against a positive control AutomationFlowPathParamsSchema (present). Had these bytes lived only in dist/, half 2 would have flipped the answer to skip-changeset.

Published content moves, so a changeset is owed: patch, .changeset/fence-api-endpoint-listings.md.

Verification

Every command below was run on this branch and exited 0. Exit codes were captured after redirecting to a file, never through a pipe.

  • Repo-wide lint, not a narrowing. pnpm exec eslint . --no-inline-config --format json — 1m48s, exit 0, 6384 files, 0 errors, 0 warnings, population read from eslint's own config. Both changed .ts files are in it and clean. No .mdx and no changeset .md are in eslint's population.
  • The gate that owns the generated pages. check:docs228 generated files in sync with packages/spec.
  • Package's own suites. pnpm --filter @objectstack/spec test467 test files, 13100 tests, all passed. pnpm --filter @objectstack/spec typecheck — passed, including the test-layer ledger.
  • 47 gate families run in total, all green, derived from the real change set with scripts/pm/dispatch-gates.mjs and reconciled back with --ran. Among them: check:generated, check:authorable-surface, check:api-surface, check:export-origins, check:skill-refs, check:skill-examples, check:yaml-examples, check:llms-txt, check:variant-docs, check:liveness, check:empty-state, check:nul-bytes, check:doc-authoring, check:doc-anchors, check:docs-single-h1, check:docs-audit-scope, check:docs-redirects, check:docs-transcript-drift, check:published-files, check:empty-changeset, check:objectui-changeset, check:adr-0087-registration.
  • Declared narrowing. 46 of the 93 derived families were not run here: 18 are --self-test variants, which grade the checker's own fixtures and are not a PR verdict in either direction, and the remainder are repo-wide families no path in this diff feeds. Those are CI's runs, not this branch's.
  • Three gates first reported non-zero and none was a red. check:generated (exit 1), check:skill-examples (exit 1) and check:docs-transcript-drift (exit 3) each refused to measure against an unbuilt dist — the last says so in as many words, PREREQUISITE NOT MET … NOT a pass and NOT a finding: nothing was measured. check:generated additionally warned that the staleness it reported was a phantom of the unbuilt tree. After building @objectstack/lint and @objectstack/client-react with their dependency closures, all three run and all three pass; check:generated reports nothing stale, confirming the phantom.

gen:schema and both builds wrote no tracked file, which is its own small piece of evidence that this change moves no projection.

Out of scope, deliberately

No other docblock was swept for similar prose runs — the census in premise 1 says there is no third page under this caption, and a wider sweep is a different card with a different justification. This is not rework on #14455, which rewrote the caption above these listings and was ruled to the tag line; that scoping was correct and this is the intended way for the remainder to survive.


Generated by Claude Code

… API docblocks

`api/automation-api` and `api/package-api` captioned a listing with
`@example Endpoints` and then wrote its rows as ordinary prose lines.
Consecutive non-blank lines are one markdown paragraph and the docs site
loads no `remark-breaks`, so each soft break rendered as a space and both
pages published their whole listing as one run-on line with the author's
column alignment collapsed.

Fence both listings at the source, exactly as the neighbouring
`api/odata` and `api/metadata` docblocks already do, and regenerate the
two reference pages. The renderer is not touched: it preserves the
source's own line layout deliberately, and a rule that guessed which
prose runs are really tables is the shape-sniffing its header rejects.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016N6xmWt5hYm94ffVEwGH8x
@github-actions github-actions Bot added the size/s label Sep 8, 2026
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️ 2 changed file(s) yielded no anchor (packages/spec/src/api/automation-api.zod.ts, packages/spec/src/api/package-api.zod.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 2 changed file(s) yielded no anchor (packages/spec/src/api/automation-api.zod.ts, packages/spec/src/api/package-api.zod.ts) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 131 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 97adce2faa9d27d7811f1f299f5ed806a467f624packageMentionDocs.

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

Labels

documentation Improvements or additions to documentation size/s tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs content: api/automation-api and api/package-api publish their endpoint listing as a run-on paragraph — the source writes it unfenced

2 participants