docs(spec): generated reference pages follow the docs title rule, sidebar labels kept via navTitle - #20401
Conversation
Generated reference pages get a PRIMARY-KEYWORD — QUALIFIER title in the 36-46 character band from one ladder per page kind (lib/page-title.ts), and keep their previous title as navTitle so the page tree is unchanged. Claude-Session: https://claude.ai/code/session_01ARcDurZ5j34RdqsGgc4jgH Co-authored-by: Claude <noreply@anthropic.com>
gen:docs output only: every generated reference page's title line is replaced by the rule-shaped title and a navTitle carrying the previous title, so the page tree is unchanged. Claude-Session: https://claude.ai/code/session_01ARcDurZ5j34RdqsGgc4jgH Co-authored-by: Claude <noreply@anthropic.com>
…nerator-title-rule
…ed tree
The merge of origin/main deferred content/docs/references/{data/field,
data/object,shared/value-domain,system/migration}.mdx to regeneration.
Regenerated with gen:schema + gen:docs on the merged sources: main's body
changes plus this branch's title/navTitle lines.
Claude-Session: https://claude.ai/code/session_01ARcDurZ5j34RdqsGgc4jgH
Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
Contract reviewServed-tier: Inputs read: card #15403 body and all 4 comments (serial note 5857122314, unlock 5862577206, claim 5863183456, os-dev-report 5865099529); PR #20401 body and its REST file listing (three pages, 215 files, served without refusal; the git three-dot diff against the merge base ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
…th a Properties table An enum-only module (data/feed) rendered no Properties table yet took the 'property reference' rung. The rung now reads rendersPropertiesTable(), the section renderer's own condition, shared through declaresProperties(); a page without a table starts at the next rung. Pinned in page-title.test.ts, including agreement with renderSchemaSection per schema shape. Claude-Session: https://claude.ai/code/session_01ARcDurZ5j34RdqsGgc4jgH Co-authored-by: Claude <noreply@anthropic.com>
…reference rung gen:docs output only: data/feed renders two enums and no Properties table, so its title drops to the next rung. No other page moves. Claude-Session: https://claude.ai/code/session_01ARcDurZ5j34RdqsGgc4jgH Co-authored-by: Claude <noreply@anthropic.com>
…nerator-title-rule
…tree The merge of origin/main deferred these two generated pages. Regenerated with gen:schema + gen:docs on the merged sources: main's retired-key rows plus this branch's title/navTitle lines. Claude-Session: https://claude.ai/code/session_01ARcDurZ5j34RdqsGgc4jgH Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewServed-tier: Inputs read: card #15403 body and all 6 comments (serial note 5857122314, unlock 5862577206, claim 5863183456, round-0 os-dev-report 5865099529, REWORK round 1 5865474678, round-1 os-dev-report 5866083524); PR #20401 body; its REST file listing (three pages, 100 + 100 + 16 = 216, served without refusal — the git three-dot diff from base ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
…nerator-title-rule
…action on the merged tree The merge of origin/main deferred these three generated pages. Regenerated with gen:schema + gen:docs on the merged sources: main's body changes plus this branch's unchanged title/navTitle lines. Claude-Session: https://claude.ai/code/session_01ARcDurZ5j34RdqsGgc4jgH Co-authored-by: Claude <noreply@anthropic.com>
|
Regen-provenance: 5866297461 ·
Generated by Claude Code |
…nerator-title-rule
The merge of origin/main deferred automation/schemaless-node-config, data/analytics, index, integration/connector and system/auth-config. Regenerated with gen:schema + gen:docs on the merged sources: main's body changes plus this branch's unchanged title/navTitle lines. Claude-Session: https://claude.ai/code/session_01ARcDurZ5j34RdqsGgc4jgH Co-authored-by: Claude <noreply@anthropic.com>
|
Regen-provenance: 5866297461 ·
Generated by Claude Code |
Fixes #15403
Clause-②: no
Summary
The generated reference pages under
content/docs/references/**now carry the docs page-title rule, emitted by the generator itself, and every one keeps its sidebar label byte-identical throughnavTitle.packages/spec/scripts/lib/page-title.ts. It builds each title from data the generator already holds (the module display name and the category's declared title) plus fixed words, picks the longest candidate inside the band, and refuses (never truncates) when no candidate fits.packages/spec/scripts/build-docs.ts, and the root index inpackages/spec/scripts/lib/root-index.ts.navTitle= the page's previoustitle, verbatim, sonavLabel()inapps/docs/lib/nav-title.tsreturns the same string as before. The page tree is unchanged (replayed below, with a control).+2/-1(thetitle:line replaced, anavTitle:line added). Nodescription:, no body, nometa.json.The rule, and how the emitter expresses it
The rule is the maintainer's, recorded on #12237 in comment
5419555720, verbatim 「其他同意」. Its text as landed is the## The rulesection of PR #20170:PRIMARY-KEYWORD — QUALIFIER, separator—;titleis 36–46 characters, so the rendered title with the 14-character| ObjectStacksuffix is 50–60, none over 60;ObjectStacknever inside a title;navTitle, whose fallback totitlelives only innavLabel().The generator holds only the module display name (3–29 characters on this tree), the category's declared title (11–20 for categories with pages) and fixed words. No single template lands every page inside an 11-character band, so each page kind has a short ladder, longest first, and the title is the first candidate inside the band:
NAME schema — CATEGORY property reference, offered only when the page renders a### PropertiestableNAME schema — CATEGORY referenceNAME — CATEGORY referenceNAME — CATEGORYCATEGORY — complete schema referenceCATEGORY — schema referenceProtocol reference — every schema by moduleThe module rungs overlap end to end and cover every name + category length from 7 to 43; the longest pair on the tree is 41 (
Schemaless Node ConfiginAutomation Protocol). The first module rung is conditional:property referenceis offered only when at least one of the page's schemas renders a### Propertiestable (rendersPropertiesTableinlib/schema-section.ts, built ondeclaresProperties, the one expression the section renderer itself branches on). A page without one, such as the enum-onlydata/feed, starts at the second rung; without the first rung the ladder covers name + category lengths 16 to 43, and the shortest property-less pair on the tree is 17 (FeedinData Protocol). The category rungs cover category titles of 8 to 27 characters; the longest declared title is 25. The category in every module title keeps same-named modules apart (Pluginis both akerneland astudiopage). A page no rung fits stopsgen:docswith a message naming the page and every candidate with its length.Rung usage on this tree: module pages 18 / 103 / 60 / 15 (rungs 1–4), category index pages 11 / 3, root index 1. All 18 rung-1 pages render a
### Propertiestable; the 14 module pages that render none are all on rungs 2–4.Measured, before and after
Population re-derived at base
862b6ce8and at head:content/docs/**/*.mdx= 406; pages carrying the generator'sAUTO-GENERATED — DO NOT EDITbanner = 211, all undercontent/docs/references/**(196 module pages, 14 category index pages, 1 root index). Rendered =title+ 14.—ObjectStacknavTitleorigin/main)After: rendered 51–60. Duplicate titles across the whole corpus (406 pages, authored and generated): 0.
The card body's 225 of 405 does not reproduce, and the difference is not generator output. The generated set is 211; the 14 others in that count are
content/docs/releases/**pages, which carry no generator banner and are release-owned (compiled by hand at release time). No other emitter writes atitle:intocontent/docs/**:build-skill-docs.tsrewrites only the region between its markers incontent/docs/ai/skills-reference.mdx, whose authored title already follows the rule (PR #20170). The onlytitle:emissions in the repo's generators are the three this PR changes (git grepoverscripts/,packages/*/scripts/,apps/docs/scripts/).The page tree is unchanged
Replayed with the site's own machinery:
fumadocs-core16.14.4loader()(theapps/docsdependency) with the site'si18nsettings and the site'snavTitlePlugin(), over every.mdxfrontmatter andmeta.jsonundercontent/docs, once fromorigin/mainand once from this head. Serialized page tree (folders, separators, pages, folder index pages): 449 nodes before, 449 after,diffexit 0.Control, so the replay can see a title change at all: the same replay of this head WITHOUT
navTitlePlugin()differs fromorigin/mainin 388 nodes, exactly the 211 generated pages plus the 177 authored pages PR #20170 gave anavTitle.Folder labels come from each category's
meta.jsontitle, which this PR does not touch. The category and rootindex.mdxpages carrynavTitleanyway because the footer previous/next list walks folder index pages.Examples
references/ai/mcp.mdxreferences/ai/agent.mdxreferences/data/feed.mdxreferences/data/object.mdxreferences/automation/flow.mdxreferences/kernel/plugin.mdxreferences/studio/plugin.mdxreferences/kernel/plugin-registry.mdxreferences/kernel/metadata-protection.mdxreferences/ui/expression-bindable-text-keys.mdxreferences/automation/schemaless-node-config.mdxreferences/ai/index.mdxreferences/automation/index.mdxreferences/identity/index.mdxreferences/index.mdxThe complete table is at the end.
Wording for maintainer voice review
The rule is approved; the fixed words the generator adds are new public text and are not in the approved table of PR #12312:
schema,property reference,reference,complete schema reference,schema reference, and the root titleProtocol reference — every schema by module. Rewording any of them is a one-line change inlib/page-title.tsplusgen:docs; the band, the unit test andcheck:docshold the result either way. Non-blocking: the seat answered land-as-shipped in comment 5865474678 on #15403, andproperty referenceis now claimed only by pages that render a property table.File surface
packages/spec/scripts/lib/page-title.ts(new): the rule, the ladders, the refusal, the frontmatter lines.packages/spec/scripts/page-title.test.ts(new): the pin (localvitest project; reads nothing outside the package).packages/spec/scripts/build-docs.ts: the two emission sites (module pages, category index pages), located by symbol.packages/spec/scripts/lib/schema-section.ts:declaresProperties()(an object that declares properties, the one spelling of that condition, now also used by the renderer's root and union-arm branches) andrendersPropertiesTable()(whether a schema renders at least one### Propertiestable), read by the module-page title. Rendered output unchanged: regenerating moved exactly one page,data/feed.mdx, and only itstitle:line.packages/spec/scripts/lib/root-index.ts: one site beyond the two the dispatch named. It is the generator's thirdtitle:emission (the rootreferences/index.mdx, previouslytitle: Protocol Reference, 18 characters). Leaving it would have left one generated page outside the rule.content/docs/references/**: 211 pages, regenerated bygen:docs, never hand-edited.description:emission,check-generated.ts(it regenerates and compares; nothing in it reads the title line),build-skill-docs.ts(emits no title).Changeset:
skip-changesetRule applied: a changeset is owed when a package's published
files[]content moves.@objectstack/specpublishesdist,json-schema,liveness,prompts,llms.txt,README.md,src/**/*.zod.ts,CHANGELOG.md,api-surface,spec-changes.json;scripts/is not among them, andapps/docs(which renderscontent/docs) is private. Measured after the build: the new symbols (titleFrontmatter,navTitle,property reference) have 0 hits across all ten of those paths, while the positive controlObjectSchemahits in 9 of the 10 (all butjson-schema).Verification
Head
1ba9d84c, REWORK round 1:41b0f683(the conditional rung),0ea42f45(data/feed.mdxregenerated), then a merge oforigin/mainatdf3ba164whose two deferred pages,security/{permission,rls}.mdx, were regenerated on the merged tree in1ba9d84c. Round 0 was heada61335f9.pnpm --filter @objectstack/spec test: 561 files, 16546 passed, 1 todo.pnpm --filter @objectstack/spec test:repo: 35 files, 634 passed.check:scripts-typecheck(tsc -p tsconfig.scripts.json, the program holding every file this diff edits,page-title.test.tsincluded) exit 0 at1ba9d84c. The full spectypecheckwas green locally at round 0's pre-merge head0a241893, andType Check · workspaceran it green in CI ona61335f9.tsc -p tsconfig.scripts.json --listFileslistslib/page-title.tsandpage-title.test.ts).node scripts/pm/dispatch-gates.mjs --commandsover this diff at1ba9d84c(216 paths, the same 89 families as round 0), each exit code recorded, then--ran: 89 derived, 85 run (all exit 0), 4 NOT MEASURED, 0 UNRUN. Among the 85:check:docs,check:generated(all 15 generated artifacts up to date),check:doc-frontmatter,check:docs-single-h1,check:doc-anchors,check:nul-bytes,check:quick-reference-counts.check:skill-examples(needs the 36-package@objectstack/client-reactclosure built),check:dual-build-cjs-loads(needs every package built),check:type-check-debt(needs a 30-package closure built).check:pm-dispatch-gates. Its self-test ofscripts/pm/dispatch-gates.mjs, which this diff does not edit, did not finish in a 420 s and then a 560 s window on the shared box. Not re-run in round 1;Lint & Repo Gatesran it green in CI ona61335f9.scripts/ablation-replace.mjschangedTITLE_MAX = 46to60inlib/page-title.ts(anchor 1 to 0, blob3fe85286f82dtoee55509927c8).page-title.test.tswent 12 failed / 13 passed. Restored under an EXIT/INT/TERM trap to3fe85286f82d= HEAD blob,git diff HEADempty.check:docssees the emission: the first module rung'sproperty referencechanged tofield reference(blob3fe85286f82dtob8f4c6d26269).check:docsexited 1 with 49 pages out of date: the 19 rung-1 pages, plus the pages the shorter word lets onto rung 1. Restored the same way....(documentsProperties ? [changed to...(true ? [inlib/page-title.ts(anchor 1 to 0, blob38277b23f728to90e0cbe18d3b).page-title.test.tswent 3 failed / 38 passed: thedata/feedrow, the condition pin, and the short property-less refusal. Restored to38277b23f728= HEAD blob,git diff HEADempty.packages/spec/json-schema/,rendersPropertiesTable(name, schema)equals whetherrenderSchemaSection(name, schema)emits a### Propertiesheading: 1219 true, 0 disagreements. The unit pin holds the same agreement shape by shape (11 JSON Schema shapes covering every renderer branch).Acceptance notes
Mcp,Rls,Scim,Odata,Http,I18n,Driver Sql,Cli Extension,Io Node Config,Bpmn Interop,Package Api,Rest Server,Events Dlq, and others. This is theQa Protocoldefect class thatlib/category-title.tsfixed for category titles, one level down, and it predates this PR (these strings were the whole title before; they are thenavTitlenow, and the primary keyword of the new title). Out of scope here: fixing it changes nav labels, which this card keeps byte-identical. Noted, not filed.releases/**pages (see Measured); nothing here depends on them.api/protocol.mdxrenders 6### Propertiestables with no rows (object schemas declaring an emptyproperties). Pre-existing renderer output; that page is on rung 2 and carries non-empty tables as well. Noted, not filed.rootIndexTitle()throughpageTitleOrExitwas not taken:pageTitleOrExitlives inbuild-docs.ts, so routing it means passing the title intorenderRootIndex(its input type and theroot-index.test.tsfixtures), more than one line. The root title is a fixed 43-character string pinned by the unit test.The complete table
All 211 generated pages.
navTitle= before, verbatim, on every row.navTitlereferences/index.mdxreferences/ai/index.mdxreferences/ai/agent.mdxreferences/ai/build-progress.mdxreferences/ai/conversation.mdxreferences/ai/embedding.mdxreferences/ai/knowledge-document.mdxreferences/ai/knowledge-source.mdxreferences/ai/mcp.mdxreferences/ai/model-registry.mdxreferences/ai/skill.mdxreferences/ai/solution-blueprint.mdxreferences/ai/tool.mdxreferences/ai/usage.mdxreferences/api/index.mdxreferences/api/analytics.mdxreferences/api/auth-endpoints.mdxreferences/api/auth.mdxreferences/api/automation-api.mdxreferences/api/batch.mdxreferences/api/contract.mdxreferences/api/discovery.mdxreferences/api/dispatcher.mdxreferences/api/documentation.mdxreferences/api/endpoint.mdxreferences/api/error-code-ledger.mdxreferences/api/errors.mdxreferences/api/events.mdxreferences/api/export.mdxreferences/api/http-cache.mdxreferences/api/metadata.mdxreferences/api/misc.mdxreferences/api/odata.mdxreferences/api/package-api-assembled.mdxreferences/api/package-api.mdxreferences/api/package-lifecycle.mdxreferences/api/plugin-rest-api.mdxreferences/api/protocol.mdxreferences/api/query-adapter.mdxreferences/api/realtime-shared.mdxreferences/api/realtime.mdxreferences/api/rest-server.mdxreferences/api/router.mdxreferences/api/sortability.mdxreferences/api/storage.mdxreferences/api/versioning.mdxreferences/api/websocket.mdxreferences/automation/index.mdxreferences/automation/approval.mdxreferences/automation/bpmn-interop.mdxreferences/automation/builtin-node-config.mdxreferences/automation/control-flow.mdxreferences/automation/execution.mdxreferences/automation/flow-function.mdxreferences/automation/flow.mdxreferences/automation/io-node-config.mdxreferences/automation/node-executor.mdxreferences/automation/schedule-organization.mdxreferences/automation/schemaless-node-config.mdxreferences/automation/state-machine.mdxreferences/automation/time-relative-trigger.mdxreferences/automation/webhook.mdxreferences/data/index.mdxreferences/data/analytics.mdxreferences/data/context-tokens.mdxreferences/data/data-engine.mdxreferences/data/datasource.mdxreferences/data/date-macros.mdxreferences/data/document.mdxreferences/data/driver-common.mdxreferences/data/driver-memory.mdxreferences/data/driver-mongo.mdxreferences/data/driver-mysql.mdxreferences/data/driver-nosql.mdxreferences/data/driver-postgres.mdxreferences/data/driver-sql.mdxreferences/data/driver-sqlite.mdxreferences/data/driver-turso.mdxreferences/data/driver.mdxreferences/data/external-catalog.mdxreferences/data/feed.mdxreferences/data/field-value.mdxreferences/data/field.mdxreferences/data/filter.mdxreferences/data/hook-body.mdxreferences/data/hook.mdxreferences/data/mapping.mdxreferences/data/object.mdxreferences/data/query.mdxreferences/data/seed-loader.mdxreferences/data/seed.mdxreferences/data/validation.mdxreferences/identity/index.mdxreferences/identity/eval-user.mdxreferences/identity/identity.mdxreferences/identity/organization.mdxreferences/identity/position.mdxreferences/identity/scim.mdxreferences/integration/index.mdxreferences/integration/connector.mdxreferences/kernel/index.mdxreferences/kernel/cli-extension.mdxreferences/kernel/cluster.mdxreferences/kernel/context.mdxreferences/kernel/dependency-resolution.mdxreferences/kernel/events-bus.mdxreferences/kernel/events-core.mdxreferences/kernel/events-dlq.mdxreferences/kernel/events-handlers.mdxreferences/kernel/events-integrations.mdxreferences/kernel/events-queue.mdxreferences/kernel/execution-context.mdxreferences/kernel/manifest.mdxreferences/kernel/metadata-loader.mdxreferences/kernel/metadata-plugin.mdxreferences/kernel/metadata-protection.mdxreferences/kernel/package-artifact.mdxreferences/kernel/package-registry.mdxreferences/kernel/package-upgrade.mdxreferences/kernel/plugin-capability.mdxreferences/kernel/plugin-lifecycle-advanced.mdxreferences/kernel/plugin-loading.mdxreferences/kernel/plugin-registry.mdxreferences/kernel/plugin-security-advanced.mdxreferences/kernel/plugin-security.mdxreferences/kernel/plugin-structure.mdxreferences/kernel/plugin-validator.mdxreferences/kernel/plugin-versioning.mdxreferences/kernel/plugin.mdxreferences/kernel/service-registry.mdxreferences/kernel/startup-orchestrator.mdxreferences/marketplace/index.mdxreferences/marketplace/marketplace.mdxreferences/marketplace/package-version.mdxreferences/marketplace/package.mdxreferences/marketplace/template-manifest.mdxreferences/qa/index.mdxreferences/qa/testing.mdxreferences/security/index.mdxreferences/security/explain.mdxreferences/security/misc.mdxreferences/security/permission.mdxreferences/security/rls.mdxreferences/security/sharing.mdxreferences/shared/index.mdxreferences/shared/duration.mdxreferences/shared/enums.mdxreferences/shared/epoch.mdxreferences/shared/expression.mdxreferences/shared/http.mdxreferences/shared/identifiers.mdxreferences/shared/mapping.mdxreferences/shared/metadata-types.mdxreferences/shared/protection.mdxreferences/shared/value-domain.mdxreferences/studio/index.mdxreferences/studio/flow-builder.mdxreferences/studio/object-designer.mdxreferences/studio/plugin.mdxreferences/system/index.mdxreferences/system/app-install.mdxreferences/system/auth-config.mdxreferences/system/book.mdxreferences/system/cache.mdxreferences/system/collaboration.mdxreferences/system/core-services.mdxreferences/system/deploy-bundle.mdxreferences/system/dev-login.mdxreferences/system/disaster-recovery.mdxreferences/system/doc.mdxreferences/system/email-config.mdxreferences/system/email-template.mdxreferences/system/encryption.mdxreferences/system/environment-artifact.mdxreferences/system/http-server.mdxreferences/system/job.mdxreferences/system/license.mdxreferences/system/logging.mdxreferences/system/metadata-persistence.mdxreferences/system/metrics.mdxreferences/system/migration.mdxreferences/system/notification.mdxreferences/system/object-storage.mdxreferences/system/registry-config.mdxreferences/system/search-engine.mdxreferences/system/security-context.mdxreferences/system/settings-client.mdxreferences/system/settings-manifest.mdxreferences/system/stack-server.mdxreferences/system/supplier-security.mdxreferences/system/tenant.mdxreferences/system/tracing.mdxreferences/system/translation.mdxreferences/system/worker.mdxreferences/ui/index.mdxreferences/ui/action-params.mdxreferences/ui/action.mdxreferences/ui/app.mdxreferences/ui/bulk-action.mdxreferences/ui/chart.mdxreferences/ui/component.mdxreferences/ui/dashboard.mdxreferences/ui/dataset.mdxreferences/ui/expression-bindable-text-keys.mdxreferences/ui/i18n.mdxreferences/ui/notification.mdxreferences/ui/page.mdxreferences/ui/report.mdxreferences/ui/responsive.mdxreferences/ui/sharing.mdxreferences/ui/view.mdxGenerated by Claude Code