Adopt Opus — from a Work to its expressions
Opus is consumed through path dependencies by an implementation that serves one Work. Adoption follows the order the domain declares: the Work, then its spaces, then their expressions.
One source, one vocabulary, every format.
Express the Work across channels
An expression is a projection of what a space holds across mode, format and channel: print, digital, web, interactive, retrieval. It sits downstream of the space and never redefines it.
Processing pipeline
opus-processor extracts text, filters corrections, generates ODT and composes through typst, from the same source every other expression reads.
Recorded dispatch
A copy for a third party leaves only as a dispatch that names its recipient, its parts with their sha256 and its purpose, appended to a ledger that only grows.
Orthotypography checks
The language's catalogue is held to its checkers by standing checks: every punctuation rule of the analyzer is cited, and nothing cited is invented.
Write digests
Every operation that rewrites a source records the digest it leaves, so a migration never launders a person's edit.
What the Work gets
Declare, then implement
Before anything is expressed, the Work is declared in its own configuration and connected to the framework through a handful of stable traits.
Declare the Work
A Work's vocabulary lives only in its consumer's configuration, typed in Nickel, with English defaults in the framework. Four places carry it.
Project
projectThe Work's title and identity, read by every expression instead of being written into any of them.
Chapters
chaptersThe chapter term and the structure the Work declares, which checks can count against what actually exists.
Presentation
presentationCaptions, callout markers and the language code that selects which language rules apply to this Work.
Orthotypography
composeThe Work composes the language's catalogue: it may add or harden rules and must choose every alternative, never withdraw a mandatory one.
Implement the traits
The framework reaches the Work only through public traits. They are stable API: once a consumer implements one, breaking it requires a new trait version.
ContentLoader
Hands the framework each section as SectionContent, the one type at the boundary; the framework never reaches past it.
PedagogyEngine
The seam for a Work whose spaces teach, served through the same MCP framework as everything else.
EmbeddingProvider and VectorStore
The retrieval contracts behind local semantic search, with fastembed and tantivy as the shipped implementations.
McpServer<T>
Serves a Work to agents once its ContentLoader exists, with no Work-specific code in the server.
Which layer you are touching
The order is the domain's, not a preference: a change to a Work belongs in the first layer it concerns, and everything downstream follows from it.
The authored production
The atom of the domain: an authored, coherent whole, declared once and read by everything below it.
Where the Work is made
A book, a logbook, a workshop, educational material: each with its own sources, structure, items and editorial state.
How it reaches readers
A projection of a space across mode, format and channel. Downstream of the space, never its definition.
Where should your Work start?
Write about the Work, its spaces and the formats it must reach; the reply points to the first layer it touches.