VOLTAreference

Reference / Work in Studio

Write music with explanations

Work in Studio

Open in the workbench →
On this page · 6 sections

Combine a song's source with prose so the musical decisions and the code can be read together.

Executable documents: markdown prose with live, editable Volta code cells. Design spec: Write music with explanations.

The standalone reader page was deleted 2026-08-21, along with the TypeScript notebook page, its markdown renderer and its headless e2e; see git history. The .volta.md format, the corpus under runtime/public/notebooks/, the pure model (notebook-doc.ts) and the content validator all still ship, but nothing reads a .volta.md today. The workbench's bench notebook is a .volta file whose top-level -- comment runs are markdown — the same prose subset, rendered by ui/src/md.rs; see Tell a story with a song. This page documents the .volta.md format and the cell contract the validator still enforces.

The format#

A notebook is a plain markdown file named *.volta.md. Three fence kinds:

FenceMeaning
```voltaa live cell — editable in the reader, has ▶
```volta noruna display cell — code styling, never compiled
any other ```ordinary static markdown code

Prose supports headings #–#### (the Rust renderer reads up to ######), paragraphs, -/1. lists, > quotes, --- rules, `code`, **bold**, *italic*, and [links](…) (http/https/mailto/relative only). Raw HTML is escaped, never rendered.

Cell semantics (the contract)#

  1. Cumulative concatenation. Cell N compiles as cells 0..N joined (current editor text, blank-line separated) into ONE module. Later cells see every earlier binding.
  2. One introduction per name. Because of (1), redefining a binding in a later cell is a duplicate-binding compile error. Author each concept as a new name (pluck, then a template glow = patch from pluck { … }).
  3. ▶ plays what the cell defines. The tracks/songs bound at column 0 in that cell; a song wins over tracks; a cell defining neither plays the whole cumulative module. One cell at a time — starting a cell stops the previous one.
  4. Edits are always honored. The cumulative source is reassembled from the live editors on every ▶; editing cell 1 changes what cell 7 plays.

Reader URLs#

Gone with the page (2026-08-21). The reader served an index from /notebooks/index.json, ?nb=<id> (a manifest notebook) and ?src=<path> (any raw .volta.md the dev server could see). Nothing serves /notebooks/ today.

Shipping a notebook#

  1. Write runtime/public/notebooks/<id>.volta.md (title = first # line).
  2. Add { id, title, description, file } to runtime/public/notebooks/index.json.
  3. cd runtime && npm run test:notebooks — every runnable cell must compile cumulatively (this runs in make test and make test-fast). The two shipped notebooks: welcome (the language tour) and flume-resample (the bounce workflow, from docs/notes/flume.md).

Authoring gotchas (found shipping the first two)#

  • play p (slow 2 !"…") does not lower (slow takes the pattern FIRST) — write the corpus idiom play p (!"…" |> slow 2).
  • A cell that should show code without compiling (an intentionally incomplete fragment) is ```volta norun — a bare ```volta fragment would fail the validator.
  • Keep shipped notebooks import-free until the validator grows a lib-dir bundle.

Code map#

runtime/src/notebook-doc.ts (pure model — parser/assembly/attribution, unit tests in runtime/src/notebook-doc.test.ts) · validator runtime/scripts/validate-notebooks.mjs (content, in make test-notebooks) · ui/src/md.rs (the shipped Rust renderer for the same prose subset). The reader page, its TypeScript markdown renderer and its headless e2e were all deleted 2026-08-21; see git history.