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 { DocSchema } from '@objectstack/spec/system';
import type { Doc } from '@objectstack/spec/system';

// Validate data
const result = DocSchema.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
tagsstring[]optionalMembership tags matched by a book group's include: { tag } rule (ADR-0046 §5)
translationsRecord<string, { label?: string; description?: string; content: string }>optionalPer-locale {label?,description?,content} variants; the base doc is the fallback
_lockEnum<'none' | 'no-overlay' | 'no-delete' | 'full'>optionalItem-level lock — controls overlay & delete (ADR-0010).
_lockReasonstringoptionalHuman-readable reason shown when a write is refused by _lock.
_lockSourceEnum<'artifact' | 'package' | 'env-forced'>optionalLayer that set _lock (artifact | package | env-forced).
_provenanceEnum<'package' | 'org' | 'env-forced'>optionalOrigin of the item (package | org | env-forced).
_packageIdstringoptionalOwning package machine id.
_packageVersionstringoptionalOwning package version.
_lockDocsUrlstringoptionalOptional documentation link surfaced next to _lockReason.

On this page