ObjectStackObjectStack

Doc

Doc protocol schemas

Package Documentation Metadata Protocol (ADR-0046)

One doc item per Markdown file under the package's flat src/docs/

directory (no subdirectories — flatness is the contract that keeps

cross-references stable). The CLI compiles each file into this shape at

build time; TS-first stacks may also declare items inline via

defineStack(\{ docs: [...] \}).

Identity model: name = filename stem (lowercase snake_case). A namespace

prefix (crm_lead_guide) is a recommended convention, no longer required:

per ADR-0048, single-doc resolution is package-scoped (`getItem('doc', name,

packageId)via?package=` on the detail route), so two packages may ship a

doc with the same bare name and each resolves within its own package — just

like page/dashboard/report. The prefix stays useful for readable,

globally-unique filenames but is not load-bearing for uniqueness.

Docs are inert data: the kernel registers them without parsing

content, and they participate in no runtime behavior. Renderers

resolve relative links between docs ([guide](./crm_lead_guide.md))

by stripping ./ and .md to obtain the target doc name.

Source: packages/spec/src/system/doc.zod.ts

TypeScript Usage

import { Doc } from '@objectstack/spec/system';
import type { Doc } from '@objectstack/spec/system';

// Validate data
const result = Doc.parse(data);

Doc

Properties

PropertyTypeRequiredDescription
namestringDoc name (= filename stem, snake_case; namespace prefix recommended, not required)
labelstringoptionalDisplay title; defaults to the first # heading, then the name
descriptionstringoptionalOne-line summary for listings; from frontmatter description:
contentstringRaw Markdown content (CommonMark + GFM)
ordernumberoptionalSort key within a book group (ADR-0046 §6)
groupstringoptionalExplicit book-group key (ADR-0046 §6); rules usually suffice
translationsRecord<string, Object>optionalPer-locale {label?,description?,content} variants; the base doc is the fallback

On this page