The hierarchy
- A workspace is the permission and asset boundary. Grants, private media, and changesets all live at workspace level.
- A manual is a reusable, multi-page document inside a workspace. Manuals bind to jobs, folders, or work projects with explicit precedence, so one manual can serve many surfaces.
- Pages form a bounded tree inside a manual (nested up to the manual’s depth limit, default 5). Each page has a title, an audience, and a canonical rich-text body.
Canonical documents
Every page body is a canonicalopentrain-tiptap/1 JSON envelope:
- Stable node IDs. Every addressable block carries an immutable
attrs.id. You patch, cite, and deep-link individual blocks without rewriting pages. - A closed vocabulary. Only node and mark types the human editor can round-trip are valid.
GET /instructions/capabilitiesadvertises the complete node/mark/attribute vocabulary, so you can author valid documents from first principles. Unknown node or mark types are rejected; unknown attributes surface as warnings. - Deterministic checksums. The
checksumis the SHA-256 of the recursively key-sorteddocJSON, so independently produced documents compare byte-equal.
Changesets: page content and tree mutations
Page content and tree mutations — content patches, page creation, moves, renames, page archives, and asset attachments — travel as changesets: atomic batches of up to 250 operations against one workspace. Either every operation applies or none do. Workspace/manual metadata, permissions, asset preparation/finalization, and publication use their dedicated endpoints.- Content edits use stable-node patch operations (
replace_node,insert_before,insert_after,append_children,set_attrs,delete_node) guarded by the page’s base revision and optional checksums. - Whole-document replacement exists only as an explicit operation with
confirmReplace: true. - A
CREATE_PAGEoperation with aclientPageKeycan be referenced by other operations in the same changeset asparentPageId: "new:<clientPageKey>"— build a whole nested section in one atomic write, in any operation order. - Conflicts come back as structured objects (operation index, code, current revision/checksum), never prose-only errors.
Idempotency-Keyis supported by workspace/manual creation, direct changeset apply, changeset submit, stored changeset apply, revision restore, and publication. Replaying a key returns the original result; reusing a key with a different request is a409.
POST /changesets/validate dry-runs the full plan and POST /changesets/diff summarizes what would change.
Direct writes and reviewed proposals
Two write modes share the same changeset format:- Direct apply (
instructions:write):POST /changesets/applywrites immediately. - Submit for review (
instructions:propose+ workspaceEDITOR/OWNER):POST /changesets/submitstores the proposal. AREVIEWERorOWNERwithinstructions:reviewapproves or rejects it (optionally with adecisionNote), and an approved proposal is applied by ID through the same guarded write path. If pages drifted since submission, the apply records the proposal asCONFLICTEDwith structured conflicts instead of overwriting newer work.
Revisions and publications
- Every applied changeset bumps the manual’s revision — an immutable, numbered snapshot of every page. Diff any two revisions; restore an old one as a new revision (history is never rewritten).
- Workers never read drafts. A publication (
POST /manuals/{manualId}/publications) freezes a manual revision into the worker-facing snapshot, filtered by audience. Publishing requires theinstructions:publishscope and is reserved for workspace owners.
Audiences and permissions
Pages and publications carry an audience tier —ADMIN, CONTRIBUTOR, REVIEWER, or WORKER. Published manifests use the monotonic ladder: a reader sees their tier and everything below it, so reviewer-only rubric notes never leak into the worker view. Working-tree tree and search audience filters are exact-match.
Workspace access is per-user: workspace creation persists the owner’s OWNER permission record, and permission grants assign EDITOR, REVIEWER, or VIEWER to other users.
Private media
Images, files, audio, and video are private assets, uploaded in two phases (prepare → upload bytes → finalize) and referenced from documents by asset ID only — raw storage URLs are rejected at write time. Finalization checks the prepared object and trusted upload metadata; the declared SHA-256 is not independently recomputed server-side. Reads mint short-lived signed URLs. Size limits per kind: images 25 MB, files 100 MB, audio 250 MB, video 2 GB.Renders and loss reports
The canonical JSON is the source of truth. HTML and Markdown are derived renders (POST /render-preview); every Markdown render carries a machine-readable loss report listing exactly what the format could not express. Nothing is silently down-converted.
Where to go next
- Author instruction manuals — the end-to-end guide.
- API reference — every endpoint.
- CLI and MCP — the same surface for terminals and agents.