# Tuning

A reflex ships its wording. You own the last word. Every change lands in a file under your project. `evoke`
writes it with your comments and order kept, and every later decision reads it. No command here needs the
classifier's key but `test`, which asks it.

## `show`: what is installed, and one reflex as used

```text
$ evoke show
  lights  radhi/home/lights 1.2.0  write  runs lights.mts
  timer   radhi/timer 1.0.1        write  runs timer.mts
  inactive  lights: HUE_TOKEN is not set  →  export HUE_TOKEN=<value>
```

`evoke show <name>` prints the reflex's **effective** manifest: the shipped one with your overlay merged in. It
prints TOML, one key per line, with `+` next to every line that is yours: A line of your overlay that addresses nothing the reflex has, an argument it
dropped, is listed after the manifest as skipped, as `update` reported it.

```text
$ evoke show lights
  description = "Turn the lights in one room on, off, or dim them.\nCeiling and lamp lights only."
  …
  [args.state]
+ ask = "On, off or dim?"
  options.on = "Switch on."
  …
  [examples]
  "turn on the kitchen lights" = { state = "on" }
+ "kill the lights" = { state = "off" }
```

## `teach`: one line in your overlay

```text
$ evoke teach "kill the lights" lights state=off
+ overlays/lights.toml  [examples] "kill the lights" = { state = "off" }
$ evoke teach "what time is it" not timer
+ overlays/timer.toml  [examples] "what time is it" = false
$ evoke teach lights state=dim
+ overlays/lights.toml  [examples] "dim the office" = { state = "dim" }
```

- `evoke teach "<utterance>" <call>`: the utterance means this call. The call uses the same grammar `evoke`
  prints, `name arg=value…`. Only what you assert is recorded. `lights state=off` teaches the route and `state`,
  and leaves `room` to the input.
- `evoke teach "<utterance>" not <name>`: the utterance is never this reflex.
- `evoke teach --forget "<utterance>" <name>`: the line your overlay holds for the utterance, an example or a
  test, is removed; the shipped wording stands again. One not there is refused.
- A phrase the reflex's examples already hold with the same values is said to be one, and nothing is written.
- Leave the utterance out, and it means the last input you gave. Say something, see it decided, then
  `evoke teach lights state=dim` corrects it. After a sentence of several steps, it means the step the lesson's
  reflex decided; when none or several did, `teach` names the steps and asks you to say which.
- A one-word utterance needs no quotes: `evoke teach dim lights state=dim`. The first word is the utterance when
  a call follows it, unless the word names an installed reflex. Then the call begins with it.
- `[t]each` at a confirm prompt does the same for the input just decided.

A value is checked at the door. A word the vocabulary lacks, an option not offered, or an argument the reflex
does not have is refused, with the command that shows what is allowed.

## Overlays

`overlays/<name>.toml` is your wording for one reflex, in the manifest's own shape. It is merged over the shipped
one by **one rule: tables merge by key, and every value replaces whole.** An overlay adds and replaces. It never
deletes.

```toml
# overlays/lights.toml
description = "Turn the lights in one room on, off, or dim them."      # replaces the shipped text whole

[args.state]
ask = "On, off or dim?"                                                # new wording for an argument
options.dim = "Lower the brightness; the lights stay on."              # new wording for an existing option

[examples]
"kill the lights" = { state = "off" }                                  # sent to the classifier

[tests]
"turn on the kitchen lights" = { state = "on" }                        # a shipped example, moved here: held out now
```

What you may change is **wording**: `description`, `not_for`, `tags`, `confirm`, each argument's `ask`, the
meaning of its existing options, examples and tests. What you may not change is the **contract**: what the reflex
runs, its argument names, option keys, sources and ranges. A contract key in an overlay makes the reflex inactive,
and names the line to remove.

- The highest layer that names an utterance decides its table and its value. Move a shipped example under
  `[tests]`, and it is no longer sent. `= false` rejects it.
- `effect` in your overlay may **tighten**: `write` over `read`, or `destructive` over either. It may never
  loosen. A loosening line makes the reflex inactive.
- Lists, like `not_for` and `tags`, replace whole.
- Your records may assert vocabulary arguments, like `{ room = "den" }`. Shipped manifests may not.
- Wording in another language is just an overlay.

At `update`, an overlay follows a declared rename. `evoke` reports what went **stale**: you override something
upstream changed, and yours wins. It reports what is **orphaned**: a line of yours addresses nothing now, and is
skipped. An overlay that fails to parse makes its reflex inactive, never silently looser.

## Vocabularies

`vocab/<name>.toml` is a closed list of your words. Every argument that names the vocabulary shares it. A package
never ships or writes one. A reflex whose required argument reads an empty vocabulary stays inactive until you
fill it; an optional one is simply never stated.

```toml
# vocab/rooms.toml
den    = "The TV room downstairs; also 'the snug'."
office = { what = "The upstairs study.", value = "group-7" }
```

The **meaning** is what the classifier reads, so other names for the thing help. The **value**, when set, is what
the program receives instead of the word. The classifier never sees it. It can be a path, a URL, or a device id.

```text
$ evoke vocab rooms
  den = "The TV room downstairs; also 'the snug'."
  office = { what = "The upstairs study.", value = "group-7" }
$ evoke vocab rooms add attic "The loft upstairs." --value group-9
+ vocab/rooms.toml  attic = { what = "The loft upstairs.", value = "group-9" }
$ evoke vocab rooms remove attic
- vocab/rooms.toml  attic
```

`add` of a word already there replaces its meaning. A word may contain spaces. `none` and `unstated` are
reserved. At an ask over a vocabulary, `+` adds a word without leaving the prompt, its path too when a reflex
declares the word's value as one it reads or writes.

## `config`: settings and secrets

A manifest declares under `[config]` what it needs from you. Each setting lands under `[config.<name>]` in
`evoke.toml`. A reflex with a setting unset stays inactive.

```text
$ evoke config lights bridge 10.0.0.2
+ evoke.toml  [config.lights] bridge = "10.0.0.2"
$ evoke config lights token hue-example
  lights: config "token" is a secret; it is set from a variable  →  evoke config lights token --env <VAR>
[3]
$ evoke config lights token --env HUE_TOKEN
+ evoke.toml  [config.lights] token = { env = "HUE_TOKEN" }
```

A setting a declaration reads or writes as a path, `writes = ["{file}"]`, is looked for: one that is not there
yet is said, and the body waits for it. A **secret** is only ever set with `--env <VAR>`. Your file names the variable. The value reaches the program
from the environment at run time, and nowhere else. `--env` works for any key. An undeclared key is refused, with
`evoke show <name>`, which lists what the reflex declares.

## `test`: every record, judged

```text
$ evoke test
  lights  3 passed · 1 failed
    "make it darker in here"  state: expected "dim", read "off"
  timer   8 passed
    "ping me in 2 hours"  passes, but would wait for a yes: the call holds all of it at 0.20, and a call runs at 0.30 or more
  1 of 12 cases failed  →  evoke test
[1]
```

`evoke test [<name>]` decides every example and every test of every active reflex, or of one. It decides against
the whole installed set, a few cases at a time, never through the cache. It judges each case on its route and its asserted arguments. It
exits 1 when a case failed, so a script can act on it. It never blocks an install. A case that passes while its
call would wait for a yes, holding less than the case's own words, is named under its reflex and fails nothing
([Records](../author/records.md#evoke-test)).

A case typed in a language other than English puts a line before the reflexes, one per such language, with how
many of its cases passed and failed ([Languages](languages.md)). A case that passed last time and fails now is
decided twice more. Failing two of three marks it `· regression`.
The last verdicts are kept per installed set, on this machine. What the confidence beside each call meant on the
same records is `evoke calibrate`'s answer: [Calibrating](calibrating.md).

## Thresholds

Everything engine-specific lives under the adapter's own table, so one dotfiles repository serves machines on
different engines:

```toml
[adapters.jev]
gate = { route = 0.5, read = 0.85, write = 0.95, whole = 0.4 }
```

The `openjev` adapter takes the same table under `[adapters.openjev]`. Both reach Jev, so the numbers mean the
same. Each number means *the probability this is right*. `read` may not exceed `write`. `whole` is the third
bar: a call that cleared its effect's bar is read back against your sentence, and runs when it holds all you
typed at `whole` or over; raise it and more calls wait for a yes with the words they leave out named, lower it
and fewer do. Destructive reflexes always confirm. [Outcomes](outcomes.md#what-confidence-is) explains what the
numbers gate, and [Calibrating](calibrating.md) measures each bar on your own records.

The `clef` and `clef_flash` adapters reach Clef, Cloudflare's model. They ship no bars, so every call through
them waits for a yes. To let calls run, give all three of `route`, `read` and `write` in the `gate` of
`[adapters.clef]` or `[adapters.clef_flash]`. `whole` and `fits` are yours to add. Choose the numbers from your
own records, which `evoke calibrate` measures. [Environment](../reference/environment.md) lists the two variables
these adapters read.

**Next:** [Calibrating](calibrating.md).
