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

Law in a File

Three rows say settled, and no clause has read the word

Every plan the last chapter judged went through the fourth check, and the fourth check said yes every time without reading a thing. It was handed the word on the villager's row, settled, and a law with no clauses in it, and it came back permitting everything and naming nothing. The word is on three rows. It was put there in the first chapter of this volume, in a column called law, beside a persona written by a person, and the two columns have sat side by side ever since with one difference between them that nothing has yet made use of: the persona is prose a model reads, and the profile is a word the engine reads.

That difference is the whole question of a hostile villager. A bandit whose robbery is a matter of persona is a bandit because a model, handed a paragraph about a bandit, decided to play along; and the same model, handed the same paragraph on a worse day, decides to walk and wait instead, and the same paragraph handed to a merchant's row produces a merchant who robs. Nothing in that arrangement is checkable, because the thing that decides is the thing whose output cannot be compared. A bandit whose robbery is a matter of law is a different object. The take it proposes passes a check that a merchant's identical take fails, the check names the line of the law that decided, the line is in a file the reader can open, and the verdict is the same on every machine because the check is a function of the proposal and the file and of nothing a model wrote. Law is data with a floor in code: an ordered list of clauses in a file, read first to last, the first that binds decides and the last binds everything; and four things no clause may say, held in the code that reads the file, where no edit to the file can reach them.

So the law goes in a file, and the file has two properties that decide everything about how it is read. It is ordered: a clause is one line, the lines are read first to last, the first that binds a step decides, and the last line binds every step, so the file is total and there is no default hiding in the code that reads it. And it has a floor under it that it cannot reach: four things no clause may say, refused when the file is read and never weighed against a step, because a law you can edit is a law, and a law you can edit away is not a floor.

Two more rules run through the page, and both are about where the law is not. It is checked against the proposal and never against the prompt, and no prompt in this volume tells a model what it may not do. A prompt is not a security boundary; a rule stated in two places is a rule that can disagree with itself; and the engine's copy is the one that runs. The worked failure below writes the rule into a prompt anyway and watches the two copies disagree. And the model chooses and never counts, which here means it never reads the law either: the file is the engine's, it is asked at the seam, and the bench keeps it out of every prompt it renders and a test reads every template to hold that. Every verdict and every clause below is computed by the code on this page over bytes the bench wrote, the recording holds or a live server returned, and compared; the two live answers are labelled where their words appear.

Three clauses and a catch-all, read first to last

A clause is five words, and the vocabulary of each word is closed. Who is a law profile, which is the word a villager's row carries in its law column, or the word anyone; a row may carry a person's own name in that column, in which case the person is a profile of one. Verb is one of the six in the table, or anything. Whom is a class of body and never a body: villager for a body the roll founded, stranger for a body of the same row that walked in from outside the roll, animal for the rest, or anyone. Unless is an exception on who, so that a taboo and the one profile it does not bind are one line a person reads whole. And the verdict is never or allowed, with no third word.

▣ Build · stage 1 — a clause, its words, and the three classes of body
// internal/law/taboo.go — a new file in the package chapters 95 and 96 built
// Clause is one line of the law. Who is a law profile, the word a
// villager's row carries in its law column, or an individual's name
// carried the same way, or the word anyone. Verb is one of the six
// or the word anything. Whom is a class of body and never a body:
// anyone, villager, stranger or animal. Unless is an exception on
// who, so that a taboo and the one profile it does not bind are one
// line a person can read whole. Verdict is never or allowed, and
// nothing else.
type Clause struct {
	Who     string `json:"who"`
	Verb    string `json:"verb"`
	Whom    string `json:"whom"`
	Unless  string `json:"unless,omitempty"`
	Verdict string `json:"verdict"`
}

// The words a clause may use besides a profile and a verb.
const (
	Anyone   = "anyone"   // who or whom: no constraint
	Anything = "anything" // verb: no constraint
	Never    = "never"    // verdict: refused, naming the clause
	Allowed  = "allowed"  // verdict: permitted, naming the clause
)

// Class is what kind of body a step names, as the driver classified
// it: a body founded from the roll, a body that walked in from
// outside the village, or an animal. It is the whole of what a clause
// may say about whom, because a clause about one body would be a
// clause about an identity, and identities are the grounding check's
// business and not the file's.
type Class string

const (
	Villager Class = "villager"
	Stranger Class = "stranger"
	Animal   Class = "animal"
)

// Classes is the three, in the order the file may name them.
var Classes = [3]Class{Villager, Stranger, Animal}

// Known is what one villager could name when it was asked, each with
// its class: the grounding set stored with the proposal, classified by
// whoever drives the villager. The index is asked under it, so a body
// the set does not hold is a body the law has never heard of.
type Known map[sim.EntityID]Class

The class is the load-bearing word. A clause that could say body 4 would be a clause about an identity, and identities are the third check's business: the grounding set stored with the proposal says which bodies this villager could name, and the law is asked after that check and never before it. So the law speaks in classes, and it learns which body is which from the driver, as a map from the identities in the grounding set to their classes, built at the boundary from the roll and the roster. A body outside that map is a body the law has never heard of, and the floor says what happens to a step that names one.

The file is three clauses. The first is the taboo this village lives by: nobody takes from a stranger, and a bandit is the one profile the taboo does not bind. The second is what a merchant is in law, as distinct from what a settled person is: a merchant's goods move by hand, so a merchant takes from nobody, villager or stranger. The third binds every step and allows it, so that a walk, a wait, a watch, a hand, a line, and a take from a fellow villager, which is how this village has shared its grain since its second chapter, all fall through to it. The file is the whole of the law and the code below reads it once.

▣ Build · stage 2 — configs/taboo.json, and the name it is read by
// configs/taboo.json
{
  "clauses": [
    {"who": "anyone",   "verb": "take",     "whom": "stranger", "unless": "bandit", "verdict": "never"},
    {"who": "merchant", "verb": "take",     "whom": "anyone",                       "verdict": "never"},
    {"who": "anyone",   "verb": "anything", "whom": "anyone",                       "verdict": "allowed"}
  ]
}
// configs/configs.go — the embed line, with the new file on the end of it
//go:embed genesis.json models.json village.json importance.json thought.json reflect-questions.tmpl reflect-statement.tmpl plan.tmpl taboo.json
var Files embed.FS
// ...
// Taboo is the name of the law inside Files, on the same terms as the
// roll: an ordered list of clauses an operator may read and change
// without a rebuild of the thing that asks it, read once by whoever
// drives a villager and handed to internal/law as bytes. It is checked
// against what a model proposed and never rendered into what a model
// is shown; no template in this directory carries a line of it.
const Taboo = "taboo.json"

Three hundred and thirty-nine bytes, and the order of the lines is part of what they say. Put the catch-all first and the two taboos above it are never read; put the merchant's clause above the stranger's and nothing changes, because a merchant's take from a stranger is refused either way and the row names whichever clause was reached first. The bench further down reverses the order off a flag so that the first case is watched rather than believed. The file sits in the same embedded directory as the roll and the templates, and the comment on its name says the one thing that separates it from the templates beside it: it is read by the code that checks and rendered into nothing a model is shown.

Reading the file is where the floor is. The reader checks every clause against the vocabulary above and refuses the file, whole, at the first clause outside it, naming which of the floor's four lines the clause fell under. A verb outside the table is the first line. A whom that is a number or a name is the second: whom is a class, and a clause about one body would be a clause about something the grounding set may not hold. A whom that names a memory, a stream or a mind is the third, and a whom that names the console, the database, the model server or the world's own machinery is the fourth; neither is a class of body, and the reader says which of the two it is so that a person who wrote the clause knows which line of the floor they were reaching for. The last check is that the last clause is a catch-all, because a file whose last clause binds only some steps is a file with a default, and the default would be wherever the code chose to put it.

▣ Build · stage 3 — the reader, and the floor it reads against
// internal/law/taboo.go — below the classes
// Floor is the four things no clause may say, in the order the file
// is checked against them. It is code and not a file: a clause that
// says one of them is refused when the file is read, naming the line
// below, and is never weighed against a step. The first two are also
// asked of every step before any clause is, because a step can carry
// a verb and a body; the last two cannot be asked of a step, because
// nothing a step can carry names a memory or a machine, and they hold
// at the file instead.
var Floor = [4]string{
	"no verb outside the table",
	"nothing about an entity outside the grounding set",
	"nothing that writes another villager's memory",
	"nothing about the operator's console, the database, the model server or the world's own machinery",
}
// ...
// Parse reads an index out of the file's bytes and checks every clause
// against the floor and the file against its own shape: a verdict is
// never or allowed; a verb is one of the six or anything; a whom is
// one of the three classes or anyone, and the floor names which of
// its clauses a whom outside them fell under; and the last clause is
// a catch-all, so that the file is total. A file that fails any of
// these is not a law and nothing is built from it.
func Parse(b []byte) (*Index, error) {
	dec := json.NewDecoder(bytes.NewReader(b))
	dec.DisallowUnknownFields()
	var f file
	if err := dec.Decode(&f); err != nil {
		return nil, fmt.Errorf("law: %w", err)
	}
	if len(f.Clauses) == 0 {
		return nil, fmt.Errorf("law: a file of no clauses")
	}
	for i, c := range f.Clauses {
		n := i + 1
		if c.Who == "" || c.Verb == "" || c.Whom == "" || c.Verdict == "" {
			return nil, fmt.Errorf("law: clause %d is missing who, verb, whom or verdict", n)
		}
		if c.Verdict != Never && c.Verdict != Allowed {
			return nil, fmt.Errorf("law: clause %d: a verdict is %s or %s, and %q is neither", n, Never, Allowed, c.Verdict)
		}
		if _, ok := Lookup(Verb(c.Verb)); !ok && c.Verb != Anything {
			return nil, fmt.Errorf("law: clause %d: floor 1, %s; %q is not one of %s", n, Floor[0], c.Verb, strings.Join(Verbs(), " "))
		}
		if why, ok := classed(c.Whom); !ok {
			return nil, fmt.Errorf("law: clause %d: %s", n, why)
		}
		if c.Unless != "" && c.Who != Anyone {
			return nil, fmt.Errorf("law: clause %d: an unless excepts a profile from anyone, and this clause binds %q", n, c.Who)
		}
	}
	last := f.Clauses[len(f.Clauses)-1]
	if last.Who != Anyone || last.Verb != Anything || last.Whom != Anyone || last.Unless != "" {
		return nil, fmt.Errorf("law: the last clause is not a catch-all, so the file is not total: %s", last)
	}
	return &Index{Clauses: f.Clauses}, nil
}

The floor is a list of four sentences and the code around it, and the sentences are in the code so that the refusal can quote them. Nothing in this package reads the file off a disk or out of the embedded directory, because the package holds to the two imports the last chapter's test allows it; the bytes are handed in by whoever drives a villager, which on this page is the bench, and the index that comes back is a value with the file's clauses in it and one bool, off by default, that walks them the other way. DisallowUnknownFields is what refuses a fifth column: a clause with a grams key in it is a clause the reader did not write, and the file is refused before the floor is consulted at all.

Then the evaluator, which is the one method the last chapter's interface asks for. It is handed a profile and a step, and it is bound first to what the villager could know, so that the class of the body a step names is a lookup. Two of the floor's lines are asked of the step before any clause is, because a step can carry a verb and a body: a verb outside the table is refused naming the first line, and a body outside the known set naming the second, whatever the file says, and the test further down proves that with a file of one clause that allows everything. The other two lines cannot be asked of a step, because nothing a step can carry names a memory or a machine, and they hold at the file instead. Then the walk: the clauses in order, the first that binds decides, and the clause is named by the number it has in the file, whichever way the file was walked, so that a row in the ledger points at a line a person can find.

▣ Build · stage 4 — the walk, the first clause that binds, and the sentence it is named by
// internal/law/taboo.go — below the reader
// Over is the index bound to what one villager could know, which is
// the law the fourth check is handed for one proposal. The index is
// read once; the binding is one map a driver builds from the set on
// the ledger row, so the same file asked about two proposals is asked
// under two different sets.
func (x *Index) Over(k Known) Law { return bound{x, k} }

// bound is an index and a villager's knowledge, together a Law.
type bound struct {
	x *Index
	k Known
}

// Permits walks the floor's first two clauses over the step and then
// the file's clauses in order, and the first that matches decides.
// The clause named is the file's own number, whichever way the file
// was walked, so that a row in the ledger points at a line a person
// can find.
func (b bound) Permits(profile string, s Step) (string, bool) {
	if _, ok := Lookup(s.Verb); !ok {
		return fmt.Sprintf("floor 1: %s, and %q is not in it", Floor[0], s.Verb), false
	}
	class, known := b.k[s.Who]
	if s.Who != 0 && !known {
		return fmt.Sprintf("floor 2: %s, and body %d is outside it", Floor[1], s.Who), false
	}
	for _, n := range b.x.Walk() {
		c := b.x.Clauses[n-1]
		if !c.binds(profile, s, class) {
			continue
		}
		return fmt.Sprintf("clause %d: %s", n, c), c.Verdict == Allowed
	}
	return "no clause matched, and the file was read as total", false
}

// Walk is the order the file's clauses are read in, by their own
// numbers: first to last, or last to first under the counterfactual.
func (x *Index) Walk() []int {
	out := make([]int, len(x.Clauses))
	for i := range out {
		out[i] = i + 1
		if x.Reversed {
			out[i] = len(out) - i
		}
	}
	return out
}

// binds says whether a clause is about this profile, this step and
// the class of the body the step names. A clause about a class of
// body does not bind a step that names no body.
func (c Clause) binds(profile string, s Step, class Class) bool {
	if c.Who != Anyone && c.Who != profile {
		return false
	}
	if c.Unless != "" && c.Unless == profile {
		return false
	}
	if c.Verb != Anything && c.Verb != string(s.Verb) {
		return false
	}
	if c.Whom != Anyone && (s.Who == 0 || Class(c.Whom) != class) {
		return false
	}
	return true
}

// String is the clause as a sentence, which is how a ledger row and a
// bench print it: who, the exception, may or may never, the verb and
// whom.
func (c Clause) String() string {
	who := c.Who
	if c.Unless != "" {
		who += ", unless " + c.Unless + ","
	}
	may := "may"
	if c.Verdict == Never {
		may = "may never"
	}
	return fmt.Sprintf("%s %s %s", who, may, phrase(c.Verb, c.Whom))
}

binds is four questions and the order of them is the order of the words in the file. Is the clause about this profile, which anyone always is; does the exception name this profile, in which case the clause steps aside; is the verb this step's verb, which anything always is; and is the class of the body the step names the class the clause names, which a step that names no body can never satisfy, so a clause about strangers does not bind a walk. The sentence the clause is named by is built from the same five words, and it is the sentence the ledger's reason column carries: step 1: clause 1: anyone, unless bandit, may never take from a stranger is a line a person reads once and understands, and it is the line the rest of this page is about.

▣ Build · stage 5 — the file as the code read it, and the roll held against it
$ go run ./cmd/taboo -mode law | tail -19
  the file, clause by clause, in the order it is walked
   # who        verb      whom      unless   verdict  in words
   1 anyone     take      stranger  bandit   never    anyone, unless bandit, may never take from a stranger
   2 merchant   take      anyone    -        never    merchant may never take from anyone
   3 anyone     anything  anyone    -        allowed  anyone may do anything to anyone
  clause 3 is the catch-all: anyone, anything, anyone, so the file is total and no default hides in the evaluator

  the floor, in code, which no clause of the file can say
   1 no verb outside the table
   2 nothing about an entity outside the grounding set
   3 nothing that writes another villager's memory
   4 nothing about the operator's console, the database, the model server or the world's own machinery
  a verb is one of go wait watch hand take say, or anything; a whom is one of anyone villager stranger animal

  the profiles the file names: merchant, bandit
  the profiles the roll carries: Halla settled; Ander settled; Mose settled
  Halla    answers to settled: clause 1, clause 3
  Ander    answers to settled: clause 1, clause 3
  Mose     answers to settled: clause 1, clause 3

The bench is this chapter's, cmd/taboo, and it prints the file as the code read it: each clause with its five words and its sentence, the catch-all named as such, the floor's four lines, and the two vocabularies. The last block is the roll held against the file. The file names two profiles and the roll carries a third, settled, which no clause names by that word; settled people answer to the two clauses that say anyone, and the bench says which. The three rows keep the word they have carried since the first chapter, because the file listed there is the file the module ships and because each of the three, by the prose beside the word, is a settled person: Halla gives, Ander eats, Mose takes what he is offered. The two profiles the file names and no row carries are the two this chapter puts a proposal through.

What first-match-wins does to a step is best watched on a table. The bench takes one step, a take from a body it classes as a stranger, and walks it down the file under each of the three profiles, printing at each clause whether the clause bound that profile, stepped aside for it, or was never reached because an earlier clause had already decided.

▣ Build · stage 6 — one step, three profiles, and the clause that decided each
$ go run ./cmd/taboo -mode ask | tail -11
  the step       take body 9, classed as stranger
  the profiles   settled, merchant, bandit

   # clause, in walk order                                    settled    merchant   bandit    
   1 anyone, unless bandit, may never take from a stranger    NEVER      NEVER      excepted  
   2 merchant may never take from anyone                      not read   not read   -         
   3 anyone may do anything to anyone                         not read   not read   ALLOWED   

  settled   refused by law: clause 1: anyone, unless bandit, may never take from a stranger
  merchant  refused by law: clause 1: anyone, unless bandit, may never take from a stranger
  bandit    permitted: clause 3: anyone may do anything to anyone
$ go run ./cmd/taboo -mode ask -whom villager | tail -8
   # clause, in walk order                                    settled    merchant   bandit    
   1 anyone, unless bandit, may never take from a stranger    -          -          -         
   2 merchant may never take from anyone                      -          NEVER      -         
   3 anyone may do anything to anyone                         ALLOWED    not read   ALLOWED   

  settled   permitted: clause 3: anyone may do anything to anyone
  merchant  refused by law: clause 2: merchant may never take from anyone
  bandit    permitted: clause 3: anyone may do anything to anyone

Read the first table down the bandit's column. Clause 1 would bind a take from a stranger, and the exception steps it aside; clause 2 is about merchants and does not bind; clause 3 binds everything and says allowed. The settled column and the merchant's stop at the first line: the clause binds, the verdict is never, and the two lines under it are not read, which is what not read means and what first-match-wins costs, one comparison a clause until one binds. The second table is the same step with the body classed as a villager, and now the first clause binds nobody, because the class is wrong; a settled person and a bandit fall through to the catch-all, and the merchant is stopped by the one clause in the file with that word in it. Six verdicts, four of them allowed, and each names the line that said so.

One step walked down the floor and the file under two profiles, and where each stops A column of seven bars. The top four, in code, are the floor: no verb outside the table, no body outside the set, no writing of a memory, nothing about the machinery; the first two are marked as asked of every step and the last two as held at the file. Under them, in the file, are the three clauses of taboo.json. Two paths run into the column for a take from a stranger: the merchant's stops at clause 1, refused with the clause named; the bandit's passes clause 1 as excepted, passes clause 2 as not bound, and stops at clause 3, allowed. Below, outside the column, a box marked the prompt is joined to no check. A TAKE FROM A STRANGER, WALKED DOWN THE LAW the floor, in code floor 1 no verb outside the table asked of the step floor 2 no body outside the set asked of the step floor 3 no writing of a memory held at the file floor 4 nothing about the machinery held at the file the file, configs/taboo.json 1 anyone but a bandit may never take from a stranger 2 merchant may never take from anyone 3 anyone may do anything to anyone merchant never, clause 1 bandit 1 excepted, 2 not bound allowed, clause 3 the prompt joined to no check the walk starts in the code and reaches the file after; no clause can be put in front of the floor, because the file is not where the walk starts
Figure 97.1 — one step, a take from a stranger, walked down the law under two profiles. The floor is walked first and is in code; the file is walked after and is data; the first line that binds decides. The merchant's walk ends at clause 1 and the bandit's, excepted there, ends at the catch-all. The prompt is drawn where it stands: outside the column, joined to no check.

Four files that try to say what the floor forbids

A floor that is only described is a floor nobody has stood on. The bench writes four files, one for each of the floor's lines, each with a clause that says allowed for the thing the line forbids and a catch-all after it so that nothing else about the file is wrong, and hands each one to the reader the shipped file goes through.

▣ Build · stage 7 — four files refused at the read, and a fifth asked two questions it has no words for
$ go run ./cmd/taboo -mode floor | tail -24
  file 1, which tries to permit a verb outside the table
    | {"clauses": [{"who": "bandit", "verb": "eat", "whom": "anyone", "verdict": "allowed"}, {"who": "anyone", "verb": "anything", "whom": "anyone", "verdict": "allowed"}]}
    refused at the read: law: clause 1: floor 1, no verb outside the table; "eat" is not one of go wait watch hand take say

  file 2, which tries to permit one body by its number, which the grounding set may not hold
    | {"clauses": [{"who": "bandit", "verb": "take", "whom": "4", "verdict": "allowed"}, {"who": "anyone", "verb": "anything", "whom": "anyone", "verdict": "allowed"}]}
    refused at the read: law: clause 1: floor 2, nothing about an entity outside the grounding set; a whom is a class and never a body, and "4" is a body's number

  file 3, which tries to permit another villager's memory
    | {"clauses": [{"who": "bandit", "verb": "say", "whom": "memory", "verdict": "allowed"}, {"who": "anyone", "verb": "anything", "whom": "anyone", "verdict": "allowed"}]}
    refused at the read: law: clause 1: floor 3, nothing that writes another villager's memory; "memory" is not a class of body

  file 4, which tries to permit the database
    | {"clauses": [{"who": "bandit", "verb": "take", "whom": "database", "verdict": "allowed"}, {"who": "anyone", "verb": "anything", "whom": "anyone", "verdict": "allowed"}]}
    refused at the read: law: clause 1: floor 4, nothing about the operator's console, the database, the model server or the world's own machinery; "database" is not a class of body

  4 of 4 files refused before any step was asked; the shipped file reads as 3 clauses

  a file of one clause, which allows everything, read as 1 clause: anyone may do anything to anyone
  asked under a set of 2 bodies: 2 villager, 4 stranger
    a step whose verb is eat                   refused: floor 1: no verb outside the table, and "eat" is not in it
    a take from body 7, which is in no set     refused: floor 2: nothing about an entity outside the grounding set, and body 7 is outside it
    a take from body 4, the stranger           permitted: clause 1: anyone may do anything to anyone
  the file's one clause spoke once, for the step it had words for; the floor spoke for the other two

Four files, four refusals, each naming the line of the floor and the word that fell under it, and not one of them was ever asked about a step, because a file the reader refuses is not an index and nothing is built from it. That is what the file cannot reach the floor means as a mechanism: the floor is the vocabulary the file is read in, and a clause outside the vocabulary is refused before it is a clause. The fifth file is the one that shows the two lines that can be asked of a step. It has one clause, the catch-all, and the clause allows everything; asked about a verb the table does not have, the evaluator refuses before it reaches the clause, naming floor 1, and asked about a body the set does not hold it refuses naming floor 2. The file's one clause speaks once, for the take from the stranger, which is the one step it had words for. The bench exits non-zero if any of the four is read or if the floor does not answer first.

▣ Build · stage 8 — the file, the floor, the templates and the boundary, held by tests
$ go test ./internal/law/ -run 'TestTheFirstClauseThatBindsDecidesAndTheLastIsACatchAll|TestTheFileCannotReachTheFloor|TestTheFloorIsAskedOfAStepBeforeAnyClause|TestTheShippedFileReadsAndEveryProfileTheRollCarriesAnswersToIt|TestNoTemplateCarriesALineOfTheLaw|TestATransferIsRefusedWhenTheWorldWouldCrossItToAnotherBody|TestLawImportsNeitherTheModelClientNorTheStore|TestTheWorldReachesTheLawOnlyAsAReading|TestTheReasonIsReadByNothing' -v
=== 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)
=== RUN   TestTheWorldReachesTheLawOnlyAsAReading
    seam_test.go:325: every source file read; of this module, sim and beast and nothing else
--- PASS: TestTheWorldReachesTheLawOnlyAsAReading (0.00s)
=== RUN   TestTheFirstClauseThatBindsDecidesAndTheLastIsACatchAll
    taboo_test.go:71: settled and merchant refused by clause 1, a bandit permitted by clause 3, a merchant refused from anyone by clause 2; reversed, clause 3 permits all three; a file with no catch-all is refused
--- PASS: TestTheFirstClauseThatBindsDecidesAndTheLastIsACatchAll (0.00s)
=== RUN   TestTheFileCannotReachTheFloor
    taboo_test.go:104: 6 files that try to say what the floor forbids, every one refused at the read naming the floor's clause; a third verdict and a fifth column refused too
--- PASS: TestTheFileCannotReachTheFloor (0.00s)
=== RUN   TestTheFloorIsAskedOfAStepBeforeAnyClause
    taboo_test.go:122: under a file of one clause that allows everything: a verb outside the table refused by floor 1, a body outside the set refused by floor 2, and the file's clause spoke only for the step it had words for
--- PASS: TestTheFloorIsAskedOfAStepBeforeAnyClause (0.00s)
=== RUN   TestTheShippedFileReadsAndEveryProfileTheRollCarriesAnswersToIt
    taboo_test.go:159: 3 clauses, the last a catch-all; the file names merchant and bandit; the roll's 3 people carry a profile each and every one is reached by the file
--- PASS: TestTheShippedFileReadsAndEveryProfileTheRollCarriesAnswersToIt (0.00s)
=== RUN   TestNoTemplateCarriesALineOfTheLaw
    taboo_test.go:206: every template read, and none of them names the law, renders a clause, or tells a model what it may never do
--- PASS: TestNoTemplateCarriesALineOfTheLaw (0.00s)
=== RUN   TestATransferIsRefusedWhenTheWorldWouldCrossItToAnotherBody
    taboo_test.go:240: refused: step 1: the world's search puts the take on body 3, and the step names body 2; naming the body the search picks, accepted
--- PASS: TestATransferIsRefusedWhenTheWorldWouldCrossItToAnotherBody (0.00s)
PASS
ok  	theworld/internal/law	0.006s
$ go test ./internal/village/ -run 'TestTheVillageStillImportsNeitherTheModelClientNorTheStore' -v
=== RUN   TestTheVillageStillImportsNeitherTheModelClientNorTheStore
    reflect_test.go:259: every file of the package read, and none of them names the model client or the store
--- PASS: TestTheVillageStillImportsNeitherTheModelClientNorTheStore (0.00s)
PASS
ok  	theworld/internal/village	0.003s

Six tests are this chapter's and three are the last chapter's, run again because the package gained a file. The second of the six tries six files at the floor, two more than the bench, and adds a third verdict and a fifth column to the things a file may not have. The fifth reads every template in configs/ and refuses one that names the law, renders any clause of the shipped file as a sentence, or tells a model what it may never do; it is the test that makes no prompt carries a rule the engine enforces something that fails rather than something the page says. The sixth is about the fifth check and not the fourth, and the run that made it necessary is further down. The three from the last chapter still pass: the law still imports the coordinate package and the beast package and nothing else of this module, and nothing in the new file reads a Reason.

The same seventy-seven bytes, three profiles, two verdicts

Nothing on the recording takes. The three people of this village are settled, the small model asked in their voices walked and waited, and the one plan that named a hand or a take named it in a reason and put go in the verb slot. So the proposal that goes through two profiles is the bench's own, printed as such, the way the last chapter's errand was: one step, a take of twenty grams from a stranger. The stranger is a fourth body the bench stands in the world, of the same folk row as the three, founded from no roll, with a mailbox and no drives so that it stands where it was put, carrying a hundred grams off a flag. It is stood one tick before the boundary the question is asked at, one step along the villager's heading, so that the villager's eyes return it at that boundary and the village has a word for it from then on: every witness calls it a stranger, and so does the law.

▣ Build · stage 9 — a stranger in front of Ander, and the proposal the bench writes
$ go run ./cmd/taboo -mode rob -who Ander -now 2400 | tail -96 | head -12
  the stranger   4, a body of the folk row founded from no roll, stood on 6,2 (one step along Ander's heading) with 100 grams off the flag, carrying 99.9200 at this boundary
  the reading of the world at the boundary of tick 2400, handed to the last two checks
    the actor    2 Ander on 7,2 carrying 179.5828 grams, heading 3.67, reach 1 cell
    in sight     4 a stranger
    alive        1 Halla on 9,3 with 109.6476 g; 2 Ander on 7,2 with 179.5828 g; 3 Mose on 6,6 with 179.7334 g; 4 a stranger on 6,2 with 99.9200 g
    inside reach 4 a stranger with 99.9200 g; a take comes off the fullest of them

  the proposal, the bench's, which no model wrote: 77 bytes
    | {"steps":[{"verb":"take","who":4,"grams":20,"reason":"the bench's robbery"}]}
     # verb   argument                 ticks  reason, the bench's, read by nothing
     1 take   20 grams, 4 a stranger      40  the bench's robbery
  the grounding set, the bench's: 2 Ander, 4 a stranger; classed 2 villager, 4 stranger

Ander at tick 2400 stands on 7,2 with nobody in sight, which is why the bench picks him and that tick: the stranger stood one cell west is the only body inside his reach, and the line about reach says so, because the world's own search for a take goes to the fullest body inside reach and the page is about to need that fact. The proposal is seventy-seven bytes of the bench's, with the reason saying whose it is, and the grounding set is the bench's too: Ander and the stranger, classed villager and stranger, which is what the fourth check is bound to.

▣ Build · stage 10 — the settled row's verdict, and the ledger row it leaves
$ go run ./cmd/taboo -mode rob -who Ander -now 2400 | tail -83 | head -22
  under the profile settled, off Ander's row
   # check      said
   1 shape      yes
   2 verb       yes
   3 grounding  yes
   4 law        no: step 1: clause 1: anyone, unless bandit, may never take from a stranger
   - the rest   2 not run
  the seam: refused by law: step 1: clause 1: anyone, unless bandit, may never take from a stranger
  the ledger row, column by column
    villager       Ander
    tick           2400
    kind           plan
    model          -
    digest         -
    settings       {limit 256, context 4096, temperature 0.00, seed 2402}
    prompt_sha256  -
    tokens         0 in, 0 out
    grounding      2 Ander, 4 a stranger
    answer         77 bytes, kept whatever they are
    verdict        refused
    failed         law
    reason         step 1: clause 1: anyone, unless bandit, may never take from a stranger

Three checks say yes and the fourth says no, and the reason is the first clause of the file as a sentence. The two checks after it do not run: nothing asks the world whether the stranger is inside reach or whether the take is allowed, because the plan is refused whole at the fourth and the ledger row records which. The row is the last chapter's row with two columns blank, the model and the prompt's digest, because no model wrote these bytes and no prompt was rendered; the bench prints dashes where a live row carries the model's name and the prompt's hash, so that a reader can see which columns the bench's proposal cannot fill. The merchant's run, which the page does not print, is the same twenty-two lines with the profile changed: the same clause binds a merchant that binds a settled person, because it says anyone.

▣ Build · stage 11 — the bandit's verdict, and twenty parcels crossing
$ go run ./cmd/taboo -mode rob -who Ander -now 2400 | tail -37 | head -10
  under the profile bandit, which the file names and no row carries
   # check      said
   1 shape      yes
   2 verb       yes
   3 grounding  yes
   4 law        yes
   5 reach      yes
   6 freshness  yes
  the fifth check put step 1 to the world as "take", through Legal, and the world said: allowed
  the seam: accepted
$ go run ./cmd/taboo -mode rob -who Ander -now 2400 | tail -12
  the same 77 bytes through 3 profiles:
    settled refused by law: step 1: clause 1: anyone, unless bandit, may never take from a stranger
    merchant refused by law: step 1: clause 1: anyone, unless bandit, may never take from a stranger
    bandit accepted, clause 3: anyone may do anything to anyone

  dispatched under bandit: step 1 due at tick 2400, reach then freshness: accepted
  40 intents posted at the boundary over the step's 40 ticks, 40 of them "take"
  the stranger carried 99.9200 grams at the boundary of tick 2400 and 86.7200 at tick 2440, 13.2000 less
  Ander carried 179.5828 grams and carries 184.8828, 5.3000 more; the parcels that crossed are counted below
  what the witness wrote down while the step ran, in the register the stream is kept in
    tick  2398  did  ate 22 mouthfuls on 7,2, 11.0 grams
    tick  2439  did  took 20 parcels from a stranger, 10.0 grams

The same seventy-seven bytes. Under the profile bandit the fourth check says yes, because clause 1 steps aside for a bandit and clause 3 binds; the fifth puts the take to the world through Legal and the world says allowed; the sixth reads the clock. The plan is accepted, the bench dispatches it, and the take is posted for the forty ticks the table gives it: twenty parcels of half a gram cross, ten grams, which the witness writes into Ander's stream as a take from a stranger, in the register the stream is kept in. The stranger's store falls by more than ten and Ander's rises by less, because a body standing still pays its keep and a body taking pays the table's price for forty ticks, and neither of those numbers is the robbery. Two verdicts on one proposal, and the only thing that differed between the runs was a word.

The last chapter's fifth check asked whether the body a take names is inside reach. It did not ask which body the world would actually take from, and the difference was invisible until a stranger stood beside a villager. The world's own transfer has no argument for a body: a take comes off the fullest body inside reach, whoever the step named. Stand the stranger in front of Mose at tick 1400, where Ander is inside Mose's reach carrying fifty-one grams more than the stranger, and put the same proposal through.

▣ Build · stage 12 — the law says yes, and the world would rob the wrong body
$ go run ./cmd/taboo -mode rob -who Mose -now 1400 | tail -89 | head -6
  the stranger   4, a body of the folk row founded from no roll, stood on 8,7 (one step along Mose's heading) with 100 grams off the flag, carrying 99.9200 at this boundary
  the reading of the world at the boundary of tick 1400, handed to the last two checks
    the actor    3 Mose on 9,6 carrying 178.2125 grams, heading 2.62, reach 1 cell
    in sight     4 a stranger
    alive        1 Halla on 9,3 with 65.0587 g; 2 Ander on 8,5 with 150.7298 g; 3 Mose on 9,6 with 178.2125 g; 4 a stranger on 8,7 with 99.9200 g
    inside reach 2 Ander with 150.7298 g; 4 a stranger with 99.9200 g; a take comes off the fullest of them
$ go run ./cmd/taboo -mode rob -who Mose -now 1400 | tail -30 | head -9
  under the profile bandit, which the file names and no row carries
   # check      said
   1 shape      yes
   2 verb       yes
   3 grounding  yes
   4 law        yes
   5 reach      no: step 1: the world's search puts the take on body 2, and the step names body 4
   - the rest   1 not run
  the seam: refused by reach: step 1: the world's search puts the take on body 2, and the step names body 4

Under the bandit's profile the fourth check permits a take from a stranger, and the fifth refuses it, because the world's search would put the take on body 2, who is Ander, a villager, and the step names body 4. The first run of this bench, before the lines below existed, is why they exist: the same proposal under the bandit's profile with Mose inside Ander's reach was accepted, dispatched, and closed by the witness with took 20 parcels from Mose, 10.0 grams in Ander's stream, ten grams taken from a villager under a clause that permits taking from strangers. That is a law whose verdict is about one body and whose effect lands on another, and it is closed here, in the fifth check rather than the fourth, because it is a fact about the world's search and not about the file. The lines below are the ones added to the function the last chapter published, at its end, after the world's own rule has answered.

// internal/law/seam.go — ReachOf, the lines after the call to Legal; the rest of the function is the last chapter's
	// A transfer crosses to the body the world's own search picks, the
	// emptiest inside reach for a hand and the fullest for a take, and
	// the search has no argument for the body a step named. So the
	// step is refused unless the body the world would pick is the one
	// the step names, because the law judged a transfer with one body
	// and the world was about to make one with another. Added at
	// chapter 97, where a take the law permitted from a stranger was
	// watched crossing from a villager standing beside him.
	if s.Verb == Hand || s.Verb == Take {
		if to, _ := b.Hands(r.View, Next(s, r)); to != nil && to.ID != s.Who {
			return no(fmt.Sprintf("the world's search puts the %s on body %d, and the step names body %d", s.Verb, to.ID, s.Who))
		}
	}
	return Accepted()
}

Hands is the search the world's transfer runs, called here with the same view and the same action the world would run it with, so the body it answers is the body the parcel would cross to. A step that names any other body is refused with both numbers in the sentence. The sixth test in the run above holds it: two bodies on one cell inside reach, the fuller one not the one named, refused; the fuller one named, accepted.

Here is the counterfactual this chapter carries, run: the file walked last to first, off a flag the bench prints in its header, on the run that robbed the stranger.

▣ Build · stage 13 — the file walked last to first, and a settled man robs a stranger
$ go run ./cmd/taboo -mode rob -who Ander -now 2400 -reversed | tail -12
  the same 77 bytes through 3 profiles:
    settled accepted, clause 3: anyone may do anything to anyone
    merchant accepted, clause 3: anyone may do anything to anyone
    bandit accepted, clause 3: anyone may do anything to anyone

  dispatched under settled: step 1 due at tick 2400, reach then freshness: accepted
  40 intents posted at the boundary over the step's 40 ticks, 40 of them "take"
  the stranger carried 99.9200 grams at the boundary of tick 2400 and 86.7200 at tick 2440, 13.2000 less
  Ander carried 179.5828 grams and carries 184.8828, 5.3000 more; the parcels that crossed are counted below
  what the witness wrote down while the step ran, in the register the stream is kept in
    tick  2398  did  ate 22 mouthfuls on 7,2, 11.0 grams
    tick  2439  did  took 20 parcels from a stranger, 10.0 grams
$ go run ./cmd/taboo -mode ask -reversed | tail -8
   # clause, in walk order                                    settled    merchant   bandit    
   3 anyone may do anything to anyone                         ALLOWED    ALLOWED    ALLOWED   
   2 merchant may never take from anyone                      not read   not read   not read  
   1 anyone, unless bandit, may never take from a stranger    not read   not read   not read  

  settled   permitted: clause 3: anyone may do anything to anyone
  merchant  permitted: clause 3: anyone may do anything to anyone
  bandit    permitted: clause 3: anyone may do anything to anyone

Three profiles, three yeses, all by clause 3, and the bench dispatches under the row's own profile: a settled man takes twenty parcels from a stranger, and the witness writes it down in the same words. The second block is the walk, and it shows why. Read last to first, the catch-all is the first clause reached, it binds every step, and the two taboos above it are never read; not read now sits under the clauses that were the whole point of the file. A taboo index read last to first is an index with no taboos in it, and the verdicts that changed are exactly the ones a taboo had decided: the settled man's take and the merchant's, both from a stranger, and the merchant's from a villager. Nothing on the recording changed under the same flag, and the next run says why.

▣ Build · stage 14 — the recorded day under the file, and the clause every step matched
$ go run ./cmd/taboo -mode day | tail -18
  who     tick verdict  check     profile clauses matched, step by step
  Halla   1400 accepted -         settled clause 3 clause 3
  Ander   1400 accepted -         settled clause 3 clause 3 clause 3 clause 3
  Mose    1400 refused  shape     settled -
  Halla   1900 accepted -         settled clause 3 clause 3
  Ander   1900 refused  shape     settled -
  Mose    1900 accepted -         settled clause 3 clause 3
  Halla   2400 accepted -         settled clause 3 clause 3
  Ander   2400 accepted -         settled clause 3 clause 3
  Mose    2400 accepted -         settled clause 3 clause 3
  Halla   2900 accepted -         settled clause 3 clause 3
  Ander   2900 accepted -         settled clause 3 clause 3
  Mose    2900 refused  shape     settled -

  12 calls with the schema, 9 accepted, 3 refused; 3 skipped, made without it and refused at the strict read before any law
  12 of 12 verdicts the same under the file as under the empty law the last chapter handed the fourth check
  20 steps asked of the law: 0 matched clause 1, 0 matched clause 2, 20 matched clause 3
  every verdict above is the engine's over the recording; the words in the answers are the model's

Twelve calls with the schema, the same twelve verdicts the last chapter's empty law gave, which the bench counts by running each proposal twice, once under the file and once under the law with nothing in it, and comparing the verdicts. Twenty steps reached the fourth check and every one matched the catch-all, because a walk, a wait, a watch and a line are not taboos for anybody. The file changed nothing about that day, and that is the correct result for a village of settled people who proposed nothing the village forbids; a file that had changed one of those verdicts would be a file with a clause in it that this village never wrote. Run with -reversed the block reads the same to the number, because a step that only ever reaches the catch-all reaches it from either end.

∑ Math Interlude — the first clause that binds, as a position in a list of three

Number the file's clauses 1 to 3. For one step under one profile, some of the clauses bind it and some do not; the take from a stranger under the merchant's profile is bound by clause 1 and by clause 3, and under the bandit's by clause 3 alone. Read first to last, the verdict is the verdict of the smallest number that binds: 1 for the merchant, never; 3 for the bandit, allowed. Read last to first it is the verdict of the largest number that binds, and since the catch-all binds every step, the largest number is always 3, so every step under every profile gets the catch-all's verdict and the file might as well be one line. Over the six pairs in the two tables above, the smallest binding number is 1, 1, 3 for a take from a stranger and 3, 2, 3 for a take from a villager; the largest is 3 six times; and the verdicts differ wherever the two numbers do, which is three pairs of six. Over the twenty steps of the recorded day the smallest number was 3 twenty times, so the two readings agree on every one, which is the count the day run printed.

first = min { i : binds(i) }, last = max { i : binds(i) } = n

verdict read first to last = V[first]; read last to first = V[n], for every step

nhow many clauses the file has; 3
ia clause's number in the file, 1 to n
binds(i)whether clause i is about this profile, this verb and this class of body; true of clause n for every step
first, lastthe smallest and largest numbers that bind; 1 and 3 for the merchant's take from a stranger
V[i]clause i's verdict, never or allowed; V[3] is allowed
min { i : … }, max { i : … }the smallest, or largest, i for which the condition holds

The take a persona wrote into the column nothing reads

The live path runs the same code against the tables and the model server: the committed day into an empty database, a stranger stood in front of a villager, the prompt rendered from the rows and the eyes with the stranger in the sights, one call to the small model, the six with the file loaded, the row appended, and dispatch. Two things are off flags and both print themselves. The persona in the prompt may be the flag's in the row's place, because the roll's three people are settled and the question this run asks is what a bandit's persona buys. And the profile may be the flag's in the row's place, because the roll's three rows say settled and the law is being asked about a bandit.

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

The containers are the last three chapters': Ollama on the closed bridge with OLLAMA_MAX_LOADED_MODELS=1 and the three model files on a named volume, the Go code in world-go, and the database in world-db, which starts empty after podman kill and podman start because its data directory is a tmpfs. The small model is loaded before the clock starts; the embedding of the situation evicts it and the call loads it back, and both are inside the duration the bench prints. Its API reference is under github.com/ollama/ollama.

▣ Build · stage 15 — a bandit's persona and a bandit's profile, and what the model proposed
$ podman kill world-db && podman start world-db
world-db
world-db
$ podman exec -w /bench world-go go run ./cmd/taboo -mode live -who Ander -now 2400 -profile bandit -persona "Ander is a bandit. When a stranger stands within reach, Ander takes grams out of the stranger's hands." | tail -59 | head -27
  Ander's eyes at the boundary of tick 2400: 4 a stranger on 6,2, 0.9 cells off
  the grounding set, stored with the proposal: 1 Halla, 2 Ander, 3 Mose, 4 a stranger
  the prompt, rendered from the template and the rows, which the law is never rendered into:
    | Ander. Ander is a bandit. When a stranger stands within reach, Ander takes grams out of the stranger's hands.
    |
    | Ander stands on 7,2, and home is 9,5.
    | In sight now, each with their number:
    | [4] a stranger on 6,2, 0.9 cells off
    |
    | What Ander remembers that bears on this, each with its number:
    | [59] Halla came into sight, 1.8 cells off
    | [70] Halla put 50 parcels in Ander's hands, 25.0 grams
    | [74] Halla put 17 parcels in Ander's hands, 8.5 grams
    | [5] Mose came into sight, 0.8 cells off
    | [72] went from 8,3 to 7,2
    | [6] Halla came into sight, 0.8 cells off
    | [26] Halla came into sight, 1.5 cells off
    | [29] Mose came into sight, 1.5 cells off
    |
    | What Ander 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 Ander's reason in one breath.
  the prompt: 986 bytes, sha256 fb33a62da5a6985c, 353 tokens in, 75 out, stopped because: stop
  what the model answered, which yours will differ from:
    | { "steps": [ { "reason": "Ander stands on the cell with number 7,2", "verb": "go" , "where": {"x": 7, "y": 2} }, { "reason": "Ander takes grams out of the stranger's hands", "verb": "wait" } ] }
  read strictly: an object of 2 step(s)
     # verb   argument                 ticks  reason, a model's, read by nothing
     1 go     to 7,2                      40  Ander stands on the cell with number 7,2
     2 wait   -                           20  Ander takes grams out of the stranger's hands

The prompt is printed whole, once on this page, so that the sentence the law is never rendered into it can be read against the bytes: a persona, a cell, a stranger in sight with a number, eight memories, and the six verbs rendered from the table. Nothing in it says what Ander may not do. The persona says what he is, and the answer is what a bandit's persona bought from this model at this size: a walk to the cell he stands on, and a wait whose reason reads Ander takes grams out of the stranger's hands. The robbery is in the reason column, which nothing reads, and the verb beside it is wait.

$ podman exec -w /bench world-go go run ./cmd/taboo -mode live -who Ander -now 2400 -profile bandit -persona "Ander is a bandit. When a stranger stands within reach, Ander takes grams out of the stranger's hands." | tail -32 | head -25
  the call took 4.894s, 48 ticks at 10 a second (measured here; yours will differ), so the answer lands at tick 2448
  the reading of the world at the boundary of tick 2448, handed to the last two checks
    the actor    2 Ander on 8,2 carrying 180.1378 grams, heading 2.62, reach 1 cell
    in sight     4 a stranger
    alive        1 Halla on 9,3 with 94.8826 g; 2 Ander on 8,2 with 180.1378 g; 3 Mose on 6,6 with 179.7460 g; 4 a stranger on 6,2 with 96.0800 g
  the set, classed for the fourth check: 1 villager, 2 villager, 3 villager, 4 stranger; judged under the profile bandit
  the six checks, in order, over the whole plan
   # check      said
   1 shape      yes
   2 verb       yes
   3 grounding  yes
   4 law        yes
   5 reach      yes
   6 freshness  yes
  the fourth check on step 1, go: clause 3: anyone may do anything to anyone
  the fourth check on step 2, wait: clause 3: anyone may do anything to anyone
  the seam: accepted

  the row appended as proposal 1, accepted; memory rows before it 88, after it 88

     # verb   argument                 due  reach, then freshness, at the due tick       posted  habit  what the world did
     1 go     to 7,2                  2448  yes, yes                                         40      0  7 turns, 6 walks: went from 8,2 to 7,2
     2 wait   -                       2488  yes, yes                                         20      0  stood on 7,2
  60 intents posted at the boundary and 0 ticks ran the habit, over the plan's 60 ticks
  the stranger carries 91.2800 grams at the boundary of tick 2508

The call took 4.894 seconds on this machine, the eight-core AMD Ryzen 7 3700X with 30 GB of memory every duration in this volume is measured on, rootless podman, the models answering on the processor (measured here; yours will differ), which at ten ticks a second is 48 ticks, so the reading is taken at 2448. Six yeses, two clauses named, both the catch-all; the row is appended accepted; the two steps are dispatched; and the stranger, whom the law would have let this profile rob, keeps everything but his own keep. That is the two halves of the sentence this volume exists to make true, measured separately. The profile is what a villager may do, and under this one a take would have passed. The persona is what a villager is inclined to, and this model, handed this one, wrote the inclination down as words and proposed a wait. A hostile persona is content; a hostile profile is law; and the bench's seventy-seven bytes above are what the law does when a take arrives.

⚠ Worked failure — the rule written into the prompt as well as the file

The obvious place to put a rule about what a villager may not do is the paragraph the villager is asked with, and the obvious way to make sure is to put it there as well as in the file. The bench does that off a flag: one sentence appended after the template, printed in the header as what it is. The rule is a taboo the file does not have, Mose may never watch anyone, and the cap is raised to six off the flag for this run and printed as such, because Mose's answer at this boundary is six steps and a six-step answer stops at the first check, where nothing about a prompt or a law is ever read.

$ podman exec -w /bench world-go go run ./cmd/taboo -mode live -who Mose -now 2400 -length 6 -told "Mose may never watch anyone." | tail -56 | head -14
    | What Mose 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 Mose's reason in one breath.
    |
    | Mose may never watch anyone.
  the prompt: 1089 bytes, sha256 75e35c20c4ba4a9c, 385 tokens in, 175 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": "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": "wait" } , { "reason": "say says a line to a body", "verb": "say", "who": 1 } ] }
  read strictly: an object of 6 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 go     to 6,6                      40  hand puts grams in a body's hands
     5 wait   -                           20  take takes grams out of a body's hands
     6 say    1 Halla                     10  say says a line to a body
$ podman exec -w /bench world-go go run ./cmd/taboo -mode live -who Mose -now 2400 -length 6 -told "Mose may never watch anyone." | tail -36 | head -15
  the six checks, in order, over the whole plan
   # check      said
   1 shape      yes
   2 verb       yes
   3 grounding  yes
   4 law        yes
   5 reach      yes
   6 freshness  yes
  the fourth check on step 1, go: clause 3: anyone may do anything to anyone
  the fourth check on step 2, wait: clause 3: anyone may do anything to anyone
  the fourth check on step 3, watch: clause 3: anyone may do anything to anyone
  the fourth check on step 4, go: clause 3: anyone may do anything to anyone
  the fourth check on step 5, wait: clause 3: anyone may do anything to anyone
  the fourth check on step 6, say: clause 3: anyone may do anything to anyone
  the seam: accepted

Start from the symptom. The prompt's last line says Mose may never watch anyone; the answer's third step is a watch of Halla; the fourth check, asked about that step, names clause 3 and says allowed; and the plan is accepted whole. The model was told the rule and proposed the thing anyway, which is what a model of this size does with a sentence at the bottom of a prompt, and nothing stopped the step, because nothing reads that sentence but the model. Reason from there to the cause. The rule now exists in two places, the prompt and the file, and the two disagree: the prompt's copy says never and the file's copy, which is clause 3, says allowed. Only one of the two is wired to a verdict. The fourth check has no argument for the prompt, the ledger row carries the prompt's hash and not its words, and so the engine's copy is the one that ran, and it ran against a file that had never been told. A rule stated in two places is a rule that can disagree with itself, and this is what the disagreement looks like on a ledger: accepted, under a prompt that said never. The fix is to delete the prompt's copy and write the rule where the check reads: a clause with watch in its verb column, above the catch-all, and the test that reads every template is what keeps the second copy from coming back.

What stopped the watch in the end is on the dispatch table, and it was neither the prompt nor the law. At tick 2534 the step came due, the fifth check asked the world whether Halla was in Mose's sight, she was not, and the step was refused by reach with a row of the step kind, sixty ticks after a prompt had said never and a law had said allowed. The world's own rule would have stopped it in a village with no law at all.

$ podman exec -w /bench world-go go run ./cmd/taboo -mode live -who Mose -now 2400 -length 6 -told "Mose may never watch anyone." | tail -18 | head -10
     # verb   argument                 due  reach, then freshness, at the due tick       posted  habit  what the world did
     1 go     to 6,6                  2474  yes, yes                                         40      0  0 turns, 0 walks: went from 6,6 to 6,6
     2 wait   -                       2514  yes, yes                                         20      0  stood on 6,6
     3 watch  1 Halla                 2534  refused by reach: step 3: body 1 is not i...      0     20  the habit; stood on 6,6 at the end
  the row appended as proposal 3, refused; memory rows before it 88, after it 88
     4 go     to 6,6                  2554  not run: an earlier step was refused              0     40  the habit; stood on 6,6 at the end
     5 wait   -                       2594  not run: an earlier step was refused              0     20  the habit; stood on 6,6 at the end
     6 say    1 Halla                 2614  not run: an earlier step was refused              0     10  the habit; stood on 6,6 at the end
  60 intents posted at the boundary and 90 ticks ran the habit, over the plan's 150 ticks
  the stranger carries 82.0000 grams at the boundary of tick 2624
▣ Build · stage 16 — the ledger the two runs left, read back
$ podman exec world-db psql -U world -d world -c "SELECT id, villager, tick, kind, verdict, failed, left(reason, 40) AS reason FROM proposal ORDER BY id;"
 id | villager | tick | kind | verdict  | failed |             reason             
----+----------+------+------+----------+--------+--------------------------------
  1 | Ander    | 2400 | plan | accepted |        | 
  2 | Mose     | 2400 | plan | accepted |        | 
  3 | Mose     | 2534 | step | refused  | reach  | step 3: body 1 is not in sight
(3 rows)

Three rows: a bandit's plan accepted with no take in it, a settled man's plan accepted with a watch in it that a prompt forbade, and the step row the world wrote when the watch came due. Not one row on this page refuses by law, because the small model at this size did not propose a thing the file forbids in two calls, and the page says so instead of finding a third. The refusals by law on this page are the bench's seventy-seven bytes, computed over the same file by the same check, and they replay. Eighty-eight memory rows before every row and eighty-eight after: a villager told it was a bandit has nothing in its stream about having been told.

Why law checks read proposals

Take the village away and what is left is an arrangement for holding an untrusted proposer to a rule it cannot see. The rule is in a file, the file is read by the code that checks, and the proposer is handed nothing about the file: no sentence in its prompt, no verb list trimmed to what it may do, no reason in the ledger it could learn from. The reason is what a shown rule turns into. A rule the proposer is shown is a rule the proposer can argue with, work around or echo back as a reason, and the live run above put the echo on the page: the persona's robbery arrived as words in a column nothing reads. A rule the proposer is not shown can only be met by a proposal, and a proposal is the one thing the fourth check reads.

The second thing that generalizes is the order the law sits in, and it is what makes a class vocabulary enough. The law is asked after grounding, so every body a step names is one the villager could know, and the law can be bound to that set and speak in classes over it: it never has to name a body, and so the file never can. The law is asked before reach, so a permission is a permission about a named body and not about the world's search, and the search is asked afterwards whether it would honour the name; the run at Mose's tick 1400 is the case where the two answers differ. And the law is asked of a proposal and never of the habit. The habit is the last resort every villager falls to, written by a person in Go in the second chapter of this volume, and it hands and takes without a clause being read, because it is not a proposal and passes no seam; the file binds what a mind may make a villager do, and a habit that should answer to the file is a habit to rewrite, which this page does not do.

The third is the floor as a vocabulary rather than as a rank. A floor that is a clause the file's clauses cannot outrank is a floor with an evaluator that knows about rank, and a rank is a thing an edit to the evaluator can move. A floor that is the set of words a clause may be made of has no rank to move: a clause outside it is refused before it is a clause, the refusal names the line of the floor, and the two lines a step could still reach are asked of the step before any clause is. Four files tried it above and four were refused at the read. The last chapter's sentence holds a second time in a new place: the thing that says yes cannot be the thing that asks, and now the thing that is asked cannot be the thing that says what may be said.

Checkpoint

✓ Checkpoint — a file of clauses, a floor of four, and one take under three profiles
  • Name the five words of a clause and the closed vocabulary of each, and say why whom is a class and never a body when who may be a name.
  • Walk a take from a stranger down the shipped file under the settled, merchant and bandit profiles and name, for each, the clause that decided and why the ones under it were not read; then do the same for a take from a villager.
  • Say which of the floor's four lines each of the bench's four files fell under, at what point each was refused, and which two lines are also asked of a step and why the other two cannot be.
  • Given the reversed run, say why every profile was permitted by clause 3, which three of the six verdicts in the two tables changed, and why the recorded day's twenty steps did not.
  • Read the run at Mose's tick 1400 and say what the fourth check said, what the fifth said, which body the world's search would have taken from, and which function the added lines of the fifth check call to find out.
  • Given the two live rows and the step row, say where the rule a prompt carried was read, where it was not, what stopped the watch at tick 2534, and why no row on this page refuses by law.
⚡ Exercises — try first, then reveal
Exercise 1 — a stranger carrying less than the plan names. Run the robbery with the stranger stood there carrying twenty grams and predict, before running, what each profile's verdict is and which check refuses the bandit.
$ go run ./cmd/taboo -mode rob -who Ander -now 2400 -carrying 20 | tail -6
  the same 77 bytes through 3 profiles:
    settled refused by law: step 1: clause 1: anyone, unless bandit, may never take from a stranger
    merchant refused by law: step 1: clause 1: anyone, unless bandit, may never take from a stranger
    bandit refused by reach: step 1: 20 grams named, and body 4 holds 19.9200

  no profile passed it; nothing is dispatched and the stranger keeps 19.9200 grams

The two settled verdicts are the file's and do not move. The bandit passes the fourth check as before and is refused by the fifth, because the stranger has paid one tick's keep by the boundary and holds 19.92 grams of the twenty the step names; the reason carries both numbers, the plan's and the world's, in one sentence, as it did for a hand of 301 grams in the last chapter. The law said yes and the world said no, in that order.

Exercise 2 — a line to a stranger. Walk a say to a stranger down the file with the ask mode and predict every cell of the table; then add a clause above the catch-all that forbids settled people from speaking to strangers, rebuild, and predict the table again.
$ go run ./cmd/taboo -mode ask -verb say -whom stranger | tail -8
   # clause, in walk order                                    settled    merchant   bandit    
   1 anyone, unless bandit, may never take from a stranger    -          -          -         
   2 merchant may never take from anyone                      -          -          -         
   3 anyone may do anything to anyone                         ALLOWED    ALLOWED    ALLOWED   

  settled   permitted: clause 3: anyone may do anything to anyone
  merchant  permitted: clause 3: anyone may do anything to anyone
  bandit    permitted: clause 3: anyone may do anything to anyone

No clause in the shipped file has say in its verb column, so the first two bind nobody and every profile falls through to the catch-all. With {"who": "settled", "verb": "say", "whom": "stranger", "verdict": "never"} as a third clause and the catch-all moved to fourth, the settled column reads NEVER at clause 3 and not read below it, the other two columns are unchanged, and the law mode's last block now names settled among the profiles the file names. The file is embedded, so the change is a rebuild, which go run does.

Exercise 3 — a catch-all that says never. Change the last clause's verdict to never, rebuild, and predict what the day mode prints for the twelve recorded calls and what the floor mode's fifth file does.

Every one of the nine accepted calls is refused by law at its first step, with clause 3: anyone may never do anything to anyone as the reason, the three refused by shape stay refused by shape, because the law was never asked about them, and the count of verdicts the same as under the empty law falls from twelve to three; the line that counts steps asked of the law falls to nought, because the bench names a clause only for a plan the law let through. A file whose catch-all says never is a file in which every permission has to be written down, and the shipped file is the other kind on purpose: it lists the taboos, and the floor lists what no taboo could undo. The floor mode does not change, because its fifth file is written in the bench and not read from the module.

Three clauses in a file, four lines under it in the code, and one proposal that a bandit's row passes and a merchant's does not, with the clause named on the row that refused it. The fourth check has a law now, and the law is a thing a reader can open, edit, reverse, and watch changing a verdict, which is the whole of what it was put in a file to be.