Proposing a change
Up to here a tree has been something you wrote. This is the part where somebody else asks for one to change, and the runtime decides what happens next.
The short version: nothing edits a page directly. An ask becomes a written proposal, the proposal is examined, and only then is anything applied. Every example on this site has that whole sequence behind it, and you can run it.
Hello from a tree
Nothing here was written as markup.
Every one of these goes through the same pipeline a model’s answer would: interpreted, analysed, weighed, judged, applied, appended. The log is real and it is in this tab — reload the page and the example is back as it was.
show the treehide the tree
{
"kind": "element",
"id": "n_firsttree5",
"type": "loom.page",
"props": {
"fills": true,
"width": "readable",
"loom:theme": {
"palette": "minimal",
"fontPack": "minimal-sans",
"stylePreset": "precise"
}
},
"children": [
{
"kind": "element",
"id": "n_firsttree2",
"type": "loom.heading",
"props": {
"level": 1
},
"children": [
{
"kind": "text",
"id": "n_firsttree1",
"value": "Hello from a tree"
}
]
},
{
"kind": "element",
"id": "n_firsttree4",
"type": "loom.prose",
"props": {},
"children": [
{
"kind": "text",
"id": "n_firsttree3",
"value": "Nothing here was written as markup."
}
]
}
]
}Click a chip. What appears underneath is not a description of what would happen — it is what happened, printed out of the same functions a production deployment calls.
The four steps, in the order they happen
1. Somebody asks for something. That ask is an intent: a sentence, plus who is asking and which page they are looking at. The sentence on the chips above is the intent's own words.
2. Something turns the sentence into a plan. The plan is a delta — a short list of operations against the page as it is right now. There are four verbs and no more:
| Verb | What it does |
|---|---|
insert | puts a new node under a parent, at a position |
remove | takes a node out, and everything under it goes too |
move | puts an existing node somewhere else, unchanged |
configure | sets or clears props on one node |
You can read the delta for yourself in the box: every operation names a node by its id, so a change is a list of small edits to specific things rather than a new version of the page to diff against the old one.
3. Something judges the plan. That is the Gate, and it is the next page.
4. If the Gate allows it, the delta is applied and the page has a new revision. If not, the tree is exactly as it was — a refusal changes nothing.
Who writes the plan
Step 2 is the only step in the sequence that has to guess, and it is the only one Loom lets you swap. The thing that does it is a change interpreter, and the runtime does not care what is behind it:
type ChangeInterpreter = {
interpret: (intent: EditIntent, tree: LoomTree) => Promise<Result<ProposedChange, …>>
}
Two of them ship. modelInterpreter asks a language model, which is the case
Loom exists for. The other computes its operations from the tree with no model
at all — which is what every chip on this site uses, and why the examples work
in a browser with no API key, no server and no network.
Connecting a model is the whole of the first one: the exact text a model is shown, what it is allowed to say back, and what a request costs.
Everything after step 2 is unable to tell the difference. The proposal records which one wrote it, and the Gate judges both by the same rules.
What a proposal carries
A delta is the plan. The proposal around it is the paperwork, and every field on it is there because someone downstream reads it:
rationale— why these operations answer that ask, in the interpreter's own words. It is what a human reviewer reads when the Gate holds the change.provenance— who asked, what interpreted it, and how confident that interpreter is in its own answer. The chips on this site report a confidence of1, and that is not a boast: their operations are computed rather than guessed, and the record saysauthoredBy: "runtime"so nobody counts them as a model's perfect score.baseRevision— the revision of the page this plan was written against. A proposal written for revision 3 does not apply to revision 4 by accident; it is refused as inapplicable, with a reason.
Click the same chip twice in the box above and watch the revision number in the frame's header go up. The second proposal is planned against the page as it is after the first — not against the page the button was drawn on.
And then it is recorded
Step 4 has a second half. A change the Gate allowed is not only applied — it is appended to a log, which is what makes a page's history readable, attributable and undoable.
The box above has one. Press a chip and look underneath the verdict: there is a row there, and it says who asked, what planned it, and what it did. That is the next page.
What matters here is that everything above is true either way — the tree in this browser tab and a tree in Postgres go through the same four steps, in the same order, judged by the same rules.