Repository navigation
Commit 9daced0
docs(content,spec): search-ready page descriptions — 52 authored rewrites and derived reference descriptions (#20258)
Fixes #12238
Clause-②: no
**Draft for the maintainer's voice review — do not merge or ready it.**
One card, both halves, per the rulings recorded on the card (comment
`5856895911`): 「一张卡全做」 (authored pages AND the generator), 「只改超范围的 52 页」
(only the out-of-range authored pages), 「不加门禁」 (no new `check:*` gate).
## The rule
A page's frontmatter `description` is the one line a search result shows
under its title.
- **Length:** 70–160 characters (under 70 the engine discards it and
writes its own snippet; over 160 it is cut mid-sentence). Rewritten
authored lines aim at **120–155**.
- **Content:** what the page lets you do, in the words a reader would
search, ending on why to click.
- **Form:** a sentence, not a truncated title.
## Population, before → after
Measured on this branch's tree (`4b7d63cc`) against its base `e0f17a3`;
`releases/**` is release-owned and out of scope.
| group | pages | median before | median after | under 70 | 70–160 |
over 160 |
|---|--:|--:|--:|---|---|---|
| authored (`content/docs/**` minus `references/**`, `releases/**`) |
181 | 117 | 129 | 15 → **0** | 129 → **181** | 37 → **0** |
| generated `references/**` | 211 | 28 | 138 | 210 → **0** | 1 → **211**
| 0 → **0** |
Every one of the 392 pages' frontmatter parses as YAML (js-yaml) with a
string `description` in range. **No exceptions remain.**
## Authored half — 52 rows
Only the `description:` line changes (`git diff` over the 52 files: 52
insertions, 52 deletions, zero other lines). `title:` / `navTitle:`
lines, the 129 in-range pages, `releases/**`, `apps/docs/**` and
`meta.json` are untouched. Over-long lines were trimmed toward their
original meaning rather than rewritten. Rows 1–15 were under 70; rows
16–52 were over 160.
| # | page | before | len | after | len |
|--:|---|---|--:|---|--:|
| 1 | `concepts/north-star.mdx` | ObjectStack's current product and
architecture direction. | 57 | Where ObjectStack is headed: a
metadata-native backend that humans and AI agents can both operate
safely — its principles, runtime shape and non-goals. | 151 |
| 2 | `data-modeling/drivers.mdx` | Configuration reference for
supported database drivers | 54 | Connect ObjectStack to PostgreSQL,
MySQL, SQLite, MongoDB, Turso or memory — URL-based driver inference,
per-driver config keys and dialect caveats. | 148 |
| 3 | `getting-started/quick-reference.mdx` | Fast lookup table for all
ObjectStack protocols | 47 | Look up any ObjectStack metadata type fast
— the key schemas of every protocol category on one page, with common
patterns and search tips. | 138 |
| 4 | `index.mdx` | Technical documentation for ObjectStack. | 40 |
ObjectStack documentation: build business apps from typed metadata that
AI agents write and humans verify — start here for guides, concepts and
APIs. | 149 |
| 5 | `kernel/architecture.mdx` | Deep dive into the ObjectKernel
architecture | 44 | How the ObjectKernel boots and runs: its core
architecture, the plugin bootstrap lifecycle, and the public kernel API
you call from a plugin. | 141 |
| 6 | `kernel/events.mdx` | System-wide event bus for loose coupling
between plugins | 56 | Every kernel lifecycle hook and data lifecycle
hook in ObjectStack — when each fires, its payload and ordering, and
which of the two systems to pick. | 149 |
| 7 | `kernel/runtime-services/email-service.mdx` | Outbound email
delivery and template rendering APIs. | 52 | Send email from a plugin or
flow with services.email — send() and sendTemplate(), the result they
return, and the typed error codes to handle. | 142 |
| 8 | `kernel/runtime-services/queue-service.mdx` | Async queue
publish/subscribe and DLQ operations. | 49 | Publish and subscribe to
async job queues with services.queue — queue size, purge, and
dead-letter listing, replay and cleanup for failed messages. | 147 |
| 9 | `kernel/runtime-services/sharing-service.mdx` | Record-level
sharing and editability checks. | 44 | Check and manage record-level
sharing with services.sharing — read filters, canEdit and canDelete
checks, and granting or revoking record shares. | 145 |
| 10 | `kernel/services.mdx` | Dependency Injection mechanism for loose
coupling between plugins | 65 | How plugins expose and consume services
in ObjectStack — register a service, resolve it by name, see the
standard services, and replace a core one. | 147 |
| 11 | `protocol/index.mdx` | The formal ObjectStack protocol for Data,
UI, and System layers | 63 | The ObjectStack protocol specification: how
the Data, UI and System layers describe a complete business application
as metadata, and its design principles. | 155 |
| 12 | `protocol/objectui/actions.mdx` | Buttons, triggers, navigation,
and user interaction definitions | 63 | The ObjectUI action protocol:
declare buttons, menu items and triggers as metadata that run business
logic, navigate, or call external integrations. | 148 |
| 13 | `protocol/objectui/concept.mdx` | The philosophy and architecture
of metadata-driven user interfaces | 66 | Why ObjectUI defines
interfaces as data, not code: forms, dashboards and reports as
declarative metadata that any renderer can draw consistently. | 145 |
| 14 | `protocol/objectui/index.mdx` | Server-driven UI protocol -
Define interfaces as data, not code | 63 | ObjectUI, the server-driven
UI protocol: define layouts, forms and dashboards as JSON or YAML
metadata that renderers turn into working interfaces. | 147 |
| 15 | `protocol/objectui/widget-contract.mdx` | Standard props, events,
and lifecycle for ObjectUI components | 61 | Build a custom ObjectUI
field widget: the standard props, events and lifecycle it implements,
how to register it, and accessibility and theme rules. | 148 |
| 16 | `api/declarative-endpoints.mdx` | Expose your app to systems
outside the platform by declaring an apis: endpoint as metadata — which
channel to pick, the four publish gates, and the obligation that comes
with an anonymous endpoint. | 197 | Expose your app to outside systems
by declaring an apis: endpoint as metadata — pick the channel, pass the
four publish gates, secure anonymous calls. | 150 |
| 17 | `api/plugin-endpoints.mdx` | REST endpoints that become available
when the corresponding plugin is installed — auth, workflow, automation,
views, realtime, notifications, AI, i18n, and file storage. | 169 | REST
endpoints each installed plugin adds — auth, workflow, automation,
views, realtime, notifications, AI, i18n and files — and how to discover
them. | 150 |
| 18 | `automation/approvals.mdx` | Route a record for sign-off — who
can configure the automation, and the run-identity decision that keeps
an approval flow from quietly bypassing row-level security. | 164 |
Route a record for sign-off with an approval flow — who may configure
it, and the run-identity choice that keeps it from bypassing row-level
security. | 150 |
| 19 | `automation/connectors.mdx` | Call external systems from flows —
plugin-registered connectors, and declarative provider-bound instances
(rest / openapi / mcp) authored as pure metadata with reference-based
credentials. | 188 | Call external systems from flows with plugin
connectors or declarative rest, openapi and mcp instances — pure
metadata with reference-based credentials. | 152 |
| 20 | `capabilities/index.mdx` | The platform's capabilities in
business language — data, views, automation, approvals, permissions,
analytics, AI, integrations — each with a real CRM as the running
example | 173 | What the platform can do, in business language — data,
views, automation, approvals, permissions, analytics, AI and
integrations, shown on a real CRM. | 150 |
| 21 | `concepts/metadata-lifecycle.mdx` | How metadata flows through
Repository → Change Log → Cache → Registry — the canonical event stream
that powers Studio HMR, REST writes, and future cloud editing. | 161 |
How metadata flows through Repository, Change Log, Cache and Registry —
the event stream behind Studio hot reload, REST writes and cloud
editing. | 145 |
| 22 | `deployment/index.mdx` | Two things deploy on this platform and
they move on separate clocks — the platform runtime you operate, and the
metadata app you build. Which one you are doing decides which pages in
this section are yours. | 206 | Deploy the platform runtime or ship your
metadata app — two things on separate clocks. Find out which one you are
doing and which pages cover it. | 145 |
| 23 | `deployment/publish-and-preview.mdx` | A metadata app is
versioned in your catalog while the platform moves on its own release
train. Compile the app into an artifact, then pick how it reaches a
running platform — installed from the catalog, or pinned as the
runtime's boot artifact. | 244 | Compile a metadata app into a versioned
artifact, then install it from the catalog or pin it as the runtime's
boot artifact to preview and publish. | 147 |
| 24 | `deployment/seed-tenancy-repair.mdx` | The automatic repair that
stamps organization_id on untenanted seed rows and merges the __global__
autonumber counter — when it runs, what it changes, what it deliberately
leaves alone, and the manual remedy for a multi-organization install. |
241 | The automatic repair that stamps organization_id on untenanted
seed rows — when it runs, what it changes, and the manual fix for
multi-org installs. | 148 |
| 25 | `deployment/self-hosting.mdx` | Run a compiled ObjectStack app on
your own infrastructure with the official Docker image — plus Compose
with Postgres, Kubernetes, and the bare Node.js fallback, including
health checks, reverse-proxy wiring, and the secrets you must pin. | 238
| Run a compiled ObjectStack app on your own servers with the official
Docker image, Compose and Postgres, or Kubernetes — health checks and
secrets too. | 151 |
| 26 | `deployment/tenancy-modes.mdx` | The three tenancy postures
(single / group / isolated), how OS_TENANCY_POSTURE resolves, the
membership policy for new users, and the degraded-tenancy boot guard. |
162 | Choose single, group or isolated tenancy: how OS_TENANCY_POSTURE
resolves, the membership policy for new users, and the degraded-tenancy
boot guard. | 148 |
| 27 | `getting-started/build-with-claude-code.mdx` | The core
ObjectStack workflow — Claude Code authors the metadata, you verify in
the visual Console, guardrails catch mistakes, and the app you build is
itself AI-operable over MCP. | 180 | Build an ObjectStack app with
Claude Code: the AI writes the metadata, you verify it in the Console,
guardrails catch mistakes, and the app speaks MCP. | 151 |
| 28 | `getting-started/how-ai-development-works.mdx` | The division of
labor behind ObjectStack — AI authors the typed metadata, you verify in
the visual UI, and layered guardrails keep the AI from shipping
mistakes. | 161 | How building with ObjectStack splits the work: AI
writes the typed metadata, you verify it in the visual UI, and layered
guardrails stop its mistakes. | 150 |
| 29 | `getting-started/your-first-project.mdx` | Scaffold a standalone
ObjectStack project with npm, understand what was generated, extend the
data model, call the REST API, and build a deployable artifact — no
monorepo checkout, no AI agent required. | 202 | Scaffold a standalone
ObjectStack project with npm, extend the data model, call the REST API
and build a deployable artifact — no AI agent required. | 148 |
| 30 | `permissions/access-recipes.mdx` | Map a concrete access
requirement onto the platform's layers — object CRUD, field-level
security, row-level security, capabilities, app/nav gating, and the
run-identity of automations. | 184 | Map a real access requirement onto
the right layer — object CRUD, field-level and row-level security,
capabilities, navigation gating and automations. | 150 |
| 31 | `permissions/administrator-guide.mdx` | The task-first operations
manual for customer system administrators — onboard a tenant in four
steps (build the org tree, add people, assign positions, verify), with
the 90% rule — daily administration is assigning positions; the
capability plumbing ships built-in. | 265 | The permissions manual for
tenant administrators: onboard a tenant in four steps, then run daily
access by assigning positions — no plumbing needed. | 148 |
| 32 | `permissions/attachments-access.mdx` | How access to record
attachments is decided — the parent-derived read/create/delete model,
authenticated downloads, the enable.files opt-in gate, and the
storage-byte lifecycle. Covers sys_attachment and sys_file. | 213 | Who
can read, upload or delete a record's attachments: the parent-derived
access model, authenticated downloads, the enable.files gate and file
cleanup. | 152 |
| 33 | `permissions/authorization.mdx` | The one-page map of ObjectStack
authorization — the enforcement chain, combination semantics, package
provenance, lifecycle coverage, and the CI governance — with its limits
— behind "declared" equals "enforced". Stitches
ADR-0049/0054/0056/0057/0066/0068/0069/0078/0086 into a single
narrative. | 295 | One-page map of ObjectStack authorization — the
enforcement chain, how grants combine, package provenance, lifecycle
coverage and the CI checks behind it. | 154 |
| 34 | `permissions/capabilities.mdx` | How a package DEFINES an
authorization capability with defineCapability — the declaration half of
ADR-0066 D1 — and how that name travels from source to the
sys_capability catalogue to a permission-set grant to a
requiredPermissions check. | 239 | Define an authorization capability in
a package with defineCapability, then follow it into the catalogue, a
permission-set grant and a runtime check. | 149 |
| 35 | `permissions/delegated-administration.mdx` | Administration
itself as a scoped grant — a business-unit subtree, an action set, and
an assignable-set allowlist, with self-escalation structurally
impossible (ADR-0090 D12). | 175 | Hand out scoped admin rights: a
business-unit subtree, an action set and an assignable-set allowlist,
with self-escalation structurally impossible. | 147 |
| 36 | `permissions/index.mdx` | Authentication, authorization, and
record- and field-level access control in ObjectStack — a cross-protocol
capability enforced by the ObjectStack runtime and declared as ObjectQL
security metadata. | 198 | Authentication, authorization, and record-
and field-level access control in ObjectStack — declared as security
metadata and enforced by the runtime. | 149 |
| 37 | `permissions/permission-sets.mdx` | The only capability container
— object CRUD + FLS + scope depth + capabilities, union-merged across
everything a user holds. Covers the built-in sets, assignment tables,
access depth, the isDefault suggestion, and delegated-admin scopes. |
237 | Permission sets are the only capability container: object CRUD,
field security, scope depth and capabilities, union-merged across what a
user holds. | 148 |
| 38 | `permissions/permissions-matrix.mdx` | Visual reference for
ObjectStack's security model — permission types, the object ×
permission-set matrix, field-level security, sharing rules,
business-unit depth, and the access-matrix snapshot gate | 199 | Visual
reference for ObjectStack security — permission types, the object ×
permission-set matrix, field security, sharing rules and business-unit
depth. | 152 |
| 39 | `permissions/positions.mdx` | Positions (岗位) are flat
capability-distribution groups — users hold positions, positions bind
permission sets. The visibility hierarchy lives on business units, never
here. Includes the built-in identity positions and the everyone/guest
audience anchors. | 254 | Positions are flat groups that hand permission
sets to users — the built-in identity positions, the everyone and guest
anchors, and where hierarchy lives. | 154 |
| 40 | `permissions/profiles.mdx` | The Profile concept was removed by
ADR-0090 D2. Baseline access is now authored with the everyone audience
anchor, package isDefault suggestions, and ordinary permission sets
distributed via positions. | 201 | Profiles were removed. Author
baseline access with the everyone audience anchor, package isDefault
suggestions and permission sets given via positions. | 151 |
| 41 | `permissions/record-view-auditing.mdx` | Who viewed this record,
and when — the `read` action in sys_audit_log: its per-object opt-in,
the four edges of its scope, and what a view row deliberately does not
carry. | 171 | Find out who viewed a record and when: the read action in
sys_audit_log, its per-object opt-in, the edges of its scope and what a
view row leaves out. | 150 |
| 42 | `permissions/sharing-rules.mdx` | Record-level access: the
organization-wide default (OWD) baseline per object, the external
sharing dial, criteria sharing rules and recipient types, and the
RLS-safe analytics read scope. | 187 | Record-level access in
ObjectStack: organization-wide defaults per object, the external sharing
dial, criteria sharing rules and RLS-safe analytics reads. | 154 |
| 43 | `permissions/system-context.mdx` | The authoritative table of
every platform behaviour keyed off `ExecutionContext.isSystem` — what an
elevated write gets, what it loses, and what the flag deliberately does
NOT do. Built by census over the whole repo, not by recall. | 231 |
Every platform behaviour that ExecutionContext.isSystem changes — what
an elevated write gets, what it loses, and what the flag deliberately
does not do. | 153 |
| 44 | `permissions/tenant-audit-census.mdx` | The authoritative
enumeration of every application-surface write call site against a
tenancy-enabled object — how many thread an execution context, how many
thread none, and how much of the population a static instrument can
decide at all. Built by census over the whole repo, not by recall. | 291
| A census of every write call site against a tenancy-enabled object —
which pass an execution context, which pass none, and what static checks
can decide. | 153 |
| 45 | `ui/actions.mdx` | Declarative buttons with server-side behavior
— define once, bind to lists, records, and navigation, permission-check
on both surfaces, and optionally expose to AI. | 164 | Declare buttons
as metadata with server-side behavior — bind them to lists, records and
navigation, permission-check both sides, and expose them to AI. | 151 |
| 46 | `ui/audience-based-interfaces.mdx` | The same data serves
different audiences. Give end users a curated app/page and keep builder
surfaces — Studio, raw object tables, automation config — out of their
view. Separate consumer and builder paths by default. | 217 | Serve one
dataset to different audiences: give end users a curated app and keep
builder surfaces like Studio and raw tables out of their view by
default. | 153 |
| 47 | `ui/create-vs-edit-form.mdx` | The new-record form asks 5 fields;
the full edit form shows 40 grouped into sections. Derive both from one
flat field set; only hand-shape the create form when layout or flow
genuinely diverges. | 194 | Derive a short create form and a full
sectioned edit form from one flat field set, and hand-shape the create
form only when its layout truly differs. | 149 |
| 48 | `ui/field-grouping-and-order.mdx` | The data model is a flat
field set, but forms need sections. Where grouping actually lives —
semantic field.group vs form sections vs a table's row grouping — and
why those three "groups" are different things. | 209 | Where form
sections really come from: field.group versus form sections versus table
row grouping — three different groups over one flat field set. | 146 |
| 49 | `ui/forms.mdx` | Render any FormView either publicly (anonymous,
/f/:slug) or internally (authed operators, /forms/:name). The same
metadata drives both, with URL prefill, configurable post-submit
behavior, and declarative open-form actions. | 224 | Render any FormView
publicly at /f/:slug or internally at /forms/:name from one metadata
source, with URL prefill, post-submit behavior and form actions. | 153 |
| 50 | `ui/public-data-collection.mdx` | Expose one form to anonymous
visitors (web-to-lead, contact-us, intake) without opening the
underlying base. Authorization is derived from the form's own
declaration; only whitelisted fields are accepted. | 204 | Collect
web-to-lead, contact and intake submissions from anonymous visitors
through one public form, without opening the underlying data to guests.
| 147 |
| 51 | `ui/react-pages.mdx` | Author a page body as real React
(kind:'react') or as constrained JSX that is parsed and never executed
(kind:'html') — the two source-authoring tiers, and how to choose | 169
| Write a page body as real React or as constrained JSX that is parsed
but never executed — the two source-authoring tiers and how to choose
between them. | 152 |
| 52 | `upgrading.mdx` | ObjectStack upgrades come in two halves that
run on separate clocks — the platform runtime and your metadata app.
Which one you are doing, what each one moves, and where the per-major
checklists live. | 200 | Upgrade ObjectStack in two halves on separate
clocks — the platform runtime and your metadata app. What each moves,
and where each major's checklist lives. | 155 |
## Generator half — `packages/spec/scripts/build-docs.ts`
**Before:** every module page was written `description: TITLE protocol
schemas`, every category overview `description: Complete reference for
all TITLE schemas` — 210 of 211 generated pages under 70.
**Derivation** (new `packages/spec/scripts/lib/page-description.ts`,
pinned by `scripts/page-description.test.ts`, 18 cases). No
`packages/spec/src/**` file is edited: the rule reads the module's
leading doc block through the existing `findModuleDocBlock` — the same
block `renderFileDescription` already renders as the page's opening.
1. **Lead** — the doc block's prose paragraphs before its first list,
table, fence or tag, after an optional title line. Markdown and
`{@link}` are flattened to text; citation-only parentheticals (`(#NNN)`,
`[ADR-NNNN …]`), bare URLs, one-word run-in labels and the `Implements
P0 requirement …` boilerplate are dropped; a sentence that only
introduced a list keeps its clause before the last comma or dash.
2. **Fit** — whole sentences while the total stays ≤ 160; later
paragraphs join only while it is still under 70; then the title line is
prefixed if that fits. A single sentence over 160 is cut at the longest
clause boundary that keeps ≥ 70 characters and leaves no bracket open —
only when none exists, at a word boundary with an ellipsis.
3. **Complete** — a lead still under 70 is followed by the page's schema
names: `… Reference for A, B and N more: every property with its type
and default.`
4. **Fallback** — a module with no doc block gets `TITLE schemas of the
ObjectStack CATEGORY: A, B and N more — each property with its type,
default and a TypeScript example.` Names are listed while they fit, the
rest counted.
5. **Category overviews** — `The ObjectStack CATEGORY in N reference
pages: every schema in @objectstack/spec with its properties, types,
defaults and a TypeScript example.`
The value is emitted double-quoted (`JSON.stringify`, a subset of YAML's
double-quoted style), because doc-block prose carries `: ` and quotes.
Everything is a pure function of the source, so `check:docs` stays a
plain regenerate-and-compare. Each `gen:docs` run prints one tally line.
**Which rule wrote the 196 module pages:** 115 from the doc block alone,
19 doc block + schema names, **62 on the schema-name fallback** (their
module has no module-level doc block — e.g. `data/object`,
`api/contract`, `kernel/plugin`). Plus 14 category overviews from rule
5. Two doc-block pages end on the word-boundary ellipsis
(`data/validation`, `marketplace/package`): their opening sentence has
no clause boundary that keeps ≥ 70 characters. They are in range.
### Sample — 10 regenerated pages
| page | before | after | len | rule |
|---|---|---|--:|---|
| `references/data/object.mdx` | Object protocol schemas | Object
schemas of the ObjectStack Data Protocol: ApiMethod, ApiOperation, Index
and 13 more — each property with its type, default and a TypeScript
example. | 156 | schema names |
| `references/ui/view.mdx` | View protocol schemas | View protocol
schemas — the view metadata type and its three persisted body spellings.
| 86 | doc block |
| `references/api/dispatcher.mdx` | Dispatcher protocol schemas |
Defines how the ObjectStack HttpDispatcher routes incoming API requests
to the correct kernel service based on URL prefix matching. | 131 | doc
block |
| `references/automation/control-flow.mdx` | Control Flow protocol
schemas | Structured control-flow constructs — the native + AI-authored
flow model: a loop container, a parallel block, and structured
try/catch/retry. | 141 | doc block |
| `references/kernel/cluster.mdx` | Cluster protocol schemas | Defines
the runtime semantics required for ObjectStack to behave correctly when
more than one Node.js process is involved. | 122 | doc block |
| `references/security/rls.mdx` | Rls protocol schemas | Implements
fine-grained record-level access control inspired by PostgreSQL RLS and
Salesforce Criteria-Based Sharing Rules. | 123 | doc block |
| `references/api/error-code-ledger.mdx` | Error Code Ledger protocol
schemas | Error-Code Ledger. Reference for ErrorCode, ProvenanceWaiver,
StandardSynonymWaiver: every property with its type and default. | 126 |
doc block + schema names |
| `references/system/object-storage.mdx` | Object Storage protocol
schemas | Object Storage Protocol. Reference for AccessControlConfig,
BucketConfig, FileMetadata, LifecycleAction and 11 more: every property
with its type and default. | 158 | doc block + schema names |
| `references/kernel/plugin.mdx` | Plugin protocol schemas | Plugin
schemas of the ObjectStack Kernel Protocol: Plugin — each property with
its type, default and a TypeScript example. | 122 | schema names |
| `references/data/index.mdx` | Complete reference for all data protocol
schemas | The ObjectStack Data Protocol in 29 reference pages: every
schema in @objectstack/spec with its properties, types, defaults and a
TypeScript example. | 149 | category index |
### Exact hunks in `build-docs.ts` (for #15403's rebase)
#15403 remains open; it will edit the **title** emission. This PR does
not touch the title line (`md += \`title: ${zodTitle}\n\``, base line
478) or anything else in the title path. Hunks, in base-file line
numbers:
- `@@ -64,0 +65,6` — import of `lib/page-description`.
- `@@ -457,0 +464,3` — the `descriptionSources` tally, after
`PAGE_SECTION_LEVEL`.
- `@@ -465 +474,2`, `@@ -470 +480` — the module source is read once into
`source` and handed to `renderFileDescription` (behaviour unchanged).
- `@@ -476,0 +487,9` — the `modulePageDescription(...)` call, just above
the frontmatter.
- `@@ -479 +498` — **the one description line** of module pages.
- `@@ -912 +931` — the one description line of category overviews.
- `@@ -1102,0 +1122,8` — the tally's `console.log`, before `flush`.
`content/docs/references/**` is regenerated by `gen:docs`, never
hand-edited: against `origin/main`, the only changed lines under it are
210 `description:` lines (the root `references/index.mdx` was already in
range and is unchanged).
## Acceptance
- [x] every `content/docs/**` description outside `releases/**` is
70–160 characters — 392 of 392, no exceptions
- [x] ~~a `check:*` gate enforces the range~~ — dropped by the ruling
「不加门禁」
- [x] descriptions read as sentences, not as truncated titles (authored:
hand-written; generated: sentence-fitted from the doc block, two
ellipsis cuts named above)
- [x] the rule and the full before/after table are in this body; the PR
stays **draft** for the maintainer's voice review
## Changeset
`skip-changeset`: nothing here ships. `packages/spec` publishes `files:
[dist, json-schema, liveness, prompts, llms.txt, README.md,
src/**/*.zod.ts, CHANGELOG.md, api-surface, spec-changes.json]`;
`scripts/**` is not in it. Measured after a real build:
`modulePageDescription` / `categoryIndexDescription` have 0 hits across
every shipped path, while the positive control `ObjectSchema` has 56
hits in `dist`. `content/docs/**` belongs to no package.
## Verification (on `4b7d63cc`, after merging `origin/main` via
`os-regen-merge.sh`)
- `pnpm --filter @objectstack/spec build`, then `check:generated` —
every gate ✓, including `check:docs` ("226 generated files in sync").
- `dispatch-gates --commands` derived 94 families. `--ran` with recorded
exit codes: **94 derived, 92 run, 2 NOT-MEASURED, 0 UNRUN**. All 92 exit
0.
- NOT MEASURED: `check:dual-build-cjs-loads` and
`check:type-check-debt`'s `--re-measure`. Both exit 3 because they need
the full `packages/*` build closure. This diff changes no package source
they read; CI builds that closure.
- `pnpm --filter @objectstack/spec typecheck` (tsc +
`check:scripts-typecheck` + `check:test-typecheck`) — exit 0.
- vitest: `scripts/page-description.test.ts` 18/18; neighbours
`file-description`, `references-banner`, `category-title`, `root-index`,
`category-index`, `schema-section` — 3 files (local) + 4 files (repo),
68 + 146 tests pass.
- Merge: `main`'s #20205 changed `automation/builtin-node-config` on
both sides. It was regenerated from the merged tree in its own commit
(`4b7d63cc`); its body is byte-identical to `origin/main` apart from the
description line.
## Acceptance notes
- 62 spec modules carry no module-level doc block, so their pages use
the schema-name fallback. Writing those doc blocks is a
`packages/spec/src/**` edit and was out of this card's surface on
purpose (clause-② path limb). The tally line printed by `gen:docs` is
the running count.
- Some doc-block leads read as internal notes rather than reader copy
(e.g. `kernel/metadata-protection`: "Phase 1 introduces the item-level
lock …"). The rule reproduces the source's own first sentence
faithfully; improving those needs a `src` docblock edit, not a generator
change.
Size: 265 files, +801 / −266 = 1,067 changed lines, generated files
included — under the 5,000-line threshold.
Seat `domain:devx#2`, dispatched by `session_018mA64scZ8fmpiPkrHVAwXj`;
implemented in `session_01RCEEP3Z95jrpXCeF3it3Y2`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---
_Generated by [Claude
Code](https://claude.ai/code/session_01RCEEP3Z95jrpXCeF3it3Y2)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 8af914a commit 9daced0
265 files changed
Lines changed: 801 additions & 266 deletions
File tree
- content/docs
- api
- automation
- capabilities
- concepts
- data-modeling
- deployment
- getting-started
- kernel
- runtime-services
- permissions
- protocol
- objectui
- references
- ai
- api
- automation
- data
- identity
- integration
- kernel
- marketplace
- qa
- security
- studio
- system
- ui
- ui
- packages/spec/scripts
- lib
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
0 commit comments