Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Playbooks

A playbook is a reflex whose body is a plan: steps, one sentence per step in the order they happen, and no run. A person reaches it with a short sentence, routed by your description, not_for and examples like any request. Each step is then decided over what that person has installed, as a typed sentence would be, and the whole plan prints before anything runs.

reflex = 1

description = """
Handle a service outage.
Looks at the service's errors, deploys and logs, finds the release behind it, rolls it back, tells the incident channel and updates the status page."""
not_for = ["one lookup on its own", "an incident's postmortem", "a service that is healthy"]
confirm = "Run the outage plan for {service}?"
steps = [
  "check {service}'s errors[ in {region}]",
  "list {service}'s deploys[ in {region}]",
  "search {service}'s logs[ in {region}]",
  "find the release behind it",
  "roll {service} back from that release[ in {region}]",
  "post to the incident channel",
  "update the status page for {service}",
]

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

[args.region]
ask      = "In which region?"
vocab    = "regions"
optional = true

[examples]
"payments is down in us-east" = {}
"search is broken"            = {}

[tests]
"checkout is failing in eu-west" = {}
$ evoke "checkout is failing in eu-west"
  1  errors service="checkout" region="eu-west"  0.90 · outage 1
  2  deploys service="checkout" region="eu-west"  0.90 · outage 2
  3  logs service="checkout" region="eu-west"  0.90 · outage 3
  4  suspect  0.90 · takes errors from 1, deploys from 2, logs from 3 · outage 4
  5  rollback service="checkout" region="eu-west" · takes release from 4 · outage 5
  6  post channel="#incident"  0.90 · outage 6
  7  status component="checkout"  0.90 · outage 7 · service as component
  outage service="checkout" region="eu-west" · destructive · weakest: route 0.90 · also errors (fits 0.60), step 1
  Run the outage plan for checkout?  [y]es [n]o [t]each > y

Every line of the plan ends with the playbook and the step that wrote it. Then comes the sentence's own line, the decision that picked the playbook, and one question over the whole plan. A step that takes a result waits for the steps it takes from, as in any sentence of several steps (Weaving).

A plan of sentences

A playbook is fetched, locked, tested, overlaid and shown like any reflex. What differs is the body: steps instead of run, and none of a body's keys, [needs], [config], [yields], returns or platforms. A plan holds at most 24 steps. Its effect is your claim about the whole; add says when a step reaches a tighter one.

Slots

A slot, {service}, is an argument of [args]: a vocabulary word, an option or a pick, never a flag. It is filled from the sentence, or asked before the plan prints, and written into the step as the person typed it, an option as its key. A word beyond the slots fills nothing. A value is never the playbook's own: a word the person lacks joins their vocabulary with [+] add one. Words in square brackets go only with the slot inside them: [ in {region}] is written when a region was stated and dropped when it was not. An optional argument stands only in a bracket; a required one never does.

$ evoke "we have an outage"
  1  outage · asks service
  Which service?  [1] checkout  [2] payments  [3] search  [+] add one  > 2
  1  errors service="payments"  0.90 · outage 1
  …

Every step is decided when the plan is made

A step is decided by the classifier over what the person has installed, from its words alone, as a typed sentence would be. So name no reflex: describe what should happen, one action per step. A word another team would change, a channel or an address, is better described than written: post to the incident channel reaches whatever channel their vocabulary holds for it, and lint flags a step that states one. A step may reach another playbook, once. A step that reaches the playbook it stands in is refused, so word a step apart from your own examples. A step no reflex matches refuses the whole plan before anything runs:

  4  "find the release behind it" · no reflex
[2]

evoke add shows what each step reaches on the set it joins, and evoke test fails a step that reaches nothing (Examples and tests).

One yes over the whole plan

Nothing runs before the whole plan is printed and one yes is given over it: your confirm when the plan is your playbook's alone, Run the plan as it stands? when the sentence holds more. A step's own confirm, a destructive one's above all, is asked again at its turn, every time. [t]each at the whole-plan question teaches the route to your playbook; at a step's turn it teaches the step's reflex from the filled sentence.

What the person adds to the sentence

A part of the sentence that repeats a step of the plan folds into that step, and the plan says so: folded "show me the error rate" into 1. A part that says what not to do beside a plan is refused, and so is a sentence that opens with a condition, if, unless or in case: evoke judges no condition, so it asks for the check first and the plan after.

What is contract

steps is contract: an overlay may reword the description, the confirm and the asks, never a step. A step added, removed, reworded or reordered is a major version, and evoke check says so: steps the steps moved. A slot added or renamed rewords a step, so it is major too.

add, test and show

add decides every step of a newcomer playbook over the set it joins, runs nothing, and prints what each reaches under its row; a step that reaches nothing installs and is reported, since the plan refuses when it is made. test decides the playbook's records as any reflex's, then its steps, each filled from the first record whose reading fills every slot it holds; a step no record fills is untested. show prints the steps after confirm, numbered.

$ evoke test outage
  outage  4 passed · 7 steps route

In the SDK

playbook(manifest) hands a playbook as code, steps in its manifest and no body; project.steps(input, { ask }) answers a slot the sentence lacks before the plan is made (Decisions). A playbook is never called by name: run, handle and evoke run <name> refuse it with say it in a sentence.

Next: Examples and tests.

FAQPrivacyGitHub