The World Vol 9 · The Village
ch 95 / 105
Chapter 95

Plans as Data

Four numbers on one side, a paragraph on the other

A mailbox takes four numbers. That was the whole of the design four chapters ago: a verb out of the action table, the body it is about, how many grams, and the tick it was decided at, copied into one slot between two ticks and taken out by a receive that gives up at once. Everything a villager has done since has been decided by the habit underneath that slot, which is arithmetic, and the one thing in this volume that is not arithmetic has so far been allowed to write exactly one column of one kind of row. A model asked what a person does next answers in text, and text does not go into a slot that takes four numbers. Between the two there has to be something that turns an answer into numbers and refuses the answers that will not turn, and that something cannot be the model, because the model is the thing being refused.

The answer this chapter builds is an object. A villager is never asked for a sentence about what it will do; it is asked for a list of steps, each step a verb with the one argument that verb takes, and the verbs are six words in a table the engine owns: go, wait, watch, hand, take, say. A villager proposes one object against a closed table of six verbs, and the engine writes its verdict down beside the answer's own bytes, in a table nothing rewrites.

Five of them are things a body in this valley can already do, because the action table has had walking and standing since the fifth volume and handing and taking since the first chapter of this one. The sixth is speech, and a step of it names who is spoken to and nothing else. Every step also carries a reason, and the reason is the one field on the object that no code reads: it is there for a person looking at the record later, and a test on this page walks the checking package's source to prove that no line of it looks. A plan has a cap on its steps and a horizon in ticks, both in a file, and a plan over either is refused, not shortened to fit.

What happens to an answer is the other half. Every answer a villager gives, accepted or not, goes into one table as a row that is never updated: who was asked, at what tick, which model at which digest under which settings, the sha256 of the prompt, the identities the villager was allowed to name, the bytes that came back, and the verdict, with the check that refused and its reason when there is one. There is no separate plan store. A villager's current plan is the newest accepted row, read with an ORDER BY id DESC LIMIT 1, and a refusal is a row beside it that nothing rewrites. The verdict comes from a set of six checks the ledger names in a fixed order, shape, verb, grounding, law, reach and freshness, and this chapter builds the first two of them, which need nothing but the answer, the table and the two caps. The four after them need what the villager knew, the law and the world, and are not on this page; the ledger's column takes their names already, because a schema that could record only two of six verdicts would be rewritten four times.

Two rules from the volume's opening chapters run through every run below and neither is relaxed. The model chooses; it never counts. A plan may name a cell and a body and may ask for grams, and the grams it asks for are what it asked for, never what moves: the engine prices a transfer in parcels and the world's own check decides whether a parcel crosses at all, and the page keeps the two numbers apart wherever they appear together. And a structured answer is a request, not a guarantee. The server this world runs takes a schema on a generation and steers what the model produces toward it, and the last chapter added the one field that carries it; a model that answers with a paragraph anyway fails the first check, and the worked failure below is exactly that, run on the recording rather than described.

A table of six verbs and a schema rendered from it

The table opens a package. internal/law is the engine's side of the seam: what may be proposed, the checks a proposal passes, and the verdict they come to. It imports the simulation's coordinate type and nothing that opens a socket, and a rule_test.go with a file floor holds it to that, because a verdict computed by a package that could ask a model or open a transaction would be a verdict nobody could replay. The store is sealed against it and the model client is sealed against it, in the two sealed lists the earlier volumes wrote, and the lists grow by one word each in this chapter.

▣ Build · stage 1 — the verb table, the step and the plan
// internal/law/law.go
// Verb is one of the six things a villager may propose to do. They are
// the world's own actions plus speech, and the table below is the
// whole of the vocabulary: a step whose verb is not in it is refused
// whichever words stand around it.
type Verb string

const (
	Go    Verb = "go"    // walk to a cell
	Wait  Verb = "wait"  // stand still
	Watch Verb = "watch" // face somebody and stand still
	Hand  Verb = "hand"  // put parcels in somebody's hands
	Take  Verb = "take"  // take parcels out of somebody's hands
	Say   Verb = "say"   // say a line to somebody
)

// Arg is which argument a verb takes. A step carries the one its verb
// takes and no other, so a hand that names a cell or a wait that names
// a body is a step whose arguments are not the verb's.
type Arg uint8

const (
	Nothing     Arg = iota // no argument at all
	Where                  // a cell
	Who                    // a body
	WhoAndGrams            // a body, and how many grams
)
// ...
// Entry is one row of the verb table: the verb, the argument it takes,
// how many ticks one step of it is given before the next step is due,
// and what it does, in words.
// ...
type Entry struct {
	Verb  Verb
	Takes Arg
	Span  int
	Does  string
}

// Table is the six, in the order they are argued for. Nothing outside
// this file decides what a villager may propose, and no prompt in this
// world carries a copy of it that is not rendered from it.
var Table = [6]Entry{
	{Go, Where, 40, "walks to a cell"},
	{Wait, Nothing, 20, "stands still"},
	{Watch, Who, 20, "faces a body and stands still"},
	{Hand, WhoAndGrams, 40, "puts grams in a body's hands"},
	{Take, WhoAndGrams, 40, "takes grams out of a body's hands"},
	{Say, Who, 10, "says a line to a body"},
}
// ...
// Step is one step of a plan, as it arrives: a verb, the argument the
// verb takes, and a reason.
//
// Reason is read by nothing. It is there for a person reading the
// ledger and for nothing else, and no check in this package looks at
// it: a plan with every reason blank, and the same plan with every
// reason a paragraph, come to the same verdict. A test holds that,
// and the test is the whole of the guarantee, because a seam that
// branched on the words a model wrote would be a seam the words could
// argue with.
type Step struct {
	Verb   Verb         `json:"verb"`
	Who    sim.EntityID `json:"who,omitempty"`
	Where  *sim.Coord   `json:"where,omitempty"`
	Grams  float64      `json:"grams,omitempty"`
	Reason string       `json:"reason"`
}

// Plan is what a villager proposes: an ordered list of steps and
// nothing else. There is no name on it, no tick and no field for what
// the villager is carrying, because every one of those is a number the
// engine holds and a model is never asked for.
type Plan struct {
	Steps []Step `json:"steps"`
}

Span is the one number in a row and it is the number the horizon is measured in. A step of go is given forty ticks, four seconds of world at the pace this volume runs at; a wait and a watch get twenty; a hand or a take gets forty, which at two ticks a parcel is twenty parcels, ten grams; a say gets ten. The spans are in the table and not in the file beside the caps, on purpose: a plan is refused for adding up to more than the horizon, and a horizon measured against spans an operator could edit would mean something different after every edit. The table is the world's, the caps are the operator's, and the line between them is where the file ends.

Where is a pointer so that a step can carry no cell at all, which is what every verb but go does, and omitempty on the three arguments is what lets a wait arrive as a verb and a reason and nothing else. A step's argument is typed by its verb and nowhere else; the type says what a step can carry and the table says what each verb does carry, and the second check below is the difference between the two.

The schema is rendered from the table. Every answer the server is asked for is asked for against a shape, and the shape says a step is one of six objects, each keyed on its verb and carrying the argument that verb takes. Writing that shape out by hand would put the six verbs in two places, and the last chapter said what happens to a rule stated twice. So it is built from Table at the moment it is wanted, and a test holds that each verb appears in it exactly once and that nothing in it caps the steps: the caps are the engine's, and a plan over them arrives and is refused rather than never arriving, which is the only way a check can be seen to work.

▣ Build · stage 2 — the shape asked for, built from the table
// internal/law/law.go
// Schema is the shape a plan is asked for, as the server takes one,
// rendered from the table: a step is one of six objects, each keyed on
// its verb and carrying the argument that verb takes, and every step
// carries a reason. It is built from Table and written in no file, so
// the shape the server steers toward and the table the check reads
// cannot disagree. It does not cap the steps, because the caps are the
// engine's, and a plan over them arrives and is refused rather than
// never arriving at all.
func Schema() json.RawMessage {
	type field map[string]any
	cell := field{"type": "object", "properties": field{"x": field{"type": "integer"}, "y": field{"type": "integer"}}, "required": []string{"x", "y"}}
	body := field{"type": "integer"}
	grams := field{"type": "number"}
	var steps []field
	for _, e := range Table {
		props := field{"verb": field{"const": string(e.Verb)}, "reason": field{"type": "string"}}
		req := []string{"verb"}
		switch e.Takes {
		case Where:
			props["where"] = cell
			req = append(req, "where")
		case Who:
			props["who"] = body
			req = append(req, "who")
		case WhoAndGrams:
			props["who"], props["grams"] = body, grams
			req = append(req, "who", "grams")
		}
		steps = append(steps, field{"type": "object", "properties": props, "required": append(req, "reason")})
	}
	b, err := json.Marshal(field{
		"type":       "object",
		"properties": field{"steps": field{"type": "array", "items": field{"oneOf": steps}}},
		"required":   []string{"steps"},
	})
	if err != nil {
		panic(err) // a map of strings and slices cannot fail to marshal
	}
	return b
}
// configs/thought.json — the retrieval and reflection blocks are the last two chapters'; this is the block beside them
  "planning": {
    "length": 5,
    "horizon": 160,
    "limit": 256
  }
// configs/plan.tmpl
{{.Name}}. {{.Persona}}

{{.Name}} stands on {{.At.X}},{{.At.Y}}, and home is {{.Home.X}},{{.Home.Y}}.
{{if .Sees}}In sight now, each with their number:
{{range .Sees}}[{{.ID}}] {{.Name}} on {{.Cell.X}},{{.Cell.Y}}, {{printf "%.1f" .Dist}} cells off
{{end}}{{else}}Nobody is in sight.
{{end}}
What {{.Name}} remembers that bears on this, each with its number:
{{range .Memories}}[{{.ID}}] {{.Text}}
{{end}}
What {{.Name}} does next, as a short list of steps in order. Each step is one of: {{range $i, $v := .Verbs}}{{if $i}}; {{end}}{{$v}}{{end}}. A body is named by its number, and every step gives {{.Name}}'s reason in one breath.
// configs/configs.go — the embed gains the template; the seven files before it are earlier chapters'
//go:embed genesis.json models.json village.json importance.json thought.json reflect-questions.tmpl reflect-statement.tmpl plan.tmpl
var Files embed.FS
// internal/village/reflect.go — Prompt, with the five fields a plan's template names; the four before them are the last chapter's
type Prompt struct {
	Name     string
	Memories []Memory
	Count    int
	Question string

	Persona string
	At      sim.Coord
	Home    sim.Coord
	Sees    []Seen
	Verbs   []string
}

Three numbers in the file, and each has an argument. length is 5 because a plan is a few minutes of a person's day and not the day; the token arithmetic further down says the limit and the cap agree with each other at about thirty tokens a step. horizon is 160 ticks, sixteen seconds of world: four walks on the table, or a walk, a wait, a watch and a hand with a wait to spare, and a plan that adds up to more than that is a plan about a world further ahead than the one it was asked in. limit is 256 tokens and is a price cap; two of the fifteen answers on this page reach it, and neither of them is a plan afterwards.

Read the template for what is not in it. It does not list the verbs; the six clauses after Each step is one of are rendered from Table by the bench, verb and description, and the file holds a loop and nothing a person typed. It does not say how many steps a plan may have or how long it may run, because those are the caps and the caps are enforced in Go. What it does carry is everything the engine knows and the model does not: the persona, which is authored prose; the cell the villager stands on and its home; who its eyes returned at this boundary, each with the number the villager may name them by; and the eight memories that came to mind, each with its own number. The five fields added to Prompt are those, and a reflection's two templates name none of them.

▣ Build · stage 3 — what a plan runs under, off the files and the table
$ go run ./cmd/plans -mode settings | tail -37

  the verb table, off internal/law, and the whole of what a villager may propose
  verb   takes                      ticks  does
  go     where: a cell                 40  walks to a cell
  wait   nothing                       20  stands still
  watch  who: a body                   20  faces a body and stands still
  hand   who: a body, and grams        40  puts grams in a body's hands
  take   who: a body, and grams        40  takes grams out of a body's hands
  say    who: a body                   10  says a line to a body

  the checks a ledger row may name, in the order they are run
    1  shape
    2  verb
    3  grounding
    4  law
    5  reach
    6  freshness

  the schema, 1082 bytes, off internal/law, as the request carries it
    | {"properties":{"steps":{"items":{"oneOf":[{"properties":{"reason":{"type":"string"},"verb":{"const":"go"},"where":{"properties":{"x":{"type":"integer"},"y":{"type":"integer"}},"required":["x","y"],"type":"object"}},"required":["verb","where","reason"],"type":"object"},{"properties":{"reason":{"type":"string"},"verb":{"const":"wait"}},"required":["verb","reason"],"type":"object"},{"properties":{"reason":{"type":"string"},"verb":{"const":"watch"},"who":{"type":"integer"}},"required":["verb","who","reason"],"type":"object"},{"properties":{"grams":{"type":"number"},"reason":{"type":"string"},"verb":{"const":"hand"},"who":{"type":"integer"}},"required":["verb","who","grams","reason"],"type":"object"},{"properties":{"grams":{"type":"number"},"reason":{"type":"string"},"verb":{"const":"take"},"who":{"type":"integer"}},"required":["verb","who","grams","reason"],"type":"object"},{"properties":{"reason":{"type":"string"},"verb":{"const":"say"},"who":{"type":"integer"}},"required":["verb","who","reason"],"type":"object"}]},"type":"array"}},"required":["steps"],"type":"object"}

  configs/plan.tmpl, 634 bytes, sha256 3de6e2fb7974c141
    | {{.Name}}. {{.Persona}}
    |
    | {{.Name}} stands on {{.At.X}},{{.At.Y}}, and home is {{.Home.X}},{{.Home.Y}}.
    | {{if .Sees}}In sight now, each with their number:
    | {{range .Sees}}[{{.ID}}] {{.Name}} on {{.Cell.X}},{{.Cell.Y}}, {{printf "%.1f" .Dist}} cells off
    | {{end}}{{else}}Nobody is in sight.
    | {{end}}
    | What {{.Name}} remembers that bears on this, each with its number:
    | {{range .Memories}}[{{.ID}}] {{.Text}}
    | {{end}}
    | What {{.Name}} does next, as a short list of steps in order. Each step is one of: {{range $i, $v := .Verbs}}{{if $i}}; {{end}}{{$v}}{{end}}. A body is named by its number, and every step gives {{.Name}}'s reason in one breath.

  the template names no verb and no cap: the six words are rendered into it
  from the table, and the caps are the engine's, so neither can disagree with
  the copy that runs

That mode opens no socket and reads nothing but the build. The schema is 1,082 bytes and every one of them came out of Table and a marshaller; the six const entries are the six rows, in the table's order, and the oneOf around them is what tells the server that a step is one of six objects and not one object with five optional fields. The difference is not a matter of taste and the bench keeps the other shape behind a flag so that it can be run: -loose sends one object a step with every argument optional, on the two live modes and nowhere else, and on this machine the half-billion-parameter model answered fifteen calls under it with plans over the cap, walks that named no cell and two answers cut off at the limit, and not one of the fifteen was accepted. Under the schema above it fills the argument its verb requires, because the grammar the server builds from the shape leaves it no other way to close the object. Nothing from the loose run is quoted here, because it produced no plan to quote; the run is in the volume's findings, and a reader with the containers up can make it again in a minute and a half.

Eleven hundred and one bytes in, two steps back

Now a prompt, for Halla at the boundary of tick 2400, rendered from the committed stream and from what her eyes returned there. The eyes are the one thing the fixtures cannot supply, so the bench does what the retrieval chapter's did: it founds the same ground with the same seed, stands the same three people on it, and runs the day to that tick in memory, with no socket anywhere, so that who is in sight at 2400 is read off the ray caster every animal uses. What the eyes returned is rendered twice. Once as the lines the model reads, each body with the number the villager may name it by. And once as a line of the engine's own, in the words the sighting memories are written in, which is the question the retrieval is asked with: a villager about to decide what to do is asked what it remembers about who is standing there.

▣ Build · stage 4 — the prompt, whole, and what it came to
// internal/village/plan.go
// Situation is what a villager's eyes returned, as one line, for the
// retrieval to be asked with: who is in sight and how far off, in the
// order the eyes returned them, or that nobody is. It is the engine's
// text, rendered in the words the sighting memories are written in, so
// that the memories a situation brings to mind are the ones about the
// bodies standing there.
func Situation(sees []Seen) string {
	if len(sees) == 0 {
		return "nobody in sight"
	}
	parts := make([]string, len(sees))
	for i, s := range sees {
		parts[i] = fmt.Sprintf("%s in sight, %.1f cells off", s.Name, s.Dist)
	}
	return strings.Join(parts, "; ")
}
$ go run ./cmd/plans -mode prompt -who Halla -now 2400 | tail -42
  Halla's eyes at the boundary of tick 2400: 2 Ander on 7,2, 1.9 cells off
  the situation, the engine's line, embedded: "Ander in sight, 1.9 cells off"
  Halla's 20 rows at ticks up to 2400 ranked against it; the 8 that come to mind, in rank order
  rank   id   tick weight  recency import   relev   score  kind     text
     1   62   2203      2   0.5791   0.20  0.9208  3.5414  saw      Ander came into sight, 0.2 cell...
     2    1    901      4   0.0157   0.40  0.9324  3.2129  saw      Ander came into sight, 0.8 cell...
     3   25   1337      2   0.0525   0.20  0.9324  3.0497  saw      Ander came into sight, 0.8 cell...
     4   73   2341      4   0.8491   0.40  0.5506  2.9009  did      handed Ander 17 parcels, 8.5 grams
     5   69   2307      5   0.7727   0.50  0.5303  2.8637  did      handed Ander 50 parcels, 25.0 g...
     6   11   1015     10   0.0215   1.00  0.5808  2.7640  saw      Ander took 40 parcels out of Ha...
     7    2    901      2   0.0157   0.20  0.7689  2.5224  saw      Mose came into sight, 0.8 cells...
     8    8    999      7   0.0206   0.70  0.5303  2.3116  did      handed Ander 50 parcels, 25.0 g...
  the grounding set: 1 Halla, 2 Ander, 3 Mose

  the prompt, 1101 bytes, sha256 54919e7b11e74e27
    | Halla. Halla came to Firstlight before there was a Firstlight and put her house on the flattest ground she could find. She keeps more grain than she needs and gives the difference away, and she has never once been asked why.
    |
    | Halla stands on 9,3, and home is 8,5.
    | In sight now, each with their number:
    | [2] Ander on 7,2, 1.9 cells off
    |
    | What Halla remembers that bears on this, each with its number:
    | [62] Ander came into sight, 0.2 cells off
    | [1] Ander came into sight, 0.8 cells off
    | [25] Ander came into sight, 0.8 cells off
    | [73] handed Ander 17 parcels, 8.5 grams
    | [69] handed Ander 50 parcels, 25.0 grams
    | [11] Ander took 40 parcels out of Halla's hands, 20.0 grams
    | [2] Mose came into sight, 0.8 cells off
    | [8] handed Ander 50 parcels, 25.0 grams
    |
    | What Halla does next, as a short list of steps in order. Each step is one of: go walks to a cell, given as x and y; wait stands still; watch faces a body and stands still; hand puts grams in a body's hands; take takes grams out of a body's hands; say says a line to a body. A body is named by its number, and every step gives Halla's reason in one breath.

  against the recording, exemplars/plans.json
    rendered here                  1101 bytes  sha256 54919e7b11e74e27
    recorded                       1101 bytes  sha256 54919e7b11e74e27
    the same bytes; the recording is a recording of this template, this stream and these eyes
    375 tokens in by the model's own table, 61 out, stopped because: stop

  what the model answered, once, and yours will differ:
    | { "steps": [ { "reason": "go walks to a cell", "verb": "go" , "where": {"x": 2, "y": 7} }, { "reason": "wait stands still", "verb": "wait" } ] }

Asked what she remembers about Ander standing two cells off, the eight that come to Halla's mind are three sightings of him carried by cosines above 0.92, three gifts and the taking carried by weight, and one sighting of Mose, and the grounding set that falls out is all three people: herself, the man in sight, and a man in one of the eight rows. The prompt is those eight rows under a persona and a position, 1,101 bytes, and its sha256 is held against a recording made once from the live model, which is this chapter's fixture and is explained in a moment. The 375 tokens are what the model's own table made of the bytes, counted by the server and written down with the answer, because no tokenizer for this model's vocabulary lives in the module and a count the engine cannot make is a count it records rather than pretends to. Sixty-one tokens came back, and they are a plan: walk to 2,7 and stand still, with two reasons that are the template's own words copied. The reasons are a model's and are labelled; the cell is a model's and is about to be checked by nothing but the table; what the world will do about 2,7 is the last section's.

The recording is exemplars/plans.json, beside the last chapter's file and not inside it, because that file is held whole against a fresh one by the last chapter's bench and a file that grew would no longer be that file. Fifteen calls: three villagers at four ticks across the committed day, each asked with the schema, and each asked once more at the last tick with no schema on the request. Every call carries the villager, the tick, whether the schema went out, the seed, the situation line, the prompt's length and sha256, the two token counts, why the server stopped, the bytes that came back, and the row the embedding model gave the situation. What the model wrote is in the file and is labelled, on the page and in the file's own note. What is not in the file is any verdict. Every verdict below is computed here, every time, by the code that follows.

▣ Build · stage 5 — the verdict, and the two checks that need only the table
// exemplars/exemplars.go — the embed gains the fourth fixture; the seven files before it are earlier chapters'
//go:embed chronicle.jsonl hero.header.json small.header.json vectors.json memories.jsonl memory-vectors.json reflections.json plans.json
var Files embed.FS
// internal/law/law.go
// Caps is the two numbers a plan is measured against on arrival: how
// many steps it may have, and how many ticks those steps may add up
// to. Both are read out of configs/ by whoever drives a villager.
type Caps struct {
	Length  int
	Horizon int
}

// Span is how many ticks a plan adds up to on the table: the sum of
// its steps' spans. A step whose verb is not in the table counts for
// nothing here, because the verb check refuses the plan before the
// number is wanted.
func Span(p Plan) int {
	n := 0
	for _, s := range p.Steps {
		if e, ok := Lookup(s.Verb); ok {
			n += e.Span
		}
	}
	return n
}

// The six checks, in the order they are run. The order is cheapest
// first, and the last two need the world. A ledger row that refuses
// names one of these and no other word.
const (
	OnShape     = "shape"
	OnVerb      = "verb"
	OnGrounding = "grounding"
	OnLaw       = "law"
	OnReach     = "reach"
	OnFreshness = "freshness"
)

// Checks is the six, in order, for a bench to print and for a schema
// to be held against.
var Checks = [6]string{OnShape, OnVerb, OnGrounding, OnLaw, OnReach, OnFreshness}

// Verdict is what the seam says about one proposal: accepted, or
// refused by a named check for a stated reason. It is the one value
// this package hands out, and it is what the ledger records.
type Verdict struct {
	OK    bool
	Check string
	Why   string
}

// Accepted is the verdict a proposal gets when every check said yes.
func Accepted() Verdict { return Verdict{OK: true} }

// Refused is the verdict a proposal gets from the first check that
// said no.
func Refused(check, why string) Verdict { return Verdict{Check: check, Why: why} }

// Unparsed is the verdict an answer gets when it did not read as a
// plan at all. Reading it is done outside this package, by the helper
// that refuses an answer that is not the shape asked for; what it
// refused with is the reason, and the check is the first one.
func Unparsed(err error) Verdict { return Refused(OnShape, err.Error()) }
// ...
// Arrive runs the checks a plan can pass with nothing but the plan,
// the table and the caps: shape, then verb. The four after them need
// the grounding set, the law and the world, and are not run here.
func Arrive(p Plan, caps Caps) Verdict {
	if v := ShapeOf(p, caps); !v.OK {
		return v
	}
	return VerbsOf(p, caps)
}

// ShapeOf is the first check: the plan is the shape that was asked
// for. It parsed, or it would not be here; it has at least one step;
// it has no more steps than the cap; and every step names a verb.
// Nothing here knows what the verbs are, and nothing here reads a
// reason.
func ShapeOf(p Plan, caps Caps) Verdict {
	if len(p.Steps) == 0 {
		return Refused(OnShape, "a plan of no steps")
	}
	if caps.Length > 0 && len(p.Steps) > caps.Length {
		return Refused(OnShape, fmt.Sprintf("a plan of %d steps, and the cap is %d", len(p.Steps), caps.Length))
	}
	for i, s := range p.Steps {
		if s.Verb == "" {
			return Refused(OnShape, fmt.Sprintf("step %d has no verb", i+1))
		}
	}
	return Accepted()
}

// VerbsOf is the second check: every verb is in the table, every step
// carries the argument its verb takes and no other, and the spans the
// table gives the steps add up to no more than the horizon.
func VerbsOf(p Plan, caps Caps) Verdict {
	for i, s := range p.Steps {
		e, ok := Lookup(s.Verb)
		if !ok {
			return Refused(OnVerb, fmt.Sprintf("step %d: %q is not in the table", i+1, s.Verb))
		}
		if why := argued(e, s); why != "" {
			return Refused(OnVerb, fmt.Sprintf("step %d: %s", i+1, why))
		}
	}
	if span := Span(p); caps.Horizon > 0 && span > caps.Horizon {
		return Refused(OnVerb, fmt.Sprintf("a plan spanning %d ticks, and the horizon is %d", span, caps.Horizon))
	}
	return Accepted()
}

Two checks, and the line between them is what each one is allowed to know. The shape check knows the answer parsed, because the strict reader from the last chapter ran first and an answer it refused arrives here as Unparsed with the reader's own sentence for a reason; it knows the plan has a step, has no more than the cap, and has a word in every verb slot; and it knows nothing about which words are verbs. The verb check knows the table: whether each word is in it, whether the step carries the argument that row says it takes and no other, and what the rows add up to in ticks against the horizon. The horizon sits under the verb check and not under its own name because it is a fact about the table's spans, and the ledger's column takes six names. The reason is read by neither. It is not checked for being present, because checking it for being present is reading it, and the schema's required is the only thing that asks for one.

▣ Build · stage 6 — Halla's plan at tick 2400, through the arrival checks and into a row
$ go run ./cmd/plans -mode arrive -who Halla -now 2400 | tail -23
  the prompt: 1101 bytes, sha256 54919e7b11e74e27, 375 tokens in, 61 out, stopped because: stop
  what the model answered, which yours will differ from:
    | { "steps": [ { "reason": "go walks to a cell", "verb": "go" , "where": {"x": 2, "y": 7} }, { "reason": "wait stands still", "verb": "wait" } ] }
  read strictly: an object of 2 step(s)
     # verb   argument                 ticks  reason, a model's, read by nothing
     1 go     to 2,7                      40  go walks to a cell
     2 wait   -                           20  wait stands still
  the table: 2 steps spanning 60 ticks, against a cap of 5 steps and a horizon of 160
  the seam: accepted
  the ledger row, column by column
    villager       Halla
    tick           2400
    kind           plan
    model          qwen2.5:0.5b-instruct-q4_K_M
    digest         c5396e06af294bd1
    settings       {limit 256, context 4096, temperature 0.00, seed 2401}
    prompt_sha256  54919e7b11e74e27
    tokens         375 in, 61 out
    grounding      1 Halla, 2 Ander, 3 Mose
    answer         144 bytes, the model's, kept whatever they are
    verdict        accepted
    failed         -
    reason         -

Read the row from the top and ask, for each line, who decided it. The villager, the tick and the kind are the engine's, because the engine asked. The model and its digest and the four settings are the kit's, read off the file and never typed, with the seed being the tick and the body added, which is the rule every call in this volume is under. The prompt's digest is the engine's, over bytes the engine rendered. The two token counts are the server's, recorded with the answer. The grounding set is the retrieval's and the eyes', computed before a word of prompt existed, and it is on the row so that a later check can ask what this villager could have known at 2400 without the world having to stand still. The answer is the model's, 144 bytes of it, kept whatever it says. The verdict and the two columns under it are the checks'. One column in fifteen came from a model, and it is stored as bytes, not read as a plan; the plan is read out of it again by whatever wants one.

▣ Build · stage 7 — the table, the caps and the reason, held by tests
$ go test ./internal/law/ -run 'TestTheTableIsSixVerbsEachWithOneArgumentAndASpan|TestTheChecksAreSixInOrderCheapestFirst|TestAVerbOutsideTheTableIsRefusedByName|TestAStepCarriesTheArgumentItsVerbTakesAndNoOther|TestAPlanOverTheLengthCapIsRefusedWholeAndNeverTrimmed|TestAPlanOverTheHorizonIsRefusedWhole|TestTheSchemaIsRenderedFromTheTableAndCarriesNoCap|TestTheReasonIsReadByNothing|TestLawImportsNeitherTheModelClientNorTheStore' -v
=== RUN   TestTheTableIsSixVerbsEachWithOneArgumentAndASpan
    law_test.go:56: six verbs, in table order: go, wait, watch, hand, take, say
--- PASS: TestTheTableIsSixVerbsEachWithOneArgumentAndASpan (0.00s)
=== RUN   TestTheChecksAreSixInOrderCheapestFirst
--- PASS: TestTheChecksAreSixInOrderCheapestFirst (0.00s)
=== RUN   TestAVerbOutsideTheTableIsRefusedByName
    law_test.go:81: refused by verb: step 2: "eat" is not in the table
--- PASS: TestAVerbOutsideTheTableIsRefusedByName (0.00s)
=== RUN   TestAStepCarriesTheArgumentItsVerbTakesAndNoOther
    law_test.go:117: ten steps carrying the wrong argument refused by the verb check, and six carrying the right one accepted
--- PASS: TestAStepCarriesTheArgumentItsVerbTakesAndNoOther (0.00s)
=== RUN   TestAPlanOverTheLengthCapIsRefusedWholeAndNeverTrimmed
    law_test.go:136: six steps against a cap of five is refused; the first five alone are accepted; nothing trims the six to the five
--- PASS: TestAPlanOverTheLengthCapIsRefusedWholeAndNeverTrimmed (0.00s)
=== RUN   TestAPlanOverTheHorizonIsRefusedWhole
    law_test.go:157: five steps spanning 180 ticks against a horizon of 160: refused by verb: a plan spanning 180 ticks, and the horizon is 160
--- PASS: TestAPlanOverTheHorizonIsRefusedWhole (0.00s)
=== RUN   TestTheSchemaIsRenderedFromTheTableAndCarriesNoCap
    law_test.go:180: 1082 bytes of schema: one object a verb, rendered from the table, no cap on the steps
--- PASS: TestTheSchemaIsRenderedFromTheTableAndCarriesNoCap (0.00s)
=== RUN   TestTheReasonIsReadByNothing
    law_test.go:258: four reasons, one verdict; every source file walked, Reason declared once and read on no line
--- PASS: TestTheReasonIsReadByNothing (0.00s)
=== RUN   TestLawImportsNeitherTheModelClientNorTheStore
    rule_test.go:55: every file of the package read, and none of them names the model client or the store
--- PASS: TestLawImportsNeitherTheModelClientNorTheStore (0.00s)
PASS
ok  	theworld/internal/law	0.003s

The eighth test is the sentence about the reason made into something that fails, and it has two halves. The first runs one sound plan through the checks four times, with every reason blank, then a paragraph in the founding document's register, then a sentence that names a verb the table does not have, then two thousand copies of one word, and gets the same verdict each time; then it appends a step whose verb is strike and whose reason says the villager is not violent, and gets a refusal that names the verb. The second half parses every source file in the package and walks the syntax tree for the word Reason: it is declared once, as the field on Step, and it appears in no selector and no key on any line. A test that only ran the first half would be proving that the code does not branch on four particular reasons; the walk proves it does not branch on any. The two tests before it are refusal whole: six waits against a cap of five is refused, the first five alone are accepted, and nothing in between hands the five back.

Fifteen columns in the tenth file; the newest accepted row is the plan

The row a bench prints is the row a migration declares. The tenth file adds the twelfth table, and its design is the memory table's a third time, with one difference the seam forces: a memory is a row about what happened, and a proposal is a row about what was answered, so it keeps the answer's bytes whether or not anything was done about them. A ledger that dropped the bytes it refused would be a ledger of verdicts about nothing.

▣ Build · stage 8 — the proposal table, and the two questions it answers
-- migrations/0010_proposal.sql
-- Every proposal a villager has ever made, appended and never
-- updated. The refusal ledger and the plan store are one table, and
-- that is the design rather than an economy: a villager's current
-- plan is the newest accepted plan-proposal, so there is no row
-- anywhere that a later decision rewrites, and a villager that has
-- made no accepted plan has no plan.
-- ...
CREATE TABLE proposal (
    id            bigint   GENERATED ALWAYS AS IDENTITY,
    villager      text     NOT NULL,
    tick          bigint   NOT NULL,
    kind          text     NOT NULL,
    model         text     NOT NULL,
    digest        text     NOT NULL,
    settings      jsonb    NOT NULL,
    prompt_sha256 text     NOT NULL,
    tokens_in     int      NOT NULL,
    tokens_out    int      NOT NULL,
    grounding     bigint[] NOT NULL DEFAULT '{}',
    answer        text     NOT NULL,
    verdict       text     NOT NULL,
    failed        text,
    reason        text,

    CONSTRAINT proposal_key PRIMARY KEY (id),
    CONSTRAINT proposal_of_a_villager FOREIGN KEY (villager) REFERENCES villager (name),
    CONSTRAINT proposal_on_a_real_tick CHECK (tick >= 0),
    CONSTRAINT proposal_is_of_a_kind CHECK (kind <> ''),
    CONSTRAINT proposal_names_its_model CHECK (model <> ''),
    CONSTRAINT proposal_is_pinned CHECK (digest ~ '^[0-9a-f]{64}$'),
    CONSTRAINT proposal_prompt_is_a_sha256 CHECK (prompt_sha256 ~ '^[0-9a-f]{64}$'),
    CONSTRAINT proposal_counts_its_tokens CHECK (tokens_in >= 0 AND tokens_out >= 0),
    CONSTRAINT proposal_is_accepted_or_refused CHECK (verdict IN ('accepted', 'refused')),
    CONSTRAINT only_a_refusal_names_a_check CHECK ((verdict = 'refused') = (failed IS NOT NULL)),
    CONSTRAINT only_a_refusal_has_a_reason CHECK ((verdict = 'refused') = (reason IS NOT NULL)),
    CONSTRAINT proposal_failed_one_of_six CHECK (failed IS NULL OR failed IN ('shape', 'verb', 'grounding', 'law', 'reach', 'freshness'))
);

-- The two questions ever asked of this table are about one villager:
-- every proposal they made, in the order they made them, and the
-- newest one that was accepted. id on the end answers both.
CREATE INDEX proposal_by_villager ON proposal (villager, id);
// internal/store/proposal.go
// Propose appends one proposal and fills in the id the database gave
// it. One row a transaction, because a proposal is the unit: the seam
// gives one verdict to one answer, and the ledger takes one row for it.
//
// It is called between ticks and never inside one, like everything
// else in this package.
func (d *DB) Propose(ctx context.Context, p *Proposal) error {
	if err := p.Check(); err != nil {
		return err
	}
	settings, err := json.Marshal(p.Settings)
	if err != nil {
		return fmt.Errorf("store: %s: %w", p.Villager, err)
	}
	var failed, reason *string
	if !p.Verdict.OK {
		failed, reason = &p.Verdict.Check, &p.Verdict.Why
	}
	const q = `INSERT INTO proposal (villager, tick, kind, model, digest, settings, prompt_sha256,
	                                 tokens_in, tokens_out, grounding, answer, verdict, failed, reason)
	           VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) RETURNING id`
	err = d.pool.QueryRow(ctx, q, p.Villager, p.Tick, p.Kind, p.Model, p.Digest, settings, p.PromptSHA,
		p.TokensIn, p.TokensOut, ids(p.Grounding), p.Answer, verdictWord(p.Verdict), failed, reason).Scan(&p.ID)
	if err != nil {
		return fmt.Errorf("store: proposing for %s at tick %d: %w", p.Villager, p.Tick, err)
	}
	return nil
}
// ...
// Current is the plan a villager is running: the newest accepted
// proposal of the plan kind, and whether there is one. There is no
// other plan store. A villager whose newest accepted plan has run out
// is a villager on the habit until another lands, and nothing here
// has to be told that, because nothing here is updated when it does.
func (d *DB) Current(ctx context.Context, name string) (Proposal, bool, error) {
	const q = `
SELECT ` + proposalColumns + `
  FROM proposal
 WHERE villager = $1 AND kind = 'plan' AND verdict = 'accepted'
 ORDER BY id DESC
 LIMIT 1`
	// ...
}
// internal/store/migrate_test.go — the list grows in the same change as the file
var world = []string{
	"world", "chronicle", "creature", "death", "species", "snapshot", "snapshot_part",
	"chronicle_vector",
	"villager", "memory",
	"memory_vector",
	"proposal",
}
$ go run ./cmd/plans -mode schema
plans: the tenth migration, and not one statement of it run

  n    file                       sha256, first 16     bytes  what it makes
  0010 0010_proposal.sql          0115c26c6a9eee48      3523  proposal

  the first nine files are chapter 93's to the byte, and this is the tenth

  proposal, 15 columns, as 0010_proposal.sql declares them
    column         type                                 null
    id             bigint, generated always             no
    villager       text                                 no
    tick           bigint                               no
    kind           text                                 no
    model          text                                 no
    digest         text                                 no
    settings       jsonb                                no
    prompt_sha256  text                                 no
    tokens_in      int                                  no
    tokens_out     int                                  no
    grounding      bigint[], default '{}'               no
    answer         text                                 no
    verdict        text                                 no
    failed         text                                 yes
    reason         text                                 yes
    and 10 checks: proposal_on_a_real_tick, proposal_is_of_a_kind, proposal_names_its_model, proposal_is_pinned, proposal_prompt_is_a_sha256, proposal_counts_its_tokens, proposal_is_accepted_or_refused, only_a_refusal_names_a_check, only_a_refusal_has_a_reason, proposal_failed_one_of_six

  the six checks a refusal may name, written in two places and held together by a test
    declared in     0010_proposal.sql
    held in Go as   law.Checks
    both of them    shape verb grounding law reach freshness

  nothing this world runs updates or deletes a row of it. A villager's plan is
  the newest accepted row, read with ORDER BY id DESC LIMIT 1, and a refusal is
  a row beside it that nothing rewrites

Fifteen columns, and two of them may be null, which is the whole of the design in one line of the listing. failed and reason are tied to the verdict by two equalities of two booleans, the way the memory table tied a speaker to a heard row: an accepted row cannot carry a check name and a refused row cannot lack one, and the server refuses both directions. The last constraint lists the six words a refusal may name, and that list exists in two places, here and in law.Checks, which is the one arrangement this volume has said twice it will not tolerate; the difference is that a test holds the two lists against each other, in order, so a seventh check added to one and not the other is a red test and not a row that will not insert. settings is one jsonb column and not four, because nothing ever asks the table a question about a temperature; the four numbers are on the row so that the row says what it is a row about. The two token columns are the server's counts, and they are the one place the price of a proposal is written down.

The listing runs on a bare workstation and lists one file, not the directory. A count over every migration this build holds would be a count that moves each time a later chapter adds a file, and this volume has already moved one such count twice; the bench prints the tenth file by number and says of the nine before it only that they are the retrieval chapter's to the byte.

▣ Build · stage 9 — the store's side, held by tests that open no socket
$ go test ./internal/store/ -run 'TestTheTwelfthTableIsInTheListAndMadeByTheTenthFile|TestTheSixChecksInTheSchemaAreTheLawsSix|TestAProposalRowIsCheckedBeforeItReachesTheServer|TestNothingTouchesAProposal|TestNoSimulationPackageImportsTheStore' -v
=== RUN   TestTheTwelfthTableIsInTheListAndMadeByTheTenthFile
    proposal_test.go:50: 0010_proposal.sql makes proposal, keyed on an identity nothing can write, and the list names it
--- PASS: TestTheTwelfthTableIsInTheListAndMadeByTheTenthFile (0.00s)
=== RUN   TestTheSixChecksInTheSchemaAreTheLawsSix
    proposal_test.go:82: 6 checks, the same six words in the same order in 0010_proposal.sql and in internal/law
--- PASS: TestTheSixChecksInTheSchemaAreTheLawsSix (0.00s)
=== RUN   TestAProposalRowIsCheckedBeforeItReachesTheServer
    proposal_test.go:121: two well-formed rows accepted and seven ways of being wrong refused, before any socket
--- PASS: TestAProposalRowIsCheckedBeforeItReachesTheServer (0.00s)
=== RUN   TestNothingTouchesAProposal
    proposal_test.go:155: every file of the store read, and no statement touches a proposal once it is written
--- PASS: TestNothingTouchesAProposal (0.01s)
=== RUN   TestNoSimulationPackageImportsTheStore
    rule_test.go:63: every file in every sealed package read, and not one of them names it
--- PASS: TestNoSimulationPackageImportsTheStore (0.00s)
PASS
ok  	theworld/internal/store	0.015s

The store imports the law, for the verdict type, and the law does not import the store, which is the direction every arrow in this module has run since the database arrived: the thing that writes a verdict down is allowed to know what a verdict is, and the thing that decides one is not allowed to know that a table exists. The fourth test is the append-only law a third time, and this time with nothing to permit: the memory chapter's walk allowed exactly one UPDATE, behind a flag, for its worked failure, and this walk allows none, because there is no design of a plan store that this chapter tried and took back out. The fifth is the sealed-import test from the seventh volume with one more word in its list, law, and the model client's list gains the same word in the same change.

Now the same plan against the live models, with the ledger on the far side of the boundary, and then two more rows behind it so that the newest-accepted query has something to choose between. The committed day goes into an empty database first, the way the last two chapters put it there; the prompt is rendered over rows read back ORDER BY tick, id; the answer goes through the same reader and the same two checks the replay ran; and the row goes into the twelfth table through Propose whatever the verdict was. A second run of the mode on the same database finds the village settled and writes nothing twice, so the ledger grows by one row a call and the table is read back after each.

⚙ Tool — the model server, one model resident at a time

The server is Ollama in a podman container on the closed bridge the last volume built, started with OLLAMA_MAX_LOADED_MODELS=1, holding the three model files on a named volume; the Go code runs in world-go on the same bridge and the database in world-db, which is the only container with psql. Nothing below downloads anything. The format field on a generation request takes a JSON schema, and the oneOf and const the schema above uses are part of what the server's grammar builder understands; its API reference is under github.com/ollama/ollama. The database starts empty after podman kill and podman start, because its data directory is a tmpfs the container mounts fresh; that pair, and never restart, is how every chapter in this volume gets an empty one.

▣ Build · stage 10 — three rows in the ledger, and the query that picks the plan
$ podman kill world-db && podman start world-db
world-db
world-db
$ podman exec -w /bench world-go go run ./cmd/plans -mode live -who Halla -now 2400 | tail -47 | head -3
  the day into the tables: 88 rows appended, 88 given the identity the dump carries, 88 vectors copied
  read back: 88 rows and 88 vectors, over 3 people

$ podman exec -w /bench world-go go run ./cmd/plans -mode live -who Halla -now 2400 | tail -16
  the row appended as proposal 1
  Halla's proposals read back, ORDER BY id: 1 row(s)
    id   tick kind  prompt_sha256          in    out  grounding      verdict  failed
     1   2400 plan  54919e7b11e74e27      375     61  {1,2,3}        accepted -
  Halla's current plan, the newest accepted row: proposal 1, asked at tick 2400, which is this one

  what one plan cost, at 10 ticks a second (measured here; yours will differ)
  call                                          took    ticks
  the situation embedded, with a load in it     418ms      4.2
  the plan, with a load in it                 3.149s     31.5
  one plan, one embedding and one call        3.568s     35.7
  24 people, one worker, one plan each     1m25.624s      856
  the horizon is 160 ticks, so a plan has run out 696 ticks before the worker comes back round,
  and the habit has every one of those ticks
  qwen2.5:0.5b-instruct-q4_K_M is the model resident now, answering on the processor, with no bytes on a graphics card
  and not one number the models answered is on this page
$ podman exec -w /bench world-go go run ./cmd/plans -mode live -who Halla -now 2900 | tail -17 | head -6
  the row appended as proposal 2
  Halla's proposals read back, ORDER BY id: 2 row(s)
    id   tick kind  prompt_sha256          in    out  grounding      verdict  failed
     1   2400 plan  54919e7b11e74e27      375     61  {1,2,3}        accepted -
     2   2900 plan  6f9a1c245cac1109      361     61  {1,2,3}        accepted -
  Halla's current plan, the newest accepted row: proposal 2, asked at tick 2900, which is this one
$ podman exec -w /bench world-go go run ./cmd/plans -mode live -who Halla -now 2900 -noschema | tail -18 | head -7
  the row appended as proposal 3
  Halla's proposals read back, ORDER BY id: 3 row(s)
    id   tick kind  prompt_sha256          in    out  grounding      verdict  failed
     1   2400 plan  54919e7b11e74e27      375     61  {1,2,3}        accepted -
     2   2900 plan  6f9a1c245cac1109      361     61  {1,2,3}        accepted -
     3   2900 plan  6f9a1c245cac1109      361    256  {1,2,3}        refused  shape
  Halla's current plan, the newest accepted row: proposal 2, asked at tick 2900; this one changed nothing
$ podman exec world-db psql -U world -d world -c "SELECT id, villager, tick, kind, tokens_in, tokens_out, grounding, verdict, failed FROM proposal ORDER BY id;"
 id | villager | tick | kind | tokens_in | tokens_out | grounding | verdict  | failed 
----+----------+------+------+-----------+------------+-----------+----------+--------
  1 | Halla    | 2400 | plan |       375 |         61 | {1,2,3}   | accepted | 
  2 | Halla    | 2900 | plan |       361 |         61 | {1,2,3}   | accepted | 
  3 | Halla    | 2900 | plan |       361 |        256 | {1,2,3}   | refused  | shape
(3 rows)

$ podman exec world-db psql -U world -d world -c "SELECT id, tick, prompt_sha256 FROM proposal WHERE villager = 'Halla' AND kind = 'plan' AND verdict = 'accepted' ORDER BY id DESC LIMIT 1;"
 id | tick |                          prompt_sha256                           
----+------+------------------------------------------------------------------
  2 | 2900 | 6f9a1c245cac1109a350fee1e5bbe6c62017c1b8b46ac95d467d4fe3bd818a77
(1 row)

The first row is the replay's row, column for column: the same 1,101 bytes with the same sha256 and the same 375 tokens, which is the one thing about a live run that has to be identical, because the prompt is rendered from the tables and the tables hold the fixture. The answer came back as the same sixty-one tokens too, and that is a fact about this machine and a seeded answer at temperature nought, not a check; on yours the words will differ, and the two checks will judge whatever arrives by the same rule. The second row is Halla's plan at the end of the day, accepted, and the current plan moves from 1 to 2 with no row touched. The third is the same prompt at the same tick sent with no schema on the request, and what came back was a paragraph, 256 tokens of it before the limit cut it off; the row records the paragraph, the check that stopped it and the reader's reason, and the current plan is still row 2. That is the sentence in the first section as a query: a refusal is a row beside the plan, and a villager whose newest answer was refused is a villager whose plan is whatever it was.

Then the price, which is what the horizon has to be read against. Every duration in that block was measured here, on the eight-core AMD Ryzen 7 3700X with 30 GB of memory that every duration in this volume has been measured on, rootless podman, with the models answering on the processor and no graphics card in use; the pace is ten ticks a second, printed from a flag beside every figure in ticks. One plan is an embedding and a generation, and each of the two has a load in it, because the server holds one model at a time and a plan needs both: 418 milliseconds to embed the situation and 3,149 to answer, 3,568 together, which is 35.7 ticks. That is one villager. Twenty-four of them with one worker is 856 ticks, and a plan is allowed 160.

∑ Math Interlude — a horizon of 160 ticks against a round of 856

A tick is a hundred milliseconds, so a duration in milliseconds divided by a hundred is a duration in ticks. Embedding the situation took 418 milliseconds: 4.2 ticks. The plan took 3,149: 31.5 ticks. Together, 3,568 milliseconds, and the bench prints 35.7 ticks. One worker asking one model at a time gets round twenty-four people in 24 times 3,568 milliseconds, which is 85,632 milliseconds, or 856 ticks: a minute and twenty-five seconds of world between one plan landing for Halla and the next one landing for her.

The horizon is 160 ticks, so a plan has run out 696 ticks before the worker comes back round, and the habit has every one of those. Turn that into a share: 160 over 856 is 0.187, so even a villager whose every answer is accepted is on its plan for under a fifth of its ticks and on the habit for the rest, and that is with the model answering in sixty-one tokens. The third row's answer ran to 256 tokens and the call took 6,285 milliseconds, 62.9 ticks, and a round of those is 1,610 ticks; a plan of the same horizon is then on the habit for nine tenths of the time. A horizon long enough to cover the round, at this size on this machine, would be a plan about a world eighty-five seconds ahead of the one it was asked in, and the world moves in eighty-five seconds. So the horizon is chosen against staleness and not against the round: sixteen seconds is far enough ahead that a plan can walk somewhere and do one thing there, and near enough that what it was asked about is still roughly where it was.

The length cap and the token limit agree with each other by a second division. The accepted answer above is two steps in 61 tokens; the seven-step plan in the next section is 204 tokens; both come to about thirty tokens a step, reasons included. Five steps at that rate is 150 tokens, comfortably under 256, and an answer that reaches 256 is one that was already past the cap in steps when the limit cut it, which is what both answers cut off at the limit turn out to be.

T = 1 ÷ f

plan = Re + Rg

round = n × plan

share = (horizon × T) ÷ round

fticks a second the world is run at; 10 for every figure on this page
Thow long one tick is; 100 milliseconds here
Reembedding the situation, start to finish; 418 milliseconds above, with a load in it
Rgthe generation, start to finish; 3,149 milliseconds above, with a load in it
npeople in the village, each getting one plan, with one worker asking; 24 above
horizonthe most ticks a plan may add up to, from the file; 160 here
sharethe part of a villager's ticks a plan can cover at most; 0.187 here
a × ba multiplied by b
a ÷ ba divided by b

Fifteen answers, nine plans, fifteen rows

The recording has fifteen calls in it and the day mode runs every one through the reader and the two checks in the order they were made, printing the ledger the day would have left. One re-run of the day serves every call at the same tick, so the world only ever runs forward, and the verdicts are the engine's over bytes the recording holds.

▣ Build · stage 11 — the ledger over the whole recording
$ go run ./cmd/plans -mode day | tail -20
  who     tick schema steps ticks  verdict  check     reason
  Halla   1400 yes        2    60  accepted -         -
  Ander   1400 yes        4   120  accepted -         -
  Mose    1400 yes        -     -  refused  shape     not the shape asked for: unexpected EOF
  Halla   1900 yes        2    60  accepted -         -
  Ander   1900 yes        -     -  refused  shape     not the shape asked for: unexpected EOF
  Mose    1900 yes        2    60  accepted -         -
  Halla   2400 yes        2    60  accepted -         -
  Ander   2400 yes        2    60  accepted -         -
  Mose    2400 yes        2    60  accepted -         -
  Halla   2900 yes        2    60  accepted -         -
  Halla   2900 no         -     -  refused  shape     not the shape asked for: invalid character 'T' looking for be...
  Ander   2900 yes        2    60  accepted -         -
  Ander   2900 no         -     -  refused  shape     not the shape asked for: invalid character 'T' looking for be...
  Mose    2900 yes        7   190  refused  shape     a plan of 7 steps, and the cap is 5
  Mose    2900 no         -     -  refused  shape     not the shape asked for: invalid character 'T' looking for be...

  15 calls, 15 prompts rendered here and every one the recorded bytes
  9 accepted, 6 refused: 6 by shape, 0 by verb
  every verdict above is the engine's over the recording; the words in the answers are the model's

Nine accepted and six refused, and every one of the six by the first check. Three are the calls made with no schema, and the worked failure below reads one of them. Two are answers cut off at the limit: a plan is an object and an object cut off at 256 tokens has no closing brace, so the reader reports an unexpected end and the row records it with nothing dispatched, exactly as the last chapter's cut-off statement was refused. The sixth is the one plan over the cap. The verb check refused nothing in the recording, and the reason is the schema: with six const verbs in the request, a server that honours the shape never sends a seventh, and it did not. What the verb check is for is the day the server does not honour it, or a recording made without it, or an operator's edit to the file; the refusals section below makes it say no four ways on this stream so that it has been seen saying no. Nine plans in fifteen calls is also the honest count of what a half-billion-parameter model does with this prompt, and every accepted plan on the recording is a walk somewhere and a wait, or a walk, a wait, a watch and a walk. Nobody hands. Nobody takes. The model chose, and what it chose is on the page.

▣ Build · stage 12 — seven steps, and the plan is refused rather than cut to five
$ go run ./cmd/plans -mode arrive -who Mose | tail -30 | head -16
  Mose's eyes at the boundary of tick 2900: nobody
  the situation, embedded and retrieved against: "nobody in sight"; the grounding set: 1 Halla, 2 Ander, 3 Mose
  the prompt: 988 bytes, sha256 fa4451e2542912da, 347 tokens in, 204 out, stopped because: stop
  what the model answered, which yours will differ from:
    | { "steps": [ { "reason": "go walks to a cell", "verb": "go" , "where": {"x": 6, "y": 6} } , { "reason": "wait stands still", "verb": "wait" }, { "reason": "watch faces a body and stands still", "verb": "watch", "who": 1 }, { "reason": "stand still", "verb": "wait" }, { "reason": "hand puts grams in a body's hands", "verb": "go", "where": {"x": 6, "y": 6} } , { "reason": "take takes grams out of a body's hands", "verb": "go", "where": {"x": 6, "y": 6} }, { "reason": "say says a line to a body", "verb": "say" , "who": 1 } ] }
  read strictly: an object of 7 step(s)
     # verb   argument                 ticks  reason, a model's, read by nothing
     1 go     to 6,6                      40  go walks to a cell
     2 wait   -                           20  wait stands still
     3 watch  1 Halla                     20  watch faces a body and stands still
     4 wait   -                           20  stand still
     5 go     to 6,6                      40  hand puts grams in a body's hands
     6 go     to 6,6                      40  take takes grams out of a body's hands
     7 say    1 Halla                     10  say says a line to a body
  the table: 7 steps spanning 190 ticks, against a cap of 5 steps and a horizon of 160
  the seam: refused by shape: a plan of 7 steps, and the cap is 5

Mose at the end of the day, with nobody in sight, answered with seven steps that add up to 190 ticks on the table, and the first check refused the plan for having seven steps. The first five of the seven are a plan the checks would accept: a walk to 6,6, two waits, a watch and another walk, 140 ticks, under both caps. Nothing hands those five to the mailbox. A plan cut to the cap is a plan partly written by the thing that cut it, because which five of seven to keep is a decision, and the check is not allowed to make one; the whole answer goes into the ledger as 529 bytes with the verdict beside it, and Mose runs the habit. Read the reasons in the table for what they are: five of the seven are the template's own descriptions copied back, and step 5's says hand while its verb says go. A check that read reasons would have something to argue with there. This one has a column it does not look at.

▣ Build · stage 13 — four plans that do not check, and the row count that proves it
$ go run ./cmd/plans -mode refuse -who Halla -now 2400 | tail -28

  the plan, recorded, which a model wrote and yours will differ from:
     # verb   argument                 ticks  reason, a model's, read by nothing
     1 go     to 2,7                      40  go walks to a cell
     2 wait   -                           20  wait stands still
  as recorded  accepted

  the first step's verb swapped for eat, which the table does not have
    the plan     2 steps spanning 20 ticks
    the seam     refused by verb: step 1: "eat" is not in the table
    dispatched   nothing; the plan is not trimmed to the steps that check

  the first step swapped for a wait that names a body
    the plan     2 steps spanning 40 ticks
    the seam     refused by verb: step 1: wait takes nothing, and the step names who
    dispatched   nothing; the plan is not trimmed to the steps that check

  the same plan with waits appended until it is 6 steps
    the plan     6 steps spanning 140 ticks
    the seam     refused by shape: a plan of 6 steps, and the cap is 5
    dispatched   nothing; the plan is not trimmed to the steps that check

  the same plan with walks home appended until it spans more than 160 ticks
    the plan     5 steps spanning 180 ticks
    the seam     refused by verb: a plan spanning 180 ticks, and the horizon is 160
    dispatched   nothing; the plan is not trimmed to the steps that check

  4 plans refused whole, 0 steps dispatched, and the one that checks is the one above

Two of the four cannot occur on the fixture as recorded, because the schema leaves the model no way to write a verb outside the table or a wait that names a body, and the other two did not happen to occur, because the model this volume runs answers in two steps more often than not. So the bench takes Halla's accepted plan and perturbs it itself, four ways, and says so: a check that has only ever been seen saying yes has not been seen. eat is refused by the verb check naming the word and the step; a wait carrying a body is refused naming what a wait takes and what the step named; six steps is refused by the shape check against the cap; and five steps that add up to 180 ticks is refused by the verb check against the horizon of 160, the plan being four walks and a wait. Every refusal is of the whole plan and dispatches nothing, and the bench stops with a non-zero status if any of the four is accepted.

⚠ Worked failure — a paragraph where an object was asked for

Here is the counterfactual, run: the same prompt, the same seed, the same model, and no schema on the request, which is what asking a model for a plan looks like before anybody has thought about the request's shape. The recording holds one such call for each villager at the last tick, and the bench selects it with a flag it prints.

$ go run ./cmd/plans -mode arrive -who Halla -noschema | tail -39 | head -25
  Halla's eyes at the boundary of tick 2900: nobody
  the situation, embedded and retrieved against: "nobody in sight"; the grounding set: 1 Halla, 2 Ander, 3 Mose
  the prompt: 1034 bytes, sha256 6f9a1c245cac1109, 361 tokens in, 256 out, stopped because: length
  what the model answered, which yours will differ from:
    | To determine what Halla remembers that bears on this, we need to analyze the given information about her actions and the steps she takes. Let's break it down step-by-step:
    |
    | 1. **Initial Setup:**
    |    - Halla stands on 9,2, 8,5.
    |    - Nobody is in sight.
    |
    | 2. **Analyzing Each Action:**
    |
    |    - **[86] ate 50 mouthfuls on 9,2, 25.0 grams:** 
    |      - This indicates that Halla has eaten 50 grams of food from her home (9,2) and gave the difference to Ander.
    |      - She then went to a cell with 8,5.
    |
    |    - **[11] Ander took 40 parcels out of Halla's hands, 20.0 grams:**
    |      - This suggests that Ander has taken 40 parcels from Halla and given them to her.
    |      - She then went to a cell with 9,2.
    |
    |    - **[84] went from 9,3 to 9,2:**
    |      - This indicates that Halla moved from 9,3 to 9,2.
    |      - She then
  read strictly: lang: qwen2.5:0.5b-instruct-q4_K_M answered with something that is not the shape asked for: invalid character 'T' looking for beginning of value
  the seam: refused by shape: lang: qwen2.5:0.5b-instruct-q4_K_M answered with something that is not the shape asked for: invalid character 'T' looking for beginning of value

Start from the symptom. The answer is 797 bytes of prose that begins To determine what Halla remembers, works through three of the eight memories as a numbered analysis, invents along the way that Halla gave the difference to Ander and that Ander gave forty parcels back to her, and stops mid-sentence because 256 tokens is where this world stops paying. It is labelled a model's, and it is a fair sample of what a small model does with a persona, eight memory lines and an open question: it explains them. Somewhere in the 797 bytes there may be a plan. The reader does not look for it. The first byte is a capital T, a JSON value cannot begin with one, and the strict read refuses the whole answer with that character named, which becomes the reason on the row, under the first check's name.

The cause is not the model and not the prompt. The prompt is the same 1,034 bytes, with the same sha256, that produced a two-step plan when the schema was on the request; the second live row above is that plan, and the third is a paragraph of the same kind, refused by the same character. The one thing that differs between the two rows is the format field, and the difference is a plan against a paragraph. What the schema does is steer the server's sampling so that every token it produces is one a plan could contain; without it the model is free to write what it writes, and what it writes, asked for a list of steps in words, is an essay about the list. The fix is the field, and the field is a request: the row is what makes the request honest, because a server that ignored the field, or an operator who took the field off, would produce exactly this row, refused by the same check for the same reason, and dispatch nothing. The obvious repair, scanning the paragraph for the six words and building a plan out of the ones found, would be the engine writing a plan the model did not, and the rule against it is the rule the last chapter gave for not trimming a citation list: a repaired answer is partly the repairer's.

The last thing an accepted plan needs to have been seen doing is crossing the seam. There is no scheduler on this page and no dispatcher: the second half of the validation, each step checked again at the moment it is due, is not built here, and neither is anything that decides when a villager is asked. What the keep mode does is smaller and exact. It takes Halla's accepted plan at 2400, and at every boundary for the ticks the table gives each step, it works the step out against her body as it stands, writes four numbers into her mailbox, and ticks the world. The tick side takes them or does not, the world's own check allows them or does not, and the witness writes down what happened, all of it by code earlier chapters built and this one does not touch.

▣ Build · stage 14 — sixty intents at the boundary, and thirty-five of them refused by the ground
// cmd/plans/replay.go — one step at a time, at the boundary, for the ticks the table gives it
		acts := map[beast.Act]int{}
		for t := 0; t < span; t++ {
			a := steer(rd.w, p, s)
			acts[a]++
			m.Box.Send(village.Intent{Act: a, Whom: s.Who, Grams: s.Grams, At: rd.now})
			rd.w.step()
			take()
		}
$ go run ./cmd/plans -mode keep -who Halla -now 2400 | tail -16

  the plan, accepted at the boundary of tick 2400, which a model wrote and yours will differ from:
     # verb   argument                 ticks  reason, a model's, read by nothing
     1 go     to 2,7                      40  go walks to a cell
     2 wait   -                           20  wait stands still
  Halla is on 9,3 carrying 109.6476 grams; the mailbox has been read 0 times and the habit has run 1500 ticks

     # verb   argument               posted  taken  habit refused  what the world did
     1 go     to 2,7                     40     40      0      35  2 turns, 38 walks: went from 9,3 to 8,3
     2 wait   -                          20     20      0       0  stood on 8,3

  60 intents posted at the boundary, 60 taken out of the slot, 0 ticks ran the habit
  the world's own check refused 35 of them: the cell ahead is open water or off the grid
  what the witness wrote down while the plan ran, in the register the stream is kept in
    tick  2403  did  went from 9,3 to 8,3
  Halla is on 8,3 carrying 102.9239 grams at the boundary of tick 2460

Sixty intents posted, sixty taken, and not one tick of the sixty ran the habit: the mailbox that had been read nought times in fifteen hundred ticks was read every tick for six seconds of world, and a villager that had only ever been driven by arithmetic was driven by a plan. Then read what the plan asked for and what the world did about it. The plan said go to 2,7. Halla stood on 9,3 facing wherever her habit had left her facing; two turns brought her heading round toward the cell and thirty-eight walks were posted, and thirty-five of the thirty-eight were refused by the world's own check, naming the cell ahead as open water. She got one cell west, to 8,3, and stood there while the plan's forty ticks ran out and its twenty of waiting ran after them. The witness closed one run for the plan's whole sixty ticks: went from 9,3 to 8,3, at tick 2403.

Cell 2,7 is the rim; nothing stands on it, and the pond lies straight across the bearing from Halla to it. The plan was accepted, and it was right to be: nothing about the shape or the table is wrong with a walk to a cell, and the two checks on this page are not handed a map. Whether a cell can be stood on, whether a body is where the step needs it and whether the world has moved since the step was asked are the checks the ledger names as reach and freshness, and they run at dispatch, because the world moves between arrival and dispatch and only the world can say. This run is what it looks like when the arrival half has said yes and the dispatch half is not there yet: the step reaches the slot as the model wrote it, and the last line of defence is the same check every animal has paid since the fifth volume, which refused thirty-five walks into a pond without being told that any of them came from a plan.

▣ Build · stage 15 — the recording, made again and held against the committed copy
$ podman exec -w /bench world-go go run ./cmd/plans -mode record | tail -29
  who     tick schema      took steps ticks  the seam
  Halla   1400 yes         3.3s     2    60  accepted
  Ander   1400 yes       4.905s     4   120  accepted
  Mose    1400 yes       7.272s     -     -  refused by shape: not the shape asked for: unexpected EOF
  Halla   1900 yes        3.62s     2    60  accepted
  Ander   1900 yes       7.291s     -     -  refused by shape: not the shape asked for: unexpected EOF
  Mose    1900 yes       3.647s     2    60  accepted
  Halla   2400 yes       6.262s     2    60  accepted
  Ander   2400 yes       9.569s     2    60  accepted
  Mose    2400 yes       6.188s     2    60  accepted
  Halla   2900 yes       3.564s     2    60  accepted
  Halla   2900 no         4.76s     -     -  refused by shape: not the shape asked for: invalid character 'T' lo...
  Ander   2900 yes       6.656s     2    60  accepted
  Ander   2900 no        4.758s     -     -  refused by shape: not the shape asked for: invalid character 'T' lo...
  Mose    2900 yes       5.872s     7   190  refused by shape: a plan of 7 steps, and the cap is 5
  Mose    2900 no        4.723s     -     -  refused by shape: not the shape asked for: invalid character 'T' lo...

  15 calls and 12 embeddings; every row a model answered was 768 numbers wide
  9 accepted and 6 refused on arrival, by the code above and not by anybody's reading
  written to plans95-plans.json, 139285 bytes, 15 calls

  against the copy this build carries
    exemplars/plans.json             c8a33073fc1d95c6    139285 bytes
    plans95-plans.json               c8a33073fc1d95c6    139285 bytes
    15 calls committed, 15 made here; of the first 15, 15 prompts are the same bytes
    and 15 answers are the same words, which is a fact about this machine and not a check

  1m27.52s inside the models, over 15 calls and 12 embeddings (measured here; yours will differ)
  1m27.573s for the whole recording (measured here; yours will differ)

Fifteen calls and twelve embeddings, because the three calls made without the schema were asked from the same boundary as the three made with it and read the same row. The recording is 139,285 bytes on disk, most of it the twelve rows of 768 numbers, none of which is printed. Every prompt came out the same bytes as the committed copy, which is the check; every answer came out the same words as well, which is what a seeded answer at temperature nought does on one machine and is not something the file promises. Nine accepted and six refused, live, by the same two checks, before the file was written; the day mode above reads the file and comes to the same fifteen verdicts, and the table above it is the reason the two agree: a verdict is a function of the bytes, the table and the caps, and none of the three is in the recording.

One object a decision: the arrival half of the seam, from answer bytes to a ledger row and a mailbox A vertical flow. At the top, the engine renders a prompt from the persona, the eyes at this boundary and the eight memories that came to mind, with the six verbs rendered from the table; it goes to the small model with a schema built from the same table and comes back as bytes. The bytes go through a strict read, then the shape check, then the verb check, each of which can refuse. Four further checks, grounding, law, reach and freshness, are drawn as an outlined box the page does not build. Every path ends in a ledger row, accepted or refused, with the answer's bytes kept; an accepted plan's steps go to the mailbox as intents at the boundary, and a refused one leaves the villager on the habit. ONE OBJECT A DECISION the engine's side persona, cell, home, the eyes, the 8 that came to mind, the verbs off the table the small model a schema off the same table, a limit, temp 0, a seed of the tick and the body bytes an object, a paragraph, or an object cut off at the limit Shaped: the strict read not JSON, a field too many, cut off: refused 1 shape at least one step, no more than the cap, a verb each 2 verb in the table, its argument, spans within the horizon 3 grounding, 4 law, 5 reach, 6 freshness: not on this page refused whole: the row keeps the bytes, the check and the reason; the habit runs a ledger row, appended accepted: the newest such row is the plan, and its steps reach the mailbox as intents the mailbox, four numbers, at the boundary
Figure 95.1 — the arrival half of the seam. One prompt the engine rendered, one answer as bytes, a strict read and two checks that need nothing but the table and the caps, and one row whatever happened. The outlined box is the four checks the ledger's column already names and this page does not run; the arrow out of the bottom right is the same slot the console has written to since the mailbox chapter.

Why verdicts read bytes and tables

Take the village away and what is left is a rule about where a decision may come from. Something outside the program produces text, and the program has to act on it. The usual arrangement lets the program read the text, in the sense of finding the parts it wants and doing its best with the rest, and the usual result is that the boundary between what the outside thing said and what the program decided is nowhere in particular. The arrangement here draws it in one place. The outside thing is asked for an object of a declared shape; the object is read by a reader that refuses anything that is not that shape; and what comes out of the reader is checked against a table the program owns, by functions that take the object, the table and two numbers and return a verdict. There is no step at which the program interprets. Either the bytes are a plan against the table or they are not, and the answer to that question is the same on every machine, which is why fifteen verdicts computed live before a file was written and fifteen computed afterwards from the file are the same fifteen.

The second thing that generalizes is the row. Every answer becomes a row before anything is done about it, and the row carries the bytes, the verdict and enough about the request to say what the bytes are an answer to. That makes the ledger the one place a question about the model can be asked. How often does it produce a plan; how often is a plan over the cap; what did it say the time it was refused. None of those can be asked of a system that keeps its accepted plans and drops its refusals, and a system that keeps its refusals in a log file and its plans in a table has two records that can disagree. One table, appended, with the plan defined as a query over it, means the plan store cannot disagree with the ledger because it is a view of it.

The third is the column nothing reads. A field that a person wants and the program does not need is dangerous in proportion to how tempting it is to read, and a reason is very tempting: it is right there, it is in words, and a line of code that refused a plan whose reason mentioned violence would look like prudence. It would also be the moment the seam stopped being a function of a table and started being a function of the model's prose, and from that moment the model could argue with the engine. So the field exists, it is stored, it is printed for a person, and a test walks the source of the package that decides to prove that no line of it looks. The rule is cheap to keep and expensive to get back once broken, and that is the kind of rule a test is for.

Checkpoint

✓ Checkpoint — six verbs, two checks, one row
  • Name the six verbs and, for each, the argument it takes and its span on the table; then say what a plan of a walk, a watch and a hand adds up to and whether the file's horizon takes it.
  • Say which of the two checks refuses a plan of seven steps, which refuses a wait that names a body, and which refuses four walks and a wait, and what each refusal's row records in its last two columns.
  • Given the fifteen columns of a proposal row, say for each whether the engine, the kit, the server, the retrieval or the model decided it, and why the one column the model decided is stored as bytes and not as steps.
  • From the three live rows, say why row 2 is Halla's current plan and not row 3, what query says so, and what would have to change in the table for a later decision to alter that answer.
  • From 418 and 3,149 milliseconds, work out a plan in ticks at ten a second, the round for twenty-four people, and the share of a villager's ticks a 160-tick horizon can cover at most.
  • Say what the keep run posted, what the tick side took, what the world's own check refused and why, and which of the six checks the ground's refusal belongs to and at which of the two moments it runs.
⚡ Exercises — try first, then reveal
Exercise 1 — a four-step plan crossing the seam. Ander's plan at tick 1400 is the one four-step plan the recording accepted. Run it through the keep mode and predict, from the table alone, how many intents are posted and how the watch step is dispatched against a body that is not in sight.

A hundred and twenty intents, and the watch turns toward Halla's cell:

$ go run ./cmd/plans -mode keep -who Ander -now 1400 | tail -17 | head -12
     2 wait   -                           20  Ander is not hungry anymore,
     3 watch  1 Halla                     20  Ander's body is empty,
     4 go     to 9,5                      40  Ander has no food left,
  Ander is on 8,5 carrying 150.7298 grams; the mailbox has been read 0 times and the habit has run 500 ticks

     # verb   argument               posted  taken  habit refused  what the world did
     1 go     to 9,5                     40     40      0       0  5 turns, 1 walks: went from 8,5 to 9,5
     2 wait   -                          20     20      0       0  stood on 9,5
     3 watch  1 Halla                    20     20      0       0  2 turns, then stood on 9,5
     4 go     to 9,5                     40     40      0       0  0 turns, 0 walks: went from 9,5 to 9,5

  120 intents posted at the boundary, 120 taken out of the slot, 0 ticks ran the habit

Forty, twenty, twenty and forty, which is the table's four spans and the plan's 120 ticks. The first walk is one cell east, home, and takes five turns and one walk to get there, after which the remaining ticks of the step are rests. The watch names Halla, who is not in Ander's sight at 1400; the bench turns him toward the cell the roster says she stands on, two turns, and he stands. That is the bench's dispatcher using knowledge the villager does not have, and it is exactly the case the grounding and reach checks exist for: the arrival checks passed a watch of a body Ander could name, because Halla is in his grounding set through his memories, and nothing on this page asks whether he can see her. The fourth step walks to the cell he is already on and posts forty rests. The meal that closed at tick 1400 is the run he was in when the plan arrived, closed by the walk.

Exercise 2 — the horizon at forty. The bench takes the caps as flags. Replay the whole recording with the horizon at 40 ticks and predict, from the day table, how many of the nine accepted plans survive and which check refuses the rest.

None survive, and every one is the verb check's:

$ go run ./cmd/plans -mode day -horizon 40 | tail -3
  15 calls, 15 prompts rendered here and every one the recorded bytes
  0 accepted, 15 refused: 6 by shape, 9 by verb
  every verdict above is the engine's over the recording; the words in the answers are the model's

Every accepted plan on the recording begins with a walk, and a walk is forty ticks on the table, so the cheapest accepted plan, a walk and a wait, is sixty, and a horizon of forty refuses all nine with the same sentence naming their span. The six shape refusals are untouched, because shape runs first and a paragraph is a paragraph whatever the horizon. The header prints the caps off the flags and says which file numbers they are not.

Exercise 3 — a seventh check name. Add a seventh word to the failed IN list in the tenth migration, run the store's tests, and say which test fails and what its message names. Then take the word back out, because a migration that has run anywhere is never edited.

TestTheSixChecksInTheSchemaAreTheLawsSix fails, and its message prints both lists in full: the seven words the schema now names and the six the law names. Nothing else notices. The migration numbering test passes, the whole-schema test passes, and a database migrated from the edited file would take a refusal named for the seventh word without complaint, which is the point of the test: the agreement between the two lists is not a property either file can hold on its own. Restore the file and the checksum test in the migrations chapter is the one that would have caught the edit on a database that had already run it.

Three people asked what they do next fifteen times over one day, nine plans, six rows of refusal, and every one of the fifteen in a table with the bytes that caused it. The table holds what a villager knew when it was asked, as a list of identities beside the answer, and nothing yet reads that list back. A plan that names a cell nobody can stand on is accepted here and refused by the ground later, thirty-five times, and a plan that named a body the villager had never seen would be accepted the same way. The four names the ledger's column already takes are the checks that read the grounding set, the law and the world, and they are where the second half of the sentence in the first section, each step again at dispatch, is made true.