Lua 5.4 · LaTeX maths · Chromium
Serious research happens in a tool designed for shopping, and the only thing anyone has added to it is a box that answers one question and forgets. Ohm puts a language in the browser instead — so the method is written down, priced before it runs, and the same next month.
Free. Models run locally by default — nothing leaves the machine until you turn on a switch that ships off.
One minute, captured from a real build: three shops read at once, and the answer you cannot get by looking.
Ask a chat assistant to compare two companies on two topics and it decides, invisibly and differently each time, how many searches to do, what to read and what to drop. Every one of those decisions is a place it can be wrong, and none of them is written down anywhere you can look.
# Two companies, two questions. The whole program. sites = [apple, nvidia] topics = [latest earnings, layoffs] jobs = sites × topics found = search(jobs, k: 3) brief = summarize(found, words: 60) table(brief)
$ npm run volt -- volt/02-research.volt
· "apple"
· "nvidia"
sites [] list("apple", "nvidia")
· "latest earnings"
· "layoffs"
topics [] list("latest earnings", "layoffs")
jobs × cross(sites, topics)
found ∀ Search(jobs; k=3)
brief ∀ Summarize(found; words=60)
→ table(brief) ⟵ output
10 nodes · at least 1 model call(s) · at least 1 page load(s)
A parser reads that — a real parser, no model involved — and produces a graph. Of the ten nodes, exactly one calls a model.
The model is not the author of the control flow. The product, the fan-out, the ordering and the table are determined by the text you wrote; the model fills named slots you can inspect.
Operators exist to constrain it with something outside itself — \Ground
rewrites an answer to what the sources support, \Cite attaches the sources,
\Verify returns true or false.
Building the graph executes nothing, so you can look at the program and at what it will cost before committing to it. The estimate is a floor and says so; the interpreter reports the real number afterwards.
A chat box cannot show you this, because until it answers there is nothing to show.
Re-running after an edit recomputes the branch under what changed and reuses the rest. The artefact is a file: diff it, review it, hand it to a colleague who runs it and gets your result.
A transcript cannot be any of those things.
The same six-line program, run twice — the second time with words: 60
changed to 30.
| Nodes computed | Reused | Pages fetched | Model calls | |
|---|---|---|---|---|
| First run | 10 | 0 | 4 | 4 |
| After the edit | 2 | 8 | 0 | 4 |
| With no edit at all | 0 | 10 | 0 | 0 |
Read the third column. The searches are not repeated, because nothing they depend on changed — and the planner knew that, and said so, before the second run started.
Every number here is produced by npm run check, so if one of them is wrong the build says so.
The honest limit. None of this makes a model truthful. A summary can still
misread the page it was given, and \Ground is itself a model call that can be wrong.
What the mathematics buys is that the error is contained in a named node, visible in the graph, attached to the sources it claims and re-runnable against them — instead of dissolved into a paragraph of confident prose with no structure to audit. That is a much smaller claim than “no hallucination”, and unlike that claim it is true.