About Opus
A Rust framework for the knowledge-works domain. A Work is an authored, coherent whole; Opus provides the machinery to express it across modes, formats and channels, and keeps every Work-specific word out of its own code.
Where Opus comes from
It started as a book system. Its first consumer was a printed book, and the framework grew from extracting, correcting and composing that book's text into reusable crates for document processing, AI suggestions, semantic search, MCP serving and file watching.
As it matured, the name drifted while the model did not: the schema already treated the Work as the unit. The first decision made that explicit. The domain's essence is the Work, and dissemination across print, digital, web and interactive is its expression, never its definition.
The second decision named the domain for its atom. The Work is the authored production, not the book: a book, a logbook, a workshop and educational material are spaces of one Work that coexist, and the order a consumer declares in is Work, then space, then expression. The domain is Opus.
Invariants
- ✓ No project logic in the framework: a Work's vocabulary comes from its consumer's configuration
- ✓ Public trait stability: breaking a trait a consumer implements means a new trait version
- ✓ Consumer inversion: the dependency arrow points from consumer to framework, never back
- ✓ Zero-warning CI gate: clippy with warnings denied stays green across the workspace
- ✓ Section content contract: SectionContent is the only type at the framework/consumer boundary
The crates
What the framework ships, behind stable traits
Processing & editorial
- ODT generation
- Text extraction
- Correction filtering
- typst composition pipeline
- Editorial analysis gated by the Work's language
Agents & suggestions
- McpServer<T> framework
- ContentLoader and PedagogyEngine traits
- ChapterConfig for a Work's structure
- AI suggestion generation
- Suggestion merge strategies
Search & watch
- Local embeddings with fastembed (ONNX)
- Full-text index with tantivy
- VectorStore, EmbeddingModel and Retriever contracts
- File watcher configured from the environment
- Watcher status persisted to .watcher/status.json
Why the Work is the unit
📖 One coherent whole
Print, digital, web and interactive are expressions of the Work. None of them is allowed to become its definition.
🧭 A declared order
Work, then space, then expression. Each format is projected from a space and sits downstream of it.
🔤 Language rules where they belong
A rule every Work in a language needs lives in the framework; a word only one Work uses lives in that Work's configuration.
📚 Cited orthotypography
Every rule cites its source by chapter and section and names the checker that holds it. A checker is cited, never an authority.
🧾 Evidence that survives
A toolchain write records the digest it leaves, so an edit by a person and a migration by a tool are never the same evidence.
✉️ A recorded dispatch
The Work reaches a third party only as a dispatch appended to its ledger; a personal copy always goes to whoever asks for it.
Build a Work on Opus
Opus is consumed through path dependencies by implementations that each serve one Work. Start from the adoption path, or write to talk about yours.