Reads run, writes need a surer reading, and what cannot be undone always asks.
evoke sets the approval for natural-language commands by what each program changes. Reads pass on a sure reading. Writes need a surer one. What cannot be undone waits for a person every time, and no flag skips it.
The programs here are reflexes. A reflex is a small program you install and ask for in your words.
Effects
01Each program declares what it changes.
Every reflex carries an effect, written by its author. A read only looks. A
write changes something you can undo. A destructive reflex cannot be undone, or costs
something. When a manifest leaves the effect out, evoke treats the reflex as destructive.
| Reflex | Does | Effect |
|---|---|---|
open | Opens one of your folders. | read |
volume | Sets the output volume. | write |
power | Puts the laptop to sleep, restarts it or shuts it down. | destructive |
Three of the thirteen reflexes in evoke's collection for a Mac.
The bars
02The bar each effect must clear.
evoke asks the classifier every question at once and takes the least sure answer as the decision's confidence. That number is compared with the bar for the reflex's effect.
| Effect | Runs without a question at | Under the bar |
|---|---|---|
| read | 0.6 or more | asks first |
| write | 0.8 or more | asks first |
| destructive | never | always asks |
Before any of that, if the choice of reflex itself is under 0.5, nothing runs. evoke shows the ranking instead.
The classifier's provider trains its probabilities to be calibrated: across many answers, those given 0.85
should be right about 85 times in 100. evoke shows every one, and evoke test checks your own sentences.
Each bar has a default. One line in evoke.toml, a file you own, moves it for your machine. A
read may never need a higher bar than a write.
[adapters.jev] gate = { write = 0.85 }
Four outcomes
03One installed set, four outcomes.
These four sentences were decided over the Mac collection. Each ended differently, and the line before the result shows why.
$ evoke "set the volume to 40 percent" volume level="40 percent" 0.93 volume 40% $ evoke "kill the wifi" wifi state="off" · write · weakest: state 0.72 Turn Wi-Fi off? [y]es [n]o [t]each > t + overlays/wifi.toml [examples] "kill the wifi" = { state = "off" } wi-fi off $ evoke "restart the computer" power action="restart" · destructive · weakest: route 0.97 Really restart now? [y]es [n]o [t]each > n [2] $ evoke "what time is it" none 0.70 · timer 0.20 · awake 0.05 · lock 0.05 note, open and visit are inactive → evoke show [2]
- 1
volumeis a write. Its reading, 0.93, cleared the bar of 0.8, so it ran. - 2
wifiis a write too. Its least sure answer, 0.72, was under 0.8, so it asked.tanswered yes and kept the phrase as an example of yours. - 3
poweris destructive. The reading was 0.97, and it still asked.ndeclined, with exit code 2. - 4Nothing fit. evoke ranked the reflexes, ran none, and exited with 2.
These lines are what evoke printed in its tests, replayed here. The classifier's answers were written for those tests, so your own numbers will differ.
Reasons
04Every confirmation names why it stopped.
A decision stops to confirm for one of five reasons. The line before the question shows it: the effect, the least sure answer, and any further reason.
- Destructive. The reflex cannot be undone, so it always asks.
- No bars. The adapter, evoke's link to the classifier, shipped none, so nothing runs on its own.
- Under the bar. The least sure answer is under the bar for this effect.
- An unused piece. You typed a number, a duration or a quoted phrase, and no input took it.
- Two things. A second reflex fits well enough that the sentence may ask for both.
With --json, every reason that applies arrives, in order, in a list named
because, for a script to read.
$ evoke run --json power action=restart power action="restart" · destructive Really restart now? [y]es [n]o > n {"input":"","outcome":"confirm","reflex":"power","args":{"action":{"type":"option","key":"restart"}},"call":"power action=\"restart\"","effect":"destructive","prompt":{"own":"power action=\"restart\" · destructive","template":"Really restart now?"},"because":[{"type":"destructive"}],"trace":[]} [2]
power here comes from evoke's tests. These lines are what evoke printed in its
tests, replayed here.
No bypass
05No flag skips the question.
There is no --yes. Even a call you write by name, with no classifier, asks before a
destructive program runs. With no terminal to ask, as in a script or a scheduled job, the question
becomes exit code 3. evoke names the command to run yourself.
$ echo "restart the computer" | evoke a confirm needs a terminal → evoke "restart the computer" [3] $ evoke run power action=restart a confirm needs a terminal → evoke run power action=restart [3]
power here comes from evoke's tests. These lines are what evoke printed in its
tests, replayed here. To let reads and writes run unattended, set their bars in a file you own. A destructive
reflex still waits for a person.
Only stricter
06An effect can only get stricter.
Your lock file keeps the effect you agreed to when you installed a reflex. If a new version claims a
looser effect, evoke keeps the old one until you run evoke update --accept <name>. Your
own overlay may tighten an effect, from read to write or to destructive. It can never loosen one.
effect = "destructive"
From now on, turning Wi-Fi off asks every time.
In an app
07In an app, the question is a value your code holds.
The SDK returns the same decision as data before anything runs. A confirm carries the call, the
reflex's own question and every reason it stopped. It runs only when your code passes
confirmed: true. So a second person can approve it later, from a queue, over the same
reflexes and the same words.
switch (d.outcome) { case "run": await project.run(d); break case "confirm": if (await ui.confirm(d.prompt.template)) await project.run(d, { confirmed: true }); break case "ask": project.fill(d, await ui.pick(d.missing)); break case "abstain": ui.say(d.contenders); break }
The SDK's first release on npm is on its way. Until then, the terminal route runs today. See a payment wait for a second person →
Limits
08What this gate does not cover.
- It gates what evoke chose from a sentence. It is not a guard around the calls another agent makes.
- Above its bar, a read or a write runs on the classifier's reading, without a question. Set the bars for what matters to you.
- A reading can be wrong. The bar decides how much can happen on one.
- The effect is the author's claim. A reflex runs as you, and there is no sandbox yet, so read what you install.
- In a sentence of several steps, a step that already ran is not undone when a later one stops.
See the question before anything runs.
On a Mac with the collection, evoke try shows what a sentence would do, and runs nothing.
evoke try "restart the computer"