Source
What humans and agents edit. Plain text, clean Git diffs, stable IDs.
Markdown is excellent at the lightest end of the document spectrum. HTML is excellent at the rendering end. The space between them — structured documents that humans still want to read in source — is where Noma lives.
Every Noma document has three layers stacked on top of each other:
What humans and agents edit. Plain text, clean Git diffs, stable IDs.
What humans consume. Standalone HTML, PDF, EPUB. One file you can share.
What AI systems use. Deterministic LLM export, less noisy than HTML, more structured than Markdown.
The same source feeds all three. You write once; Noma renders into the form your reader needs.
Noma asks you to learn two new pieces of syntax — ::block{attrs} for typed blocks and [[block-id]] for cross-references — in exchange for native layout, semantic blocks, validation, and an agent patch protocol. If your document is six paragraphs and a code fence, Markdown is still the right answer. If it has claims, evidence, plots, decisions, and a quarterly review task attached, Noma starts paying for itself by the third edit.
Noma documents are trees of typed blocks. Each block knows what it is, what it contains, and how it should render across HTML, PDF, and LLM context.
::claim{id="claim-living-docs" confidence=0.9}
Documentation rots faster than the code it describes.
::
The opener carries the type (claim), an attribute list (id, confidence), and the body content. The closer is a bare :: on its own line. Children get one more colon than their parent — :::card inside ::grid, ::::tab inside :::tabs.
A claim is not a risk is not a decision. The validator can reason about them differently — claims should have backing evidence, risks should have an owner, decisions should have a status. Themes can render them with different visual emphasis. Agents can patch them by ID without touching unrelated text.
You can do most real work with about a dozen blocks: section, paragraph, code, list, quote, table, callout, grid, card, claim, evidence, risk, agent_task. The rest are convenience.
The single most important question this format answers is: can an AI agent edit my document without breaking it?
The answer in Markdown is "sort of, if you're lucky." The answer in HTML is "no." The answer Noma is built to give is yes, by construction.
Agents propose operations, not full-file rewrites. Five ops cover most editing flows:
| Operation | What it does |
|---|---|
replace_block | Swap a single block by ID |
add_block | Insert a new block under a parent |
delete_block | Remove a block by ID |
update_attribute | Change one attribute on one block |
rename_id | Move an ID, retargeting every reference |
noma patch thesis.noma --op '{"op":"update_attribute","id":"asml-euv-moat","key":"confidence","value":0.9}' --inplace
The CLI parses, applies, re-serializes via the source printer, and writes back. The unrelated 95% of the file is byte-identical to where you left it.
The patch protocol is the third leg of the-three-layers introduced in chapter 1: source, artifact, agent context. Without it, the agent layer is read-only.
# patch a real demo
noma patch examples/thesis.noma --op '{"op":"update_attribute","id":"asml-euv-moat","key":"confidence","value":0.95}'
# render this book to a single HTML page
noma render examples/book/book.noma.yml --to html --out dist/book.html
# pipe the LLM context to your agent of choice
noma render examples/book/book.noma.yml --to llm
Re-read this book once a quarter. If a paragraph still describes the format and CLI accurately, leave it. If the CLI has new commands or block types, file a replace_block patch op and a follow-up commit. The book is meant to age in lockstep with the code.