evoke

Examples · 03 of 06

Run kubectl operations in your team's words.

Natural-language commands for the operations your team approved. A reflex is a small program you install and ask for in your words. Your team writes one per operation, and only those can run. Your service names fill in kubectl's arguments. A scale runs when evoke is sure enough, and a rollback asks every time.

The request and the result

01

A scale runs. A rollback waits for a yes.

Four sentences typed in the ops project, the directory that holds these reflexes. Jev, TypeSafe AI's model, read each one and gave every answer a probability. A change runs without a question only when every answer is at least 0.9, the default. Recorded on 21 September 2026.

~/ops
$ evoke "silence db-3 for 2 hours" silence host="db-3" duration="2 hours" 0.99 db-3 silenced until 01:12 AM
  1. 1kubectl, and no code. The scale reflex is only a manifest, the reflex.toml file that describes it. It names kubectl and its arguments, and the sentence fills them in.
  2. 2Your names become kubectl's values. «checkout» is a word in your list, and its value is checkout-api. The classifier reads the word and its meaning. kubectl gets the value.
  3. 3A rollback cannot be undone, so it asks. «weakest: service 0.99» names its least sure answer, the service. evoke was that sure, and it still asked. Every value is one your lists allow, but a reading can still be wrong.

Why the rollback asked at 0.99 →

The operations

02

The scale reflex as a manifest, as code, and in an app.

The scale manifest around kubectl, your service names in a file, and an app of nine lines that runs one sentence. In code, the manifest becomes an object, and with() passes your names to it.

scale/reflex.tomlthe author's
reflex = 1

description = """
Scale a service to a number of replicas.
One deployment in one environment; the number is set, never added to."""
not_for = [
  "restarting or rolling back a service",
  "resizing a database or a disk",
  "autoscaling rules",
]
tags    = ["ops"]
effect  = "write"
confirm = "Scale {service} in {env} to {replicas}?"
run     = [
  "kubectl", "-n", "{env}", "scale", "deployment", "{service}",
  "--replicas", "{replicas}",
]

[needs]
writes = ["~/.kube"]                   # the kubeconfig, and kubectl's cache beside it
hosts  = ["*"]

[args.service]
ask   = "Which service?"
vocab = "services"

[args.env]
ask   = "Which environment?"
vocab = "envs"

[args.replicas]
ask   = "How many replicas?"
pick  = "number"
range = [1, 20]

[examples]
"scale checkout to 6 in staging"   = { replicas = "6" }
"run 3 replicas of search in prod" = { replicas = "3" }
"take payments down to 1 replica"  = { replicas = "1" }

[tests]
"bring checkout up to 12 in prod" = { replicas = "12" }
"scale checkout"                  = { replicas = false }
"restart checkout"                = false
vocab/services.tomlyours
checkout = { what = "The checkout API.", value = "checkout-api" }
search   = { what = "The search API.", value = "search-api" }
payments = { what = "Payments; also 'the gateway'.", value = "payments-svc" }
  1. 1A reflex that runs a program directly needs no Node. evoke starts kubectl itself with its arguments, never through a shell. Each placeholder, such as {service}, fills one whole argument. A value that starts with a dash is refused.
  2. 2silence and rollback have the same shape. silence reads a duration from the sentence and a host from your words. rollback is marked destructive.
  3. 3The app asks through two handlers. One asks for a yes or a no. The other offers a numbered menu for a missing value. Both live in terminal.ts, which the ops and runbook apps share.

One boundary

03

A missing environment is asked for, from your own list.

The sentence named the service and the number, but not where. evoke offered the environments you listed, then checked the call again with your answer.

evoke
$ evoke "take payments down to 1 replica"
  Which environment?  [1] staging  [2] prod  [+] add one  > 2
  scale service="payments" env="prod" replicas="1"  0.95
deployment.apps/payments-svc scaled

The choices are the words in vocab/envs.toml. With no terminal attached, as in a cron job, evoke cannot ask. It prints the command to run yourself and exits with code 3. A file of requests: the inbox example →

Set it up

04

Build the scale reflex from this page, then type one sentence.

scale is shown whole above, and it runs kubectl itself, so the terminal route needs no Node. kubectl changes your cluster for real, so point your words at a deployment you may scale.

  1. Make the project

    A folder with an evoke.toml file is a project, and adapter = "jev" has Jev read its sentences. Then save the manifest from the files tab above as ~/ops/scale/reflex.toml.

    mkdir -p ~/ops/scale && cd ~/ops && echo 'adapter = "jev"' > evoke.toml
  2. Trust it, and add the reflex

    evoke decides in a new project only after you trust it once. The add checks the manifest and prints one row: scale runs kubectl. It stays inactive until its two lists have words.

    evoke trust
    evoke add ./scale
  3. Put in your words

    The word is what you type, and the meaning is what the classifier reads. The value is what kubectl gets: here the deployment checkout-api. A word with no value, like staging, passes the word itself as the namespace. Put your own deployments and namespaces in place of these.

    evoke vocab services add checkout "The checkout API." --value checkout-api
    evoke vocab envs add staging "The pre-production cluster."
  4. Look at a decision before it runs

    evoke try decides and runs nothing. It shows the ranking, the answer for each input, and what would happen.

    evoke try "scale checkout to 6 in staging"
  5. Type the sentence

    evoke prints the call it chose and how sure it was, then kubectl's own line. kubectl changes the cluster for real.

    evoke "scale checkout to 6 in staging"

To add an operation, copy scale/ to a directory of its own, then change its description, its examples and its run line. evoke add ./<name> checks the manifest, and warns when the new reflex would win a phrase that belongs to another one.

In your app

05

The same reflex, from a Node application.

app.ts loads ~/ops: its evoke.toml, the scale reflex and your words. It runs the manifest, so kubectl gets the same five variables as at your terminal. It needs Node 24.5 or newer, and ES modules.

npm init -y && npm pkg set type=module
npm install @evoke-build/evoke
node app.ts "scale checkout to 3"
  1. 1Save app.ts in ~/ops, and terminal.ts in the folder above it. app.ts imports its two handlers from there.
  2. 2The sentence names no environment, so the app's menu offers the ones you listed. kubectl then scales for real.