Ohm specifications#

A hierarchical specification of every feature, written from a review of the code and detailed enough to rebuild the product from. Each spec states what the code does, which invariants a reimplementation must preserve, and what the review found wrong.

The specs#

Spec Covers
00 Product What Ohm is, the cross-cutting decisions, the map
01 Engine seam and browser shell The replaceable engine, tabs, hidden tabs, schemes, the UI↔core protocol, automation
02 The Ohm language Lua + LaTeX syntax, compilation, the runtime, the host API, operators
03 Scripts The scripts folder, explorer, editor, console, run lifecycle
04 Models, settings and credentials Five providers, encrypted secrets, the models folder, Hugging Face
05 Prompt management Versioned templates, typed variables, diffs, the playground
06 Experiment management Datasets × sweeps × profiles, evaluators, runs, statistics
07 Curves and typed variables Piecewise curves, the expression language, typed outputs, sweeps
08 Projects and deep research Project storage, links, templates, the research pipeline
09 Graph editor Components, profiles, the graph→Ohm compiler
10 The spec editor The spec tree itself, references, AI actions, markdown
11 Documents and annotations PDF, Word, spreadsheet, slide, image and text viewers
12 Storage, bundles and the mirror Files first, bundles, IndexedDB backup
13 Packaging and installers The build, staging, the Windows wizard, the macOS DMG
14 The Context tab Open tabs, page structure as data, set algebra over tabs, exports
15 Apps and capabilities The app folder, the manifest, the capability model and its enforcement

How they are written#

Specs are authored as data, not prose files. Each source in src/ exports { name, description, nodes } built from the helpers in src/_lib.mjs:

section('Tabs', [
  n('requirement', 'Focus follows Chrome’s rule', `…body…`, {
    tags: ['regression'],
    refs: [ref.node('tab-lifecycle')],
  }),
])

npm run specs turns every source into two artefacts:

  • <name>.spec.md — rendered by the product's own specToMarkdown, so the docs look exactly like what the spec editor generates.
  • <name>.spec.json — a SpecDoc, openable in Ohm's spec editor.

npm run check:specs (part of npm run check) validates that every node: reference resolves within its document and every spec: reference names a real spec, and fails if the committed output is stale.

Reading them#

Each node carries a kind (requirement, decision, data-model, flow, api, component, test, risk, task, note) and a status. The convention here:

  • done — describes code that exists today.
  • todo — describes work that does not exist yet, including everything the review flagged.

So the progress percentage in each spec's front matter is a rough measure of how much of that spec is actually built, and the risk and task nodes are the backlog.

Tags mark why a line matters: regression (this was a real bug once), gotcha (surprising but correct), security, correctness, data-loss, safety.

Opening a spec in Ohm#

The .spec.json files are ordinary spec documents. To edit one inside the app, copy it into a project:

cp docs/specs/02-ohm-language.spec.json "$HOME/Documents/Ohm/projects/<project-id>/specs/"

It then appears under Specs in the Projects panel, with the tree editor, references, history and markdown generation. Editing it there and copying it back is a one-way trip — the generator owns docs/specs/*.spec.{json,md}, so lasting changes belong in src/.