Repository navigation
Commit 5983d11
docs(content): apply the approved search-intent title rule to 169 authored pages, short nav labels kept via navTitle (#20170)
Fixes #12237
Clause-②: no
## Summary
Applies the maintainer-approved page-title rule to the authored docs
pages that still carried their pre-rule title, and keeps every
navigation label exactly as it was through `navTitle`.
- **175 approved rows applied verbatim** from the table in PR #12312,
each with a `navTitle:` line holding the page's previous title.
- **1 approved row re-worded** because a required gate rejects the
approved text (`check:role-word`), and **1 authored page the table never
listed** authored per the rule. Both are listed under *Needs maintainer
voice review* below.
- **One gate premise moved, not loosened:**
`check:runtime-services-index` used to hold each
`kernel/runtime-services/NAME-service.mdx` to `title: services.NAME`. It
now reads that accessor premise from the page's `navTitle`, so the
chapter's 8 approved titles land verbatim with `navTitle:
services.NAME`. See *The runtime-services gate* below. (PM answer to the
round-1 open question, review comment `5852831074` on #12237.)
- 177 docs files, frontmatter only: every one is `+2/-1` (`title:`
replaced, `navTitle:` added). No `description:`, no page body, nothing
under `references/**` or `releases/**`, nothing in `apps/docs/**` or any
`meta.json`. Plus one gate script,
`scripts/check-runtime-services-index.mjs` (file surface amended by the
seat for this round).
⛔ **Draft, and it stays open for maintainer review — do not self-merge**
(card body). The landing path after review is the seat's call.
## The rule
```
PRIMARY-KEYWORD — QUALIFIER
```
- The frontmatter `title:` string is **36–46 characters**, so the
rendered title with the 14-character ` | ObjectStack` suffix lands in
**50–60**; no rendered title over 60. (PM ruling on the card, comment
`5414218147`, Q2: the band is authoritative.)
- Separator ` — ` throughout; `ObjectStack` never inside a title,
because the suffix carries it; one declared exception,
`getting-started/index.mdx` keeps `What is ObjectStack?`. (Maintainer
ruling recorded in comment `5419555720`, verbatim: 「其他同意」 — the rule and
the full before/after table in PR #12312 approved as they stand.)
- Scope: authored pages only. The generator-emitted pages are #15403
(`domain:spec`), per the triage split in comment `5541938216`.
- Short navigation labels: `navTitle` (landed with PR #14055). The
fallback to `title` lives only in `navLabel()` in
`apps/docs/lib/nav-title.ts`.
## What changes on the site, and what does not
Measured in `apps/docs` at this head. A page's `title` is read at **12
read points on 5 faces**, plus the site search index. All of these take
the longer title:
| face | read points |
|---|---|
| SERP / Open Graph / Twitter metadata |
`app/[lang]/docs/[[...slug]]/page.tsx` `generateMetadata`: `title`
(232), `openGraph.title` (237), OG image `alt` (248), `twitter.title`
(254) |
| on-page h1 | `page.tsx:171` `DocsTitle` |
| JSON-LD | `TechArticle` `headline` and `name` (`page.tsx:144,145`);
the `BreadcrumbList` leaf crumb (`page.tsx:116`) |
| `llms.txt` / `llms-full.txt` / `/llms.mdx/docs/…` |
`app/llms.txt/route.ts:10`; `lib/source.ts:66` `getLLMText` |
| Open Graph card image | `app/og/docs/[...slug]/route.tsx:18` |
| site search results | `app/api/search/route.ts`,
`createFromSource(source)` (fumadocs indexes `page.data.title`) |
**Unchanged, by construction:** the page tree, i.e. the sidebar entries
and the footer previous/next links. Every page this PR lengthens is a
page-tree node, and each one declares `navTitle:` with its previous
title verbatim (same YAML quoting), so `navLabel()` returns the old
string.
How "page-tree node" was measured, not guessed: replaying fumadocs-core
16.14.4 `buildFolder()` over every `meta.json` (all 19 authored
`meta.json` list `pages` explicitly, none uses a rest entry, none lists
`index`) gives **180 of 181 authored pages in the tree**: 162 sidebar
leaves and 18 folder index pages. A folder index page is not a sidebar
row (its folder label comes from `meta.json` `title`), but
`flattenTree()` puts `folder.index` into the footer previous/next list,
so it needs `navTitle` too. The one authored page outside the tree is
`content/docs/index.mdx`, the global root (landed by #12312, not touched
here).
The JSON-LD breadcrumb does not pick up the short label: `docsTrail()`
calls `getBreadcrumbItems(…, { includePage: false })` and pushes
`page.data.title` itself, pinned by leg D of
`scripts/check-docs-nav-label.mjs` (run green below).
## Statistics, re-derived
Population: every `content/docs/**/*.mdx` outside `references/**` and
`releases/**`, **181 pages**. Rendered length = `title` + 14. Base
`84880f9`, head `c69d5c7`.
| | pages | median | min | max | in 50–60 | over 60 | under 50 |
duplicate titles | `navTitle` declared |
|---|--:|--:|--:|--:|--:|--:|--:|--:|--:|
| before | 181 | 32 | 19 | 56 | 6 | 0 | 175 | 0 | 0 |
| after | 181 | 54 | 50 | 60 | 181 | 0 | 0 | 0 | 177 |
Duplicates were also checked against the 225 generated `references/**` +
`releases/**` titles: no new title collides with any page.
**Premise check on the approved table** (PR #12312 body, section 6): it
parses to **180 rows** — 4 landed with #12312 and **176 not landed**. On
base `84880f9`, **176 of 176** pages still carry exactly the table's
*before*, **0** carry its *after*, **0** paths are missing. The
generated-page test reads the file head for a marker, never prose: no
authored page carries one (the nine prose hits of the word "generated"
in a page head, e.g. `api/index.mdx`, `ui/index.mdx`, are body text).
One authored page is absent from the table:
`permissions/tenant-audit-census.mdx` (added after #12312; its
frontmatter is authored, only a body region is generated by
`scripts/tenant-audit-census.mjs`).
## Needs maintainer voice review — not covered by the approved table
Every row here is **applied in this diff**.
| page | before | approved *after* | applied | rendered | why |
|---|---|---|---|--:|---|
| `permissions/administrator-guide.mdx` | Administrator Guide |
Administrator guide to permissions and roles | **Administrator guide to
permissions and access** | 59 | the approved text fails the required
`check:role-word` gate: "role" is a reserved word (ADR-0090 D3).
Smallest change that clears it. |
| `permissions/tenant-audit-census.mdx` | Tenant-Audit Census | — (page
not in the table) | **Tenant-audit census — tenancy write call sites** |
60 | authored page the table never listed; written per the rule.
`navTitle: Tenant-Audit Census`. |
## The runtime-services gate
`scripts/check-runtime-services-index.mjs` checks first that each
chapter page declares the accessor its filename claims; the other five
enumerations rest on that premise. It used to read `title`. The title
rule lengthens `title` for the search-facing surfaces, so the premise
now reads `navTitle`, which is the page-tree label and, on these 8
pages, the bare accessor.
- Read from the page's **leading frontmatter block only**; one layer of
matching YAML quotes is syntax, not value. The `title` is not read at
all.
- Still red: `navTitle` absent, blank, present only in the body, or not
`services.NAME`. A page that still says `title: services.NAME` with no
`navTitle` is red too. Each finding names the fix (`add \`navTitle:
services.sms\` to the page's leading frontmatter block`).
- The header prose that stated the `title:` premise is rewritten to say
what the gate now does and why.
- `--self-test`: new floored battery *The accessor premise lives in
navTitle*, 7 cases (absent, wrong, old title-only spelling, body-only
line and blank are red; a long title and a quoted value are green).
Roster floor 8 to 9. The fixture's default `title` is now a long
search-intent string, so every existing green case is also a green with
a long title. 59 assertions.
- **Ablation, trapped:** `scripts/ablation-replace.mjs` set `navTitle:
services.sms` to `navTitle: services.text` in `sms-service.mdx` (anchor
1 to 0, blob `2001694b2859` to `67f9af393d4d`). The gate exited **1**:
`frontmatter navTitle is "services.text", expected "services.sms" to
match the filename -- set \`navTitle: services.sms\`, or rename the page
if the accessor really changed`. Restored under an EXIT/INT/TERM trap to
blob `2001694b2859`, which equals HEAD; `git diff HEAD` empty.
- The live tree before the 8 pages were edited: the new gate went red
with exactly 8 `declares no navTitle` findings.
**Other readers of these pages' `title`** (`git grep` over `scripts/`,
`packages/`, `apps/docs`, `.github/`, `content/docs`): no other gate or
script parses it. `apps/docs` reads it generically through
`page.data.title`, which is the intended change.
`content/docs/kernel/index.mdx` names the accessors in its services
table and does not read the page titles. One piece of stale prose: the
header of `scripts/check-docs-single-h1.mjs` (lines 72-73) uses
`audit-service.mdx` `title: services.audit` as a worked example. Its
logic is unaffected and it is green, but the example no longer matches
the page. That file is outside this PR's surface, so it is noted here
and not edited.
## The complete table
All 177 authored pages this PR changes. Rendered = `title` + ` |
ObjectStack`. `navTitle` = the page's previous title, declared verbatim.
✳️ = in the review section above.
| page | before | after | rendered | `navTitle` |
|---|---|---|--:|:-:|
| `ai/actions-as-tools.mdx` | Actions as Tools | MCP tools — expose
actions to AI agents | 53 | yes |
| `ai/agents.mdx` | AI Agents | AI agents — declare tools, model and
prompt | 57 | yes |
| `ai/connect-mcp.mdx` | Connect an MCP Client | MCP client setup —
Claude, Cursor and IDEs | 56 | yes |
| `ai/index.mdx` | AI Overview | AI features — MCP tools, agents and RAG
| 53 | yes |
| `ai/knowledge-rag.mdx` | Knowledge & RAG | RAG — embeddings and
knowledge retrieval | 54 | yes |
| `ai/natural-language-queries.mdx` | Natural Language Queries | Natural
language queries over your data | 53 | yes |
| `ai/skills-reference.mdx` | AI Skills Reference | AI skill reference —
every field explained | 56 | yes |
| `ai/skills.mdx` | AI Skills System | AI skills — reusable instructions
for agents | 58 | yes |
| `ai/tools.mdx` | Tool Records | Tool records — govern what an agent
may call | 58 | yes |
| `api/client-sdk.mdx` | Client SDK | Client SDK — typed JavaScript data
access | 55 | yes |
| `api/data-api.mdx` | Data API | REST data API — CRUD over every object
| 52 | yes |
| `api/data-flow.mdx` | Data Flow Diagrams | Request data flow — from
HTTP to driver | 53 | yes |
| `api/declarative-endpoints.mdx` | Declarative Endpoints | Custom
endpoints declared as metadata | 51 | yes |
| `api/environment-routing.mdx` | Environment-Scoped Routing |
Environment routing — dev, preview, prod | 54 | yes |
| `api/error-catalog.mdx` | Error Code Catalog | API error codes — the
complete catalog | 52 | yes |
| `api/error-handling-client.mdx` | Client-Side Error Handling | Client
error handling — retries and codes | 55 | yes |
| `api/error-handling-server.mdx` | Server-Side Error Handling | Server
error handling — throw the envelope | 56 | yes |
| `api/index.mdx` | API Overview | REST and GraphQL APIs — generated per
object | 58 | yes |
| `api/metadata-api.mdx` | Metadata & Package API | Metadata API — read
and publish packages | 54 | yes |
| `api/plugin-endpoints.mdx` | Plugin Endpoints | Plugin endpoints — add
routes from a plugin | 57 | yes |
| `api/wire-format.mdx` | Wire Format & JSON Examples | API wire format
— request and response JSON | 57 | yes |
| `automation/approvals.mdx` | Approval workflow | Approval chains —
multi-step sign-off rules | 57 | yes |
| `automation/connectors.mdx` | Connectors | Connectors — call external
systems safely | 55 | yes |
| `automation/email-templates.mdx` | Email Templates | Email templates —
merge fields and layouts | 56 | yes |
| `automation/flows.mdx` | Flow Metadata | Flows — DAG automation as
typed metadata | 54 | yes |
| `automation/hook-bodies.mdx` | Hook & Action Bodies (L1 / L2) | Hook
and action bodies — the L1/L2 rules | 54 | yes |
| `automation/hooks.mdx` | Hooks | Record hooks — beforeInsert to
afterDelete | 56 | yes |
| `automation/index.mdx` | Automation | Automation — flows, triggers and
schedules | 56 | yes |
| `automation/jobs.mdx` | Scheduled Jobs | Scheduled jobs — cron
automation metadata | 55 | yes |
| `automation/webhooks.mdx` | Webhook Delivery | Webhooks — outbound
delivery and retries | 54 | yes |
| `automation/workflows.mdx` | Workflow Metadata | Workflow rules —
declarative record logic | 55 | yes |
| `build-without-code.mdx` | Build Without Code | Build business apps
without writing code | 54 | yes |
| `capabilities/ai.mdx` | AI Under Governance | AI under governance —
permissioned agents | 55 | yes |
| `capabilities/analytics.mdx` | Analytics & Dashboards | Analytics —
dashboards, reports and charts | 56 | yes |
| `capabilities/approvals.mdx` | Approvals | Approvals — routing, queues
and audit trail | 57 | yes |
| `capabilities/automation.mdx` | Automation — Processes That Run
Themselves | Automation — processes that run themselves | 56 | yes |
| `capabilities/data.mdx` | Manage Business Data | Business data —
objects, fields and records | 57 | yes |
| `capabilities/forms.mdx` | Forms & Data Quality | Forms and data
quality — validation rules | 55 | yes |
| `capabilities/index.mdx` | What Can It Do? | What can it do? — the
capability overview | 55 | yes |
| `capabilities/integrations.mdx` | Integrations & Everyday Work |
Integrations — email, files and everyday work | 59 | yes |
| `capabilities/permissions.mdx` | Permissions — Who Sees What |
Permissions — who sees what, enforced | 51 | yes |
| `capabilities/request-template.mdx` | How to Request Features |
Request a feature — how to describe it | 52 | yes |
| `capabilities/views.mdx` | Views — See Data Your Way | Views — lists,
kanban, calendar and gantt | 55 | yes |
| `concepts/architecture.mdx` | Protocol Architecture | Protocol
architecture — the four layers | 53 | yes |
| `concepts/design-principles.mdx` | Design Principles | Design
principles behind the metadata spec | 56 | yes |
| `concepts/index.mdx` | Core Concepts | Core concepts — metadata,
runtime, protocol | 57 | yes |
| `concepts/metadata-driven.mdx` | Metadata-Driven Development |
Metadata-driven development explained | 51 | yes |
| `concepts/metadata-lifecycle.mdx` | Metadata Lifecycle & HMR |
Metadata lifecycle — load, publish and HMR | 56 | yes |
| `concepts/north-star.mdx` | North Star | North star — why this
framework exists | 52 | yes |
| `data-modeling/analytics.mdx` | Analytics Datasets | Analytics
datasets — modelling for reports | 56 | yes |
| `data-modeling/drivers.mdx` | Database Drivers | Database drivers —
Postgres, MySQL, Mongo | 55 | yes |
| `data-modeling/external-datasources.mdx` | External Datasources
(Federation) | External datasources — query without ETL | 54 | yes |
| `data-modeling/field-type-decision-tree.mdx` | Field Type Decision
Tree | Which field type should I use? A decision tree | 60 | yes |
| `data-modeling/field-types.mdx` | Field Type Gallery | Field types —
the complete visual gallery | 55 | yes |
| `data-modeling/fields.mdx` | Field Metadata | Field metadata — every
option explained | 53 | yes |
| `data-modeling/formulas.mdx` | Expressions (CEL) | Formulas — CEL
expressions on records | 51 | yes |
| `data-modeling/import-mappings.mdx` | Import Mappings | Import
mappings — load external data files | 56 | yes |
| `data-modeling/index.mdx` | Data Modeling | Data modelling — objects,
fields, relations | 57 | yes |
| `data-modeling/indexing.mdx` | Database Indexing | Database indexes —
declare and tune them | 54 | yes |
| `data-modeling/object-extensions.mdx` | Object Extensions | Object
extensions — extend without forking | 56 | yes |
| `data-modeling/objects.mdx` | Object Metadata | Object metadata —
define your data schema | 55 | yes |
| `data-modeling/queries.mdx` | Query Syntax Cheat Sheet | ObjectQL
query syntax — a cheat sheet | 51 | yes |
| `data-modeling/relationships.mdx` | Relationships & Lookups |
Relationships — lookups, master-detail | 52 | yes |
| `data-modeling/schema-design.mdx` | Schema Design | Schema design —
model a business domain | 53 | yes |
| `data-modeling/seed-data.mdx` | Seed Data & Fixtures | Seed data —
fixtures and demo datasets | 52 | yes |
| `data-modeling/validation-rules.mdx` | Field Validation Rules |
Validation rules — reject bad records | 51 | yes |
| `data-modeling/validation.mdx` | Validation Metadata | Validation
metadata — declare the checks | 54 | yes |
| `deployment/backup-restore.mdx` | Backup & Restore | Backup and
restore — protect tenant data | 54 | yes |
| `deployment/cli.mdx` | Command Line Interface | Command line interface
— the os CLI reference | 59 | yes |
| `deployment/environment-variables.mdx` | Environment Variables |
Environment variables — the full list | 51 | yes |
| `deployment/index.mdx` | Deployment Overview | Deployment — ship a
runtime to production | 55 | yes |
| `deployment/production-readiness.mdx` | Production Readiness |
Production readiness — the go-live list | 53 | yes |
| `deployment/publish-and-preview.mdx` | Publish, Versioning & Preview |
Publish, versioning and preview builds | 52 | yes |
| `deployment/seed-tenancy-repair.mdx` | Seed Tenancy Repair | Repair
seed tenancy after a bad import | 52 | yes |
| `deployment/self-hosting.mdx` | Self-Hosted Deployment | Self-hosting
— run your own deployment | 52 | yes |
| `deployment/single-project-mode.mdx` | Single-Environment Mode |
Single-environment mode — the simple setup | 56 | yes |
| `deployment/tenancy-modes.mdx` | Tenancy Postures & Membership |
Tenancy postures and membership models | 52 | yes |
| `deployment/troubleshooting.mdx` | Troubleshooting & FAQ |
Troubleshooting — common errors and fixes | 55 | yes |
| `deployment/validating-metadata.mdx` | Validating Metadata | Validate
metadata before you deploy it | 52 | yes |
| `getting-started/build-with-claude-code.mdx` | Build with Claude Code
| Build an app with Claude Code, step by step | 57 | yes |
| `getting-started/common-patterns.mdx` | Common Patterns | Common
patterns — proven metadata recipes | 55 | yes |
| `getting-started/examples.mdx` | Example Apps | Example apps — CRM,
showcase and more | 51 | yes |
| `getting-started/glossary.mdx` | Glossary | Glossary — every metadata
term defined | 52 | yes |
| `getting-started/how-ai-development-works.mdx` | How AI Development
Works | How AI-written app development works | 50 | yes |
| `getting-started/index.mdx` | What is ObjectStack? | What is
ObjectStack? — a 5-minute intro | 53 | yes |
| `getting-started/quick-reference.mdx` | Quick Reference Guide | Quick
reference — every metadata type | 51 | yes |
| `getting-started/quick-start.mdx` | Anatomy of an ObjectStack App |
Anatomy of an app — your first metadata | 53 | yes |
| `getting-started/your-first-project.mdx` | Your First Project | Your
first project — from zero to running | 55 | yes |
| `kernel/architecture.mdx` | Architecture | Core architecture — kernel
and services | 53 | yes |
| `kernel/cluster.mdx` | Cluster Semantics | Cluster semantics —
multi-node runtimes | 53 | yes |
| `kernel/contracts/auth-service.mdx` | IAuthService Contract |
IAuthService — the authentication contract | 56 | yes |
| `kernel/contracts/cache-service.mdx` | ICacheService Contract |
ICacheService — the cache service contract | 56 | yes |
| `kernel/contracts/data-engine.mdx` | IDataEngine Contract |
IDataEngine — the storage driver contract | 55 | yes |
| `kernel/contracts/index.mdx` | Service Contracts Overview | Service
contracts — the kernel interfaces | 55 | yes |
| `kernel/contracts/metadata-service.mdx` | IMetadataService Contract |
IMetadataService — the metadata contract | 54 | yes |
| `kernel/contracts/storage-service.mdx` | IStorageService Contract |
IStorageService — the file storage contract | 57 | yes |
| `kernel/events.mdx` | Events & Hooks | Kernel events and hooks — the
full list | 53 | yes |
| `kernel/index.mdx` | Kernel & Services | Kernel and services — the
runtime core | 52 | yes |
| `kernel/runtime-services/audit-service.mdx` | services.audit |
services.audit — the audit log service API | 56 | yes |
| `kernel/runtime-services/data-service.mdx` | services.data |
services.data — the record CRUD service API | 57 | yes |
| `kernel/runtime-services/email-service.mdx` | services.email |
services.email — the outbound mail API | 52 | yes |
| `kernel/runtime-services/examples.mdx` | Runtime Service Examples |
Runtime service examples — copyable code | 54 | yes |
| `kernel/runtime-services/index.mdx` | Runtime Service APIs | Runtime
service APIs — the services object | 56 | yes |
| `kernel/runtime-services/queue-service.mdx` | services.queue |
services.queue — the job queue service API | 56 | yes |
| `kernel/runtime-services/settings-service.mdx` | services.settings |
services.settings — the settings API | 50 | yes |
| `kernel/runtime-services/sharing-service.mdx` | services.sharing |
services.sharing — the record share API | 53 | yes |
| `kernel/runtime-services/sms-service.mdx` | services.sms |
services.sms — the text message service API | 57 | yes |
| `kernel/runtime-services/storage-service.mdx` | services.storage |
services.storage — the file store API | 51 | yes |
| `kernel/runtime-services/versioning.mdx` | Runtime Service API
Versioning | Runtime service API versioning policy | 51 | yes |
| `kernel/services-checklist.mdx` | Kernel Services Checklist | Kernel
services checklist for reviewers | 53 | yes |
| `kernel/services.mdx` | Service Registry | Service registry — resolve
and override | 53 | yes |
| `permissions/access-matrix.mdx` | Access-Matrix Snapshot Gate | Access
matrix snapshot gate explained | 51 | yes |
| `permissions/access-recipes.mdx` | Who can see data / automation /
interface | Access recipes — data, automation and UI | 54 | yes |
| `permissions/administrator-guide.mdx` ✳️ | Administrator Guide |
Administrator guide to permissions and access | 59 | yes |
| `permissions/attachments-access.mdx` | Attachments Access | Attachment
access — who can read a file | 53 | yes |
| `permissions/authentication.mdx` | Authentication | Authentication —
sessions, tokens, SSO | 52 | yes |
| `permissions/authorization.mdx` | Authorization Architecture |
Authorization architecture — how it decides | 57 | yes |
| `permissions/capabilities.mdx` | Declaring Capabilities | Declaring
capabilities in a permission set | 56 | yes |
| `permissions/delegated-administration.mdx` | Delegated Administration
| Delegated administration — scoped admin rights | 60 | yes |
| `permissions/explain.mdx` | Explain Engine | Explain engine — why
access was denied | 52 | yes |
| `permissions/field-level-security.mdx` | Field-Level Security |
Field-level security — hide and mask fields | 57 | yes |
| `permissions/index.mdx` | Permissions & Identity | Permissions and
identity — the overview | 53 | yes |
| `permissions/permission-metadata.mdx` | Permission Metadata |
Permission metadata — every option explained | 58 | yes |
| `permissions/permission-sets.mdx` | Permission Sets | Permission sets
— grant access in bundles | 55 | yes |
| `permissions/permissions-matrix.mdx` | Security Permissions Matrix |
Security permissions matrix reference | 51 | yes |
| `permissions/positions.mdx` | Positions | Positions — org hierarchy
for sharing | 51 | yes |
| `permissions/profiles.mdx` | Profiles (removed) | Profiles (removed) —
use permission sets | 54 | yes |
| `permissions/record-view-auditing.mdx` | Record-View Auditing | Record
view auditing — who read what | 50 | yes |
| `permissions/rls.mdx` | Row-Level Security (RLS) | Row-level security
(RLS) — filter by rule | 55 | yes |
| `permissions/sharing-rules.mdx` | Sharing Rules | Sharing rules and
organization-wide defaults | 58 | yes |
| `permissions/sso.mdx` | Social & Enterprise SSO | SSO — social and
enterprise sign-in setup | 55 | yes |
| `permissions/system-context.mdx` | System Context (isSystem) | System
context (isSystem) — bypass rules | 54 | yes |
| `permissions/tenant-audit-census.mdx` ✳️ | Tenant-Audit Census |
Tenant-audit census — tenancy write call sites | 60 | yes |
| `plugins/adding-a-metadata-type.mdx` | Adding a Metadata Type | Add a
custom metadata type from a plugin | 54 | yes |
| `plugins/anatomy.mdx` | Plugin Anatomy | Plugin anatomy — files, hooks
and exports | 55 | yes |
| `plugins/development.mdx` | Plugin Development | Plugin development —
build and test one | 53 | yes |
| `plugins/index.mdx` | Plugin System | Plugin system — extend the
runtime safely | 55 | yes |
| `plugins/packages.mdx` | Package Overview | Package overview — what
each one does | 51 | yes |
| `protocol/backward-compatibility.mdx` | Backward Compatibility Policy
| Backward compatibility policy for the spec | 56 | yes |
| `protocol/diagram.mdx` | Protocol Relationship Diagram | Protocol
relationship diagram explained | 53 | yes |
| `protocol/index.mdx` | Protocol Specification | Protocol specification
— the open format | 54 | yes |
| `protocol/kernel/config-resolution.mdx` | Configuration Resolution |
Configuration resolution order and layers | 55 | yes |
| `protocol/kernel/error-handling.mdx` | Error Handling | Error handling
— the response envelope | 52 | yes |
| `protocol/kernel/http-protocol.mdx` | HTTP API | HTTP API protocol —
routes and verbs | 50 | yes |
| `protocol/kernel/i18n-standard.mdx` | Internationalization Standard |
Internationalization standard for metadata | 56 | yes |
| `protocol/kernel/index.mdx` | Kernel: The System Protocol | Kernel —
the system protocol specification | 56 | yes |
| `protocol/kernel/lifecycle.mdx` | System Lifecycle | System lifecycle
— from boot to ready state | 57 | yes |
| `protocol/kernel/metadata-service.mdx` | Metadata Service | Metadata
service protocol specification | 53 | yes |
| `protocol/kernel/plugin-spec.mdx` | Plugin Package Specification |
Plugin package specification and manifest | 55 | yes |
| `protocol/kernel/realtime-protocol.mdx` | Real-Time Protocols |
Real-time protocols — websockets, SSE | 51 | yes |
| `protocol/knowledge.mdx` | Knowledge Protocol | Knowledge protocol —
RAG as metadata | 50 | yes |
| `protocol/objectql/query-syntax.mdx` | Query Syntax | ObjectQL query
syntax — the full specification | 60 | yes |
| `protocol/objectql/schema.mdx` | Schema Definition | ObjectQL schema
definition specification | 54 | yes |
| `protocol/objectql/security.mdx` | Security & Access Control |
ObjectQL security and access control | 50 | yes |
| `protocol/objectql/state-machine.mdx` | State Machine (Lifecycle) |
State machine — record lifecycle spec | 51 | yes |
| `protocol/objectql/types.mdx` | Type System | ObjectQL type system —
the specification | 54 | yes |
| `protocol/objectui/actions.mdx` | Action Protocol | Action protocol —
buttons as metadata | 51 | yes |
| `protocol/objectui/concept.mdx` | UI as Data Concept | UI as data —
the core ObjectUI concept | 52 | yes |
| `protocol/objectui/layout-dsl.mdx` | Layout DSL | Layout DSL — arrange
fields declaratively | 55 | yes |
| `protocol/objectui/widget-contract.mdx` | Widget Contract | Widget
contract — build a custom widget | 53 | yes |
| `ui/actions.mdx` | Actions | Actions — permission-checked UI buttons |
53 | yes |
| `ui/apps.mdx` | App Metadata | App metadata — navigation and branding
| 52 | yes |
| `ui/audience-based-interfaces.mdx` | Audience-based interfaces |
Audience-based interfaces — one app, many | 55 | yes |
| `ui/create-vs-edit-form.mdx` | Create form ≠ edit form | Create form
vs edit form — the differences | 56 | yes |
| `ui/dashboards.mdx` | Dashboard Metadata | Dashboard metadata — charts
and KPIs | 50 | yes |
| `ui/doc-pages.mdx` | Doc Metadata | Doc metadata — in-app
documentation pages | 55 | yes |
| `ui/field-grouping-and-order.mdx` | Field grouping & order | Field
grouping and order in generated forms | 57 | yes |
| `ui/forms.mdx` | Forms (Public + Internal) | Forms — public and
internal data entry | 52 | yes |
| `ui/index.mdx` | UI Engine | UI engine — render views from metadata |
52 | yes |
| `ui/pages.mdx` | Page Metadata | Page metadata — build custom app
screens | 54 | yes |
| `ui/public-data-collection.mdx` | Collect data from the public |
Collect data from the public with web forms | 57 | yes |
| `ui/react-pages.mdx` | React Pages | React pages — escape hatch for
custom UI | 54 | yes |
| `ui/reports.mdx` | Report Metadata | Report metadata — grouped,
filtered data | 54 | yes |
| `ui/setup-app.mdx` | Setup App | Setup app — administer a running
runtime | 54 | yes |
| `ui/translations.mdx` | Translations | Translations — labels and UI
text per locale | 58 | yes |
| `ui/views.mdx` | View Metadata | View metadata — list, kanban,
calendar | 52 | yes |
| `upgrading.mdx` | Upgrading | Upgrade guide — move between major
versions | 57 | yes |
## Verification
All at head `c69d5c7`, `git status --porcelain` empty. `origin/main` was
merged in twice during the rework round (now at merge base `e2c4e12`);
neither merge touched this PR's files.
Gate list derived with `node scripts/pm/dispatch-gates.mjs --repo
objectstack-ai/objectstack --commands` (178 paths vs merge base
`e2c4e12`, three-dot; 640 changed lines, under the 5,000 human-merge
threshold), then reconciled: `--ran` answered `74 derived famil(ies)
accounted for — 74 run, 0 NOT-MEASURED (a DERIVED zero — all 74 recorded
an exit code and none of them is 3)`. Each command's exit code was
captured before any pipe:
```
exit 0 node scripts/check-ci-filter-parity.mjs
exit 0 node scripts/check-closing-keyword-parity.mjs
exit 0 node scripts/check-closing-keyword-parity.mjs --self-test
exit 0 node scripts/check-comment-mask-corpus.mjs
exit 0 node scripts/check-declaration-mirrors.mjs
exit 0 node scripts/check-declaration-mirrors.mjs --self-test
exit 0 node scripts/check-doc-frontmatter.mjs
exit 0 node scripts/check-doc-frontmatter.mjs --self-test
exit 0 node scripts/check-doc-route-spelling.mjs --advisory
exit 0 node scripts/check-doc-route-spelling.mjs --self-test
exit 0 node scripts/check-docs-section-name.mjs
exit 0 node scripts/check-docs-section-name.mjs --self-test
exit 0 node scripts/check-scripts-symbol-anchors.mjs
exit 0 node scripts/check-scripts-symbol-anchors.mjs --self-test
exit 0 node scripts/check-section-landing-index.mjs
exit 0 node scripts/check-section-landing-index.mjs --self-test
exit 0 node scripts/check-self-test-wired.mjs
exit 0 node scripts/check-self-test-wired.mjs --self-test
exit 0 node scripts/check-self-test-workflow-commands.mjs
exit 0 node scripts/check-self-test-workflow-commands.mjs --self-test
exit 0 node scripts/check-system-context-census.mjs
exit 0 node scripts/check-system-context-census.mjs --self-test
exit 0 node scripts/check-tenant-audit-census.mjs
exit 0 node scripts/check-tenant-audit-census.mjs --self-test
exit 0 node scripts/check-whole-set-label-write.mjs
exit 0 node scripts/check-whole-set-label-write.mjs --self-test
exit 0 node scripts/docs-audit/check-drift-comment.mjs
exit 0 node scripts/pm/bare-root-worklist.mjs --self-test
exit 0 pnpm --filter @objectstack/lint run check:doc-formula-expressions
exit 0 pnpm --filter @objectstack/lint run check:doc-security-posture
exit 0 pnpm --filter @objectstack/spec run check:docs
exit 0 pnpm --filter @objectstack/spec run check:empty-state
exit 0 pnpm --filter @objectstack/spec run check:liveness
exit 0 pnpm --filter @objectstack/spec run check:skill-docs
exit 0 pnpm --filter @objectstack/spec run check:skill-examples
exit 0 pnpm --filter @objectstack/spec run check:strictness-ledger
exit 0 pnpm --filter @objectstack/spec run check:variant-docs
exit 0 pnpm --filter @objectstack/spec run check:yaml-examples
exit 0 pnpm check:agent-test-spelling
exit 0 pnpm check:bash32-floor
exit 0 pnpm check:cli-command-ids
exit 0 pnpm check:cli-examples-parity
exit 0 pnpm check:corpus-claim-drift
exit 0 pnpm check:cross-package-test-inputs
exit 0 pnpm check:doc-anchors
exit 0 pnpm check:doc-authoring
exit 0 pnpm check:docs-audit-scope
exit 0 pnpm check:docs-image-tag
exit 0 pnpm check:docs-redirects
exit 0 pnpm check:docs-single-h1
exit 0 pnpm check:docs-spec-enumerations
exit 0 pnpm check:docs-transcript-drift
exit 0 pnpm check:driver-memory-census
exit 0 pnpm check:entry-guard
exit 0 pnpm check:error-status-conformance
exit 0 pnpm check:gitlink-declared
exit 0 pnpm check:lockstep-package-count
exit 0 pnpm check:merge-driver
exit 0 pnpm check:nul-bytes
exit 0 pnpm check:overlay-whitelist-table
exit 0 pnpm check:parse-guard
exit 0 pnpm check:pm-dispatch-gates
exit 0 pnpm check:pm-widening-tells
exit 0 pnpm check:pnpm-filter-targets
exit 0 pnpm check:published-readme-links
exit 0 pnpm check:quick-reference-counts
exit 0 pnpm check:ratchet-remedy-authority
exit 0 pnpm check:react-page-adapter-contract
exit 0 pnpm check:refd-timer-probe
exit 0 pnpm check:role-word
exit 0 pnpm check:runtime-services-index
exit 0 pnpm check:skill-identifier-liveness
exit 0 pnpm check:vendor-version-stamps
exit 0 pnpm check:watch-hint-literal
exit 0 node scripts/check-docs-nav-label.mjs
exit 0 node scripts/check-docs-nav-label.mjs --self-test
```
Verdict lines:
- `check-doc-anchors: 376 internal #fragment link(s) across 411 source
file(s) all resolve to a real heading` (the card's acceptance gate)
- `check-doc-frontmatter: 2 content root(s) verified, each against its
own floor — content/docs 406, content/blog 3.`
- `check-docs-nav-label`: `navTitle` named in code by 2 file(s) only;
resolver executed; plugin wired into the docs loader; JSON-LD breadcrumb
leg green. It reads `apps/docs/**` only, so a `navTitle:` frontmatter
line is not judged by it; run as a guard that the mechanism this PR
relies on is intact.
- `check-runtime-services-index --self-test: 59 assertions …` and
`check-runtime-services-index: 8 chapter page(s) vs meta.json "pages" …`
both green, with the 8 approved titles applied.
For the record, round 1: on the verbatim table `check:role-word` and
`check:runtime-services-index` exited **1**. Both were real findings:
the first is handled by the re-worded row, the second by the gate change
above. `check:skill-examples` exited **3** (`PREREQUISITE NOT MET`,
stale `client-react` declarations, nothing measured) until
`@objectstack/client-react` was built. All green at this head.
**NOT MEASURED locally:** the card's "link checker" is
`.github/workflows/check-links.yml` (lychee, advisory lane); lychee is
not installed in this container. It runs on this PR in CI. This diff
changes no link, link text or file path, only two frontmatter keys. A
full `next build` of `apps/docs` was not run locally; `fumadocs-mdx`
regenerated the source index at exit 0, and `check-doc-frontmatter`
parses every page with the `yaml` version the build resolves.
`pnpm lint` is not owed: `.mdx` is outside the ESLint population and no
other file type is touched.
No changeset: docs content only, publishes nothing. `skip-changeset`
applied.
## Acceptance notes
- **30 approved rows have no ` — ` separator** (for example
`ai/natural-language-queries.mdx` → `Natural language queries over your
data`), although the ruling says "separator ` — ` throughout". The
ruling approves the table "as they stand", so they are applied verbatim
(PM answer in review comment `5852831074`); re-wording them is the
maintainer's call.
- **The two folder-index pages #12312 lengthened show the long title in
the footer previous/next links**: `protocol/objectql/index.mdx` and
`protocol/objectui/index.mdx` carry no `navTitle`, and `flattenTree()`
puts a folder index into that list. #12312 judged them "not in the page
tree / `meta.json` title wins", which holds for the sidebar only. Left
as they are, per the PM answer in review comment `5852831074`.
- The #12236 trap note (76 demoted body H1s as a mapping-table input) is
moot for the applied rows: the table was approved as it stands.
- Pre-existing duplicate titles exist among the generated
`references/**` pages (e.g. `Mapping`, `Sharing`, `Plugin`); that is the
generator half, #15403.
---
_Generated by [Claude
Code](https://claude.ai/code/session_018bR89KaSkoZVqgBnUYXtyD)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent a91d12a commit 5983d11
178 files changed
Lines changed: 446 additions & 194 deletions
File tree
- content/docs
- ai
- api
- automation
- capabilities
- concepts
- data-modeling
- deployment
- getting-started
- kernel
- contracts
- runtime-services
- permissions
- plugins
- protocol
- kernel
- objectql
- objectui
- ui
- scripts
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
0 commit comments