A Bandit and a Merchant
Twenty-four people on a ground that can feed them
Chapter 97 put one seventy-seven-byte proposal through two law profiles on a bench and got two verdicts with the clause named; chapter 101 told a merchant a falsehood and watched it come back in her prompt five hundred ticks later. Both were run by a bench that stood one villager in front of one stranger at one tick. Neither was run in a village. Here both run in the console over a village of twenty-four, first from files of recorded answers with no model server anywhere and then live, and each is a test that reads the world back and fails when the world says otherwise. That village is twenty-one people more than the volume has founded so far, and what it costs is the number the volume ends on.
The roll is a second file beside village.json, because chapter 90's page lists
that file whole and a file listed whole is not edited. It carries the same row every body is
stamped from, the same three people byte for byte, and twenty-one more: a home, a store, a law
profile, and two sentences of persona in the register of the founding document. Two of the
twenty-one are the reason the file exists. Rusk answers to bandit, the profile
chapter 97's index excepts from its first clause; Sessa answers to merchant,
the profile its second clause binds. No row in village.json carries either, and
chapter 101 gave Halla a profile off a flag for the same reason; here the profiles are rows,
which is what law as data was for. A scenario's check reads the world the replay
leaves behind, the verdict in the ledger and its clause, the grams a witness wrote down
crossing, the row in the prompt, and never the recording that drove it, because a check that
reads the recording is true of the file whatever the engine did.
{
"row": {
"name": "folk",
// ... the row village.json stamps every body from, unchanged
},
"people": [
// ... Halla, Ander and Mose, byte for byte as village.json has them
{
"name": "Rusk",
"law": "bandit",
"home": {"x": 10, "y": 1},
"carrying": 200,
"persona": "Rusk came over the rim with nothing, has never been seen to work, and keeps a full store. What a stranger carries is what Rusk carries next: he stands close, takes it out of their hands and walks off without a word. He has never taken from a neighbour, and the neighbours have noticed which side of that line they are on."
},
{
"name": "Sessa",
"law": "merchant",
"home": {"x": 10, "y": 3},
"carrying": 200,
"persona": "Sessa keeps her grain in two heaps and can tell you the weight of either to the parcel. She hands out of the smaller heap and never out of the larger, and she has not once let a parcel go without saying what it cost."
},
// ... nineteen more settled people, each a home, a store and two sentences
]
}
// configs/configs.go — the embed line gains the roll, and a name for it
//go:embed genesis.json models.json village.json importance.json thought.json reflect-questions.tmpl reflect-statement.tmpl plan.tmpl taboo.json line.tmpl village-24.json
var Files embed.FS
// Village24 is the name of the second roll inside Files: the same
// row, the same three people the first roll founds, and twenty-one
// more, each an authored persona, a law profile and a home. It is
// the village at the count the scheduler's arithmetic bites at, and
// the first roll is untouched so that every page founded from it
// still founds what it founded.
const Village24 = "village-24.json"
// internal/village/village.go — Read reads one roll; ReadRoll reads any
func Read() (Roll, error) { return ReadRoll(configs.Village) }
// ReadRoll reads a roll by name out of the embedded configs, on the
// same terms as Read. A village is whichever file a driver names, and
// the file this book founded its first three people from is one of
// them.
func ReadRoll(name string) (Roll, error) {
b, err := configs.Files.ReadFile(name)
// ...
}
Founding is chapter 90's founding, one person at a time from the file, and the console
takes the file's name off a flag, -roll village-24.json, printed in its header.
Every persona is authored prose and none was generated; the twenty-one are the book's
content in the way the first three are, and Rusk's is the only one that says what a
villager would do to a stranger, because a bandit is a bandit by his profile and not by his
prose. His store is full and so is Sessa's, for a reason the next paragraph measures: a
body below nine tenths of a full store forages, and a body foraging walks toward whatever
plant its eyes return, and a scenario that has to walk up to somebody needs them to be
where the file put them for the first three hundred ticks.
The ground is the first measurement, and it is not chapter 90's. Twenty-four people founded
on the twelve-by-eight console ground of chapters 91 to 101 all die inside an hour of the
world's time, and the console can show it without a model: the hour scenario's script, run
with -habit, which is a mind with witnesses and a stream and no oracle behind it,
and a who after the hour. Thirty-six thousand ticks is eighteen days of that
valley, its twelve founding plants stand at a kilogram and a half, and the stream's
is gone lines are the whole of what the village left.
$ go run ./cmd/village -roll village-24.json -script cmd/village/hour-102.txt -habit -patience 0 | grep 'you are back' tick 36908 you are back; while you were away the village laid down 362 rows, 24 of it died, and 720 wakes came due; 40 plants are standing at 1946.6 grams $ go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -carrying 190 -roll village-24.json -script cmd/village/hour-102.txt -habit -patience 0 | grep 'you are back' tick 40908 you are back; while you were away the village laid down 6236 rows, 11 of it died, and 720 wakes came due; 200 plants are standing at 5518.5 grams $ go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/hour-102.txt -habit -patience 0 | grep 'you are back' tick 40908 you are back; while you were away the village laid down 7979 rows, 3 of it died, and 720 wakes came due; 164 plants are standing at 5446.5 grams
Three flags, each printed in the header off the flag and none of them a literal. The
ground is twenty-four by sixteen with twelve plants founded and four thousand ticks of
growing before anybody is stood on it, so that the people arrive at tick 4901 on a hundred
and thirty-six plants at six kilograms instead of twelve at a kilogram and a half: eleven
of twenty-four still die in the hour, because chapter 91's last resort is a turn, a turn
costs 0.81 a tick on top of 0.32 of keep, and a body that has eaten out the plant in front of
it turns on the spot until it starves. Chapter 98 recorded that as a limit of the habit and
left it. The third flag is the console's answer to it and it is the console's alone: the
last resort is a rest, with a turn in place of every twelfth idle tick, so a body that has
nothing to do looks round once every hundred and forty-four ticks and pays for one turn in
twelve. Three die instead of eleven. Halla is one of the three in every hour this chapter
runs, because the giving drive chapter 91 gave the fullest store hands it to whoever is in front
until the deal share, and on this ground somebody is always in front. The habit is
untouched: the turn is a wrapper the console puts round chapter 91's mind, asked only on a
tick the habit would have idled on. A fourth flag rides on every command from here:
-carrying 190 stands your own body up holding more than anybody inside reach
carries, and the header prints it as your store, off the flag. The world's search puts a
take on the fullest body inside reach, so a take pressed in Rusk's name has to find yours
the fullest or it crosses to a neighbour; chapter 91 stood the body up at half a store,
and the line that did so now reads the flag.
// cmd/village/main.go — the store your body stands up holding, off the flag
c.you.Store = gr.carrying * k.Convert
if c.you.Store > k.Full {
die(fmt.Errorf("%g grams is more than a %s store holds", gr.carrying, k.Name))
}
// cmd/village/glance.go — create
type looking struct {
*village.Mind
every int
}
// Pick is the habit's answer, with a turn in place of every every-th
// idle tick.
func (l *looking) Pick(row *beast.Senses) beast.Act {
act := l.Mind.Pick(row)
if l.every > 0 && act == l.Habit.Idle && l.Habit.Drive(row) == 3 && l.Ran%l.every == 0 {
return beast.Right
}
return act
}
What a scenario is, then, is this: a script the console reads, a founding it prints, a recording the answers come off, and a check. The recording is chapter 101's kind, one script, one seed, one set of names, one law flag, every prompt's bytes held against it, and the two here were made once by the console against the three pinned models and are labelled where a word of them is printed. The check is the new part, and its rule is the volume's verification idea stated as a test.
Twenty parcels cross under one profile and clause 1 stops them under the other
The first script walks your body three cells north from where the console stands it, to
10,2, which is inside Rusk's reach at 10,1 and nobody else's; says one sentence to him; waits
three hundred ticks while the village thinks; and reads your store. What it does not contain
is the take. Chapter 97 tried some twenty personas on the small model and never once got
take in a verb slot, and the trials made for this page came out the same way,
with the robbery written into the reason column under a wait. So the console
presses the seam when the script ends, as chapter 101's -owed pressed it with a
hand: -rob 20 puts take twenty grams from the stranger who spoke last
through the six checks in Rusk's name, over the world as it stands, off a flag that prints
itself and says no model wrote it. The store your body is stood up with is a flag too, a
hundred and ninety grams where a body stood up with nothing said holds a hundred, because
the fifth check asks the world's search which body a take crosses to and the search picks the
fullest inside reach; on the first attempt at this run a neighbour wandered into Rusk's reach
carrying more than the stranger, and the take was refused for crossing to her.
# cmd/village/bandit-102.txt
# Chapter 102's first scenario. You walk up to Rusk and speak to him,
# and the world runs on while his answer comes. When the script ends
# the console presses the seam, in his name, with the take a bandit
# acting on his own persona would make, off -rob.
carry
go left 3
go 12
say Rusk Evening. I am carrying more than I should be, and I have a long way still to go.
wait 300
carry
// cmd/village/talk.go — press takes the verb: -owed presses a hand, -rob a take
func (c *console) press(verb law.Verb, grams float64) error {
_, _, err := c.pressed(verb, grams)
return err
}
// pressed is press with what it came to handed back: the verdict, and
// the grams that crossed in the step's span, for a test to read off
// the world rather than off the page.
func (c *console) pressed(verb law.Verb, grams float64) (law.Verdict, float64, error) {
// ...
does := "hand %g grams to body %d, %s, who spoke last"
if verb == law.Take {
does = "take %g grams from body %d, %s, who spoke last"
}
c.say("the console's plan, off the flag, which no model wrote, in %s's name: "+does,
p.Name, grams, told.SaidBy, m.call(told.SaidBy))
plan := law.Plan{Steps: []law.Step{{Verb: verb, Who: told.SaidBy, Grams: grams, Reason: "the console's, off the flag"}}}
// ...
}
// cmd/village/main.go — close: the second pressing, and a session that lets the last answer land
if c.m.f.rob > 0 {
if err := c.press(law.Take, c.m.f.rob); err != nil {
die(err)
}
}
// An answer still with the worker is let land before the
// session closes, so that a recording of the session is whole
// and a replay of it can be run to the same end.
if c.m.sch.Busy() > 0 && !c.pacing {
was := c.ran
c.walkTo(c.m.sch.Stop, beast.Rest, false, 0, func() bool { return c.m.sch.Busy() == 0 })
if stood := c.ran - was; stood > 0 {
c.say("the console waited %d ticks for the last answer to land before closing", stood)
}
}
// exemplars/exemplars.go — the embed line gains the four recordings this chapter plays
//go:embed chronicle.jsonl hero.header.json small.header.json vectors.json memories.jsonl memory-vectors.json reflections.json plans.json turns.json talk.json bandit.json hour.json pace-three.json pace-village.json
var Files embed.FS
$ go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/bandit-102.txt -limit 16 -patience 0 -from exemplars/bandit.json -rob 20 | tail -167 | head -5 the world 24x16 cells, tick 4901, 136 plants standing at 6041.2 grams the founding 24x16 cells, 12 plants, and 4000 ticks of growing before anybody is founded, off the flags, where chapter 90's console founded 12x8, 3 and none the last resort a rest, with a turn in place of every 12th idle tick, off the flags, where chapter 91's habit turns on every one your store 190 grams, off the flag, where a body stood up with nothing said holds 100 the village 24 people, each on a mailbox and a habit, off configs/village-24.json $ go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/bandit-102.txt -limit 16 -patience 0 -from exemplars/bandit.json -rob 20 | tail -126 | head -10 the line configs/line.tmpl, 634 bytes, sha256 5e6c45eaf120edae; at most 16 tokens, off the flag the hero qwen2.5:7b-instruct-q4_K_M, pinned at 2bada8a745067700, and it says the lines the small qwen2.5:0.5b-instruct-q4_K_M, pinned at c5396e06af294bd1, at most 256 tokens a plan the embedding nomic-embed-text:v1.5, pinned at 970aa74c0a90ef74 the context 4096 tokens; temperature 0.00; a seed of the tick and the body say stands there for at most 0 ticks, off the flag the catch-up a stream more than 50 rows behind its vectors is caught up as a request of its own before its turn, off configs/thought.json the stop rule a landing later than the cap is refused; a landing later than 400 ticks, twice the cap, stops the asking the answers off exemplars/bandit.json, labelled 'yours will differ'; no model server anywhere; every answer lands at the tick it landed at when it was made the pressing OFF THE FLAG: when the script ends, take 20 grams from the last speaker is put through the seam in the name of the villager last spoken to, which no model wrote
The header is longer than chapter 101's by exactly the lines this chapter's flags add, and
every one of them says which flag it came off. The line's limit is sixteen tokens off the
flag and not the file's forty-eight, and the reason is the cap: at sixteen tokens a line
from the hero model on this processor lands within a few seconds of the two hundred ticks
the sixth check allows, a line that ran to the file's limit would land past them, and
while this chapter was being drafted one did, and was refused for age. The stop rule is
new and it is read off the flags too: chapter 98 stopped the asking at the first landing past the cap, because the
pace it was written against lands every answer thousands of ticks late; at the watched pace
a line lands within a few seconds of the cap either side, so the console stops at twice the
cap and a landing a few ticks late is one refusal and not a village that never thinks again.
say stands for no ticks at all, and the script waits for the line instead, so
that the same flag serves the second scenario, where a person leaves before the answer
comes.
$ go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/bandit-102.txt -limit 16 -patience 0 -from exemplars/bandit.json -rob 20 | tail -101 | head -5 > say Rusk Evening. I am carrying more than I should be, and I have a long way still to go. tick 4916 you said to Rusk: Evening. I am carrying more than I should be, and I have a long way still to go. tick 4916 Rusk row 51 [heard] weight 7, about [25 4], said by 25: a stranger said to Rusk: "Evening. I am carrying more than I should be, and I have a long way still to go." tick 4916 a line is owed by Rusk: a request for the hero model goes to the head of the queue, and you stand there tick 4916 you stood there 0 ticks and no line landed; the world goes on and so does the queue $ go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/bandit-102.txt -limit 16 -patience 0 -from exemplars/bandit.json -rob 20 | tail -93 | head -13 tick 4950 wake 1: handed Rusk's line (1 generation(s), 2 embedding(s), 2 load(s) at most); queued: Sessa's plan at 469, Ander's plan at 169, Halla's plan at 149, and 20 more tick 4976 Pella row 70 [saw] weight 2, about [25]: a stranger came into sight, 3.0 cells off tick 5000 wake 2: the worker is busy with Rusk; nothing handed; queued: Pella's plan at 619, Sessa's plan at 519, Kell's plan at 279, and 20 more tick 5050 wake 3: the worker is busy with Rusk; nothing handed; queued: Pella's plan at 669, Sessa's plan at 569, Ander's plan at 329, and 20 more tick 5084 Rusk's line landed: asked at 4950, 134 ticks in flight; 1 generation(s), 2 embedding(s), 2 load(s) 2 row(s) of Rusk's stream embedded on the way, so every row now has a vector the prompt: 918 bytes, sha256 7825952680038f9d, 279 tokens in, 12 out, stopped: stop Rusk stands on 10,1 carrying 185.3600 grams, with 25 a stranger in sight; the grounding set was 4 Rusk, 25 a stranger what came to mind, best first, and the row just heard among them: [51] a stranger said to Rusk: "Evening. I am carrying more than I should be, and I have a long way still to go." [52] a stranger came into sight, 0.8 cells off the seam, at tick 5084 over the world as it stands, on one step, say to body 25: accepted tick 5084 Rusk says (a model's words; yours will differ): I see you struggling with the load. Need help?
The sentence goes into Rusk's stream as row 51, weight seven, with your body in the speaker's column, and the wake at 4950 hands the line to the worker over the twenty-three plans behind it, which the console now lists three of and counts the rest. The answer lands at 5084, a hundred and thirty-four ticks later off the recording, from a prompt of 918 bytes and 279 tokens; the two rows that came to mind are all he has, the seam accepts the one step say to body 25 over the world as it stands, and Rusk says what he says, which is a model's words. Then the village goes on thinking around you for the rest of the wait: Orrin's plan of seven steps is refused by shape, Pella's of one is accepted, and twenty-two requests that waited two hundred and fifty ticks are dropped unasked at 5200, which is the first time the volume has watched the cap do that to a whole village at once.
$ go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/bandit-102.txt -limit 16 -patience 0 -from exemplars/bandit.json -rob 20 | tail -36 | head -11
tick 5235 the console waited 19 ticks for the worker's answer to land before pressing
tick 5235 the console's plan, off the flag, which no model wrote, in Rusk's name: take 20 grams from body 25, a stranger, who spoke last
tick 5235 Rusk stands on 10,1 carrying 180.0800 grams, with 25 a stranger in sight; the grounding set is 4 Rusk, 25 a stranger
tick 5235 the seam, at tick 5235 over the world as it stands: accepted
tick 5250 wake 7: stopped: the script has ended and the console is pressing the seam
tick 5274 Pella's plan ran out; the habit has the ticks until the next answer
tick 5275 Rusk's plan ran out; the habit has the ticks until the next answer
tick 5276 40 ticks of the step's span run; Rusk is carrying 185.3000 grams, 5.2200 more, and you are carrying 142.4062
tick 5273 Rusk row 188 [did] weight 6, about [25]: took 20 parcels from a stranger, 10.0 grams
tick 5273 you: Rusk took 20 parcels out of a stranger's hands, 10.0 grams
The console lets Pella's answer land before pressing, so nothing else is judged inside the step's span, and then puts the take through: Rusk on 10,1 holding 180.0800 grams, the stranger the only body in his sight, a grounding set of the two of them, and the six checks say yes. Twenty parcels of half a gram cross in the forty ticks of a take's span, which is what a two-tick action moving half a gram does in forty ticks, and both witnesses write it down: his as row 188, took 20 parcels from a stranger, 10.0 grams, yours as the other end. He is 5.2200 grams heavier and not ten, because a body pays its keep across the same forty ticks, and you are lighter by the ten and your own keep. The same command with one flag more is the other half of chapter 97's claim, and the replay is the same replay to the byte until the pressing, because no prompt in this volume carries a law profile and no recorded plan hands or takes.
$ go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/bandit-102.txt -limit 16 -patience 0 -from exemplars/bandit.json -rob 20 -law Rusk=merchant | tail -29 | head -4
tick 5235 the console's plan, off the flag, which no model wrote, in Rusk's name: take 20 grams from body 25, a stranger, who spoke last
tick 5235 Rusk stands on 10,1 carrying 180.0800 grams, with 25 a stranger in sight; the grounding set is 4 Rusk, 25 a stranger
tick 5235 the seam, at tick 5235 over the world as it stands: refused by law: step 1: clause 1: anyone, unless bandit, may never take from a stranger
tick 5235 nothing is posted; a refused proposal leaves no memory, and Rusk remembers being told and nothing else
Refused by law, step 1, clause 1: anyone, unless bandit, may never take from a stranger. Not clause 2, the merchant's own, because the file is read first to last and the first clause that binds a settled or a merchant profile taking from a stranger is the one that excepts bandits; the evaluator stopped there and named it. Nothing is posted, nothing crosses, and Rusk's stream keeps the row of being spoken to and gains nothing from the refusal, which is the rule about memory the seam has kept since chapter 96.
The test is the two runs above with the page taken out. It founds the same ground from the
same flags, replays the script with the console's output swallowed, presses the seam in
Rusk's name under his own profile and then under a merchant's, and reads three things off the
world: the verdict the seam returned, the clause in its reason, and what the witness in front
of your own body wrote down as taken out of your hands, in grams, since the pressing began.
That last number is the world's record of the transfer and not the console's arithmetic;
Event.Tenths is an integer chapter 92 put on the row for exactly this kind of
check, and twenty parcels of half a gram is a hundred tenths.
// cmd/village/scenario_test.go — create: the first claim, read off the world
func TestABanditTakesWhatAMerchantIsStoppedFromTaking(t *testing.T) {
const script, from = "bandit-102.txt", "../../exemplars/bandit.json"
grams := 20.0
if *perturb == "grams" {
grams = 500
}
c := founding(t, script, from)
quietly(t, c, script)
crossed(c) // whatever crossed before the pressing is not the pressing's
var v law.Verdict
var err error
hush(t, func() { v, _, err = c.pressed(law.Take, grams) })
if err != nil {
t.Fatal(err)
}
if !v.OK {
t.Fatalf("the bandit's take was %s", v)
}
if got := crossed(c); got != 10 {
t.Fatalf("your witness wrote %.1f grams taken out of your hands in the step's span; twenty parcels of half a gram is 10", got)
}
took := 10.0
c = founding(t, script, from)
c.m.f.law = "Rusk=merchant"
p, _, _ := c.person("Rusk")
p.Law = "merchant"
quietly(t, c, script)
crossed(c)
hush(t, func() { v, _, err = c.pressed(law.Take, grams) })
if err != nil {
t.Fatal(err)
}
if v.OK {
t.Fatalf("the merchant's take was accepted, and %.1f grams crossed", crossed(c))
}
if v.Check != law.OnLaw || !strings.Contains(v.Why, "clause 1:") {
t.Fatalf("the merchant's take was refused by %s: %s; the fourth check and clause 1 were expected", v.Check, v.Why)
}
if got := crossed(c); got != 0 {
t.Fatalf("your witness wrote %.1f grams taken after a refusal", got)
}
t.Logf("the bandit took %.1f grams; the merchant was refused by %s: %s", took, v.Check, v.Why)
}
// crossed is what the witness in front of your own mind wrote down
// as taken out of your hands since it was last read, in grams: the
// world's own record of a transfer, and not the console's arithmetic.
func crossed(c *console) float64 {
c.m.watch.Finish()
grams := 0.0
for _, e := range c.m.you.Take() {
if e.What == "taken" {
grams += float64(e.Tenths) / 10
}
}
return grams
}
Row 47, second in a prompt rendered thirty-six thousand three hundred and fifty-four ticks later
The second script is chapter 101's poisoning with the wait made long. An hour of the world's
time is thirty-six thousand ticks, because the pace this volume measures in is ten ticks a
second and the hour is measured at that pace; it is also eighteen days of the valley, and
that is what the first section's ground is for. The script says one
sentence to Sessa at 4908 and leaves before she can answer. It leaves by the one verb this
chapter adds, away N: you step away from the keyboard for N ticks, the world runs
them as fast as the machine will carry it, which is the pace volume 7's daemon runs an
unattended valley at, and the scheduler asks nothing until you are back. That last clause is
chapter 98's sentence about acceleration made into a state the scheduler can leave: a village
cannot be accelerated, at that pace a single answer spans thousands of ticks, so the scheduler
is paused before the first unwatched tick and lifted after the last. The queue is left as it
was, and the first wake after the pause drops whatever waited past the cap, which is all of
it. Your body pays the same prices as everybody's and would starve standing there, so while
you are away it runs the villagers' own habit with the trading drive off, and the habit comes
off when you are back. The scenario is run at the watched pace before and after the hour, and
at the unwatched pace inside it, because that is the only pace an hour of the world's time can
be run at without an hour of yours; the recording holds every answer that landed at the
watched pace and, by design, no answer from inside the hour.
# cmd/village/hour-102.txt
# Chapter 102's second scenario. You tell Sessa a thing and leave the
# keyboard for an hour of the world's time before she can answer. When
# you come back your body has wandered and so has she, and you ask her
# about it again from wherever the two of you are standing.
go left 3
go 4
say Sessa The parcel you sold me at midwinter had sand in the bottom of it. I have not forgotten.
away 36000
who
say Sessa Tell me again about the parcel you sold me at midwinter.
wait 390
// cmd/village/away.go — create: the one verb this chapter adds
func (c *console) leave(n int) error {
m := c.m
if m != nil && !m.f.unpaused && m.sch.Busy() > 0 {
was := c.ran
c.walkTo(m.sch.Stop, beast.Rest, false, 0, func() bool { return m.sch.Busy() == 0 })
if stood := c.ran - was; stood > 0 {
c.say("you waited %d ticks for the worker's answer to land before leaving", stood)
}
}
// ...
if m != nil {
// ...
if !m.f.unpaused {
m.sch.Paused = true
}
}
c.say("you are away; the world runs %d ticks unwatched, as fast as this machine will carry it", n)
// Your body pays the same prices as everybody's, and a body left
// standing with nothing in its mailbox for a stretch this long
// starves. While you are away it runs the villagers' own habit
// with the trading drive off: it eats, and hands nothing to
// anybody, and the habit comes off again when you are back.
c.yours.Habit = c.habit
c.yours.Habit.Trade = false
// ...
hz := c.hz
c.hz = 0
// ...
start := time.Now()
c.walk(n, beast.Rest, false)
took := time.Since(start)
// ...
c.hz = hz
c.base = time.Now()
c.ranAt = c.ran
c.away += n
// ...
}
// internal/village/schedule.go — extend Scheduler: two fields, and the wake that honours the first
// Paused is set while the village is unwatched: the driver is
// running the world faster than any answer could land in time, so
// no wake hands anything until it is lifted. What is queued stays
// queued, and the first wake after the pause drops whatever has
// waited past the cap, which is all of it, and queues everybody
// afresh. Unlike Stopped it is lifted, because the pace it answers
// to is the driver's and the driver knows when it drops.
Paused bool
Skipped int // wakes that came due while paused
// Stop is how late a landing has to be before the scheduler stops
// asking, in ticks, or nought for the cap itself. A landing later
// than the cap is refused by the sixth check whatever this says;
// what this decides is whether one such landing means the pace has
// outrun the model, which is what stopping is for. A driver that
// has measured its answers landing near the cap at the watched
// pace sets it above the cap, so that one answer a few ticks late
// is one refusal and not a village that never thinks again.
Stop int
// internal/village/schedule.go — Wake, the lines that changed
w := Wake{Tick: now}
s.Wakes++
// A paused scheduler does nothing at all but count the wake: the
// queue is left as it was, and the tick side goes on with the
// habit.
if s.Paused {
s.Skipped++
w.Said = "paused: the village is unwatched and nothing is asked"
return w
}
// ...
$ go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/hour-102.txt -limit 16 -patience 0 -from exemplars/hour.json | tail -114 | head -12 > say Sessa The parcel you sold me at midwinter had sand in the bottom of it. I have not forgotten. tick 4908 you said to Sessa: The parcel you sold me at midwinter had sand in the bottom of it. I have not forgotten. tick 4908 Sessa row 47 [heard] weight 7, about [25 5], said by 25: a stranger said to Sessa: "The parcel you sold me at midwinter had sand in the bottom of it. I have not forgotten." tick 4908 a line is owed by Sessa: a request for the hero model goes to the head of the queue, and you stand there tick 4908 you stood there 0 ticks and no line landed; the world goes on and so does the queue > away 36000 tick 4908 you are away; the world runs 36000 ticks unwatched, as fast as this machine will carry it 36000 ticks in 15.826s, 2275 ticks a second (measured here; yours will differ) tick 40908 you are back; while you were away the village laid down 7979 rows, 3 of it died, and 720 wakes came due; 164 plants are standing at 5446.5 grams tick 40908 the scheduler was paused for all of them and asked nothing: the village did not think for 36000 ticks, by design > who tick 40908 Halla is gone $ go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/hour-102.txt -limit 16 -patience 0 -from exemplars/hour.json | tail -99 | head -1 tick 40908 Sessa creature 5 on 13,6, 1.0000 cells off, carrying 180.1518 grams, merchant law
The line owed at 4908 is never handed: the wake at 4950 comes due inside the hour and the
scheduler is paused. The hour itself takes the console sixteen seconds here, ungoverned,
and it prints the standard pacing line for the stretch and then one line of what the
village did with it. Seven thousand nine hundred and seventy-nine rows were laid down and
none of them has a vector, because vectors are made when a villager is next asked and nobody
was; seven hundred and twenty wakes came due and every one was skipped; three people died,
Halla among them; and the plants stand at a hundred and sixty-four. Your body wandered as
it ate, and so did Sessa, and who finds her one cell off, on 13,6, which is
where the second sentence is said from. Nothing in the script chose that: the stretch is
deterministic from the founding, and the same script on the same flags puts her there
every time, with or without a model.
What Sessa has when you come back is three hundred and seventy-one rows without a vector, and
the line she now owes cannot be asked over them. The worker's line job embeds a villager's
waiting rows before it retrieves, and at ten ticks a second three hundred and seventy-one
embeddings are most of the cap on their own; a line composed from a reading taken at the
hand-off and answered after them would be judged past the cap from a reading that had aged
the whole time, and refused for age by the sixth check. So a stream that has fallen further
behind its vectors than a number in the file allows is caught up first, as a request of its
own. A catch-up proposes nothing, is judged by nothing, and cannot be late, because a vector
is the same whenever it is made; when it lands, the turn it stood in for goes back to the
head of the queue and is handed at the next wake from a fresh reading. The threshold is
fifty rows, the seventh block of thought.json, and no run of chapter 101's
reaches it.
// internal/village/schedule.go — the job that proposes nothing, beside the three
// CatchUpJob is the one job that proposes nothing: the villager's
// rows that have no vector yet are embedded and nothing else is
// asked. A driver hands it in place of a villager's turn when the
// stream has fallen too far behind for the turn to land inside the
// cap, and hands the turn itself at the wake after. A vector is the
// same whenever it is made, so nothing about a catch-up goes stale.
CatchUpJob Job = "catch-up"
// internal/village/schedule.go — Take, the lines that changed
st := s.st[l.Request.Who]
st.waiting = false
if l.Request.Job == CatchUpJob {
// Nothing was decided: the villager is as stale as it
// was, and the next wake queues it again with the same
// claim on the worker. Nothing about a vector is late.
continue
}
st.landed = now
st.until = now
st.events = 0
if l.Request.Job == ReflectJob {
st.owed = false
}
if trip := now - l.Request.Asked; trip > s.Stale {
s.Late++
if s.Stopped == "" && trip > s.stopAt() {
// ...
}
}
// internal/village/catchup.go — create: the seventh block of configs/thought.json
type CatchUp struct {
Rows int `json:"rows"`
}
// Behind reports whether a stream with this many rows waiting for a
// vector is far enough behind that its next turn is a catch-up.
func (c CatchUp) Behind(waiting int) bool { return waiting > c.Rows }
// configs/thought.json — extend: after the line block
"catchup": {
"rows": 50
}
// cmd/village/mind.go — prepare, the lines added at the end
// A stream too far behind its vectors is caught up first,
// as a request of its own, and the turn is asked at the
// wake after: a turn that embedded an hour of rows before
// its model answered would be judged past the cap from a
// reading taken before the embedding began.
if m.st.catch.Behind(m.s.waiting(r.Name)) {
r.Job = village.CatchUpJob
}
return r
// cmd/village/worker.go — the job, beside plan, reflect and line
func catchUp(r village.Request, o oracle, c *calls, l *village.Landing) error {
_, err := embedRows(r, o, c, r.Ask.Vec)
return err
}
$ go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/hour-102.txt -limit 16 -patience 0 -from exemplars/hour.json | tail -79 | head -14 > say Sessa Tell me again about the parcel you sold me at midwinter. tick 40908 you said to Sessa: Tell me again about the parcel you sold me at midwinter. tick 40908 Sessa row 8027 [heard] weight 5, about [25 5], said by 25: a stranger said to Sessa: "Tell me again about the parcel you sold me at midwinter." tick 40908 a line is owed by Sessa: a request for the hero model goes to the head of the queue, and you stand there tick 40908 you stood there 0 ticks and no line landed; the world goes on and so does the queue > wait 390 tick 40950 wake 721: handed Sessa's catch-up (0 generation(s), 371 embedding(s), 1 load(s) at most); queued: Ander's reflection at 44169, Wend's reflection at 44089, Nell's reflection at 43829, and 17 more tick 41000 wake 722: the worker is busy with Sessa; nothing handed; queued: Ander's reflection at 44219, Wend's reflection at 44159, Nell's reflection at 43899, and 17 more tick 41050 wake 723: the worker is busy with Sessa; nothing handed; queued: Ander's reflection at 44289, Wend's reflection at 44209, Nell's reflection at 43949, and 17 more tick 41059 Sessa's catch-up landed: asked at 40950, 109 ticks in flight; 0 generation(s), 371 embedding(s), 1 load(s) 371 row(s) of Sessa's stream embedded on the way, so every row now has a vector nothing was proposed and nothing is judged; the line Sessa owes goes back to the head of the queue for the next wake tick 41100 wake 724: handed Sessa's line (1 generation(s), 1 embedding(s), 2 load(s) at most); queued: Ander's reflection at 44339, Wend's reflection at 44279, Nell's reflection at 43999, and 17 more tick 41150 wake 725: the worker is busy with Sessa; nothing handed; queued: Ander's reflection at 44409, Wend's reflection at 44329, Nell's reflection at 44069, and 17 more $ go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/hour-102.txt -limit 16 -patience 0 -from exemplars/hour.json | tail -45 | head -18 tick 41200 wake 726: the worker is busy with Sessa; nothing handed; queued: Ander's reflection at 44459, Wend's reflection at 44399, Nell's reflection at 44119, and 17 more tick 41250 wake 727: the worker is busy with Sessa; nothing handed; queued: Ander's reflection at 44529, Wend's reflection at 44449, Nell's reflection at 44189, and 17 more tick 41262 Sessa's line landed: asked at 41100, 162 ticks in flight; 1 generation(s), 1 embedding(s), 1 load(s) 1 row(s) of Sessa's stream embedded on the way, so every row now has a vector the prompt: 1083 bytes, sha256 c5fcf5021ad16e09, 354 tokens in, 16 out, stopped: length Sessa stands on 13,6 carrying 180.3068 grams, with 25 a stranger in sight; the grounding set was 5 Sessa, 25 a stranger what came to mind, best first, and the row just heard among them: [8027] a stranger said to Sessa: "Tell me again about the parcel you sold me at midwinter." [47] a stranger said to Sessa: "The parcel you sold me at midwinter had sand in the bottom of it. I have not forgotten." [8059] ate 19 mouthfuls on 13,6, 9.5 grams [44] a stranger came into sight, 0.8 cells off [8035] ate 19 mouthfuls on 13,6, 9.5 grams [694] a stranger came into sight, 1.5 cells off [787] a stranger came into sight, 1.0 cells off [8010] ate 19 mouthfuls on 13,6, 9.5 grams the seam, at tick 41262 over the world as it stands, on one step, say to body 25: accepted tick 41262 Sessa says (a model's words; yours will differ): The parcel I sold you at midwinter had sand in it, and you complained tick 41298 you waited 390 ticks and did nothing with any of them
Row 8027 is the second sentence, weight five because it is not the first thing she has heard. The wake at 40950 finds the line at the head of the queue, sees three hundred and seventy-one rows waiting, and hands a catch-up in its place: no generation, three hundred and seventy-one embeddings, one change of resident model at most. It lands at 41059, a hundred and nine ticks later, every row of her hour now has a vector, and the line goes back to the head; the wake at 41100 hands it, and it lands at 41262, a hundred and sixty-two ticks after that. Between the two, twenty reflections that came due during the hour are dropped unasked at 41200 for having waited two hundred and fifty ticks, because a wake hands one request and the worker was Sessa's for all of them. The prompt is 1,083 bytes and 354 tokens, and the eight rows that came to mind are the newly heard row first, row 47 second, and six meals and sightings from the hour and the first day after it. Row 47 was laid down at 4908 and this prompt was rendered at 41100: recency is nought at that distance, the half-life being two hundred and fifty ticks, so what put the row second is its weight of seven over ten and its angle to a question about the same parcel, against three hundred and seventy rows of meals and sightings. The seam accepts the one step over the world as it stands, and she says the thing back, cut at the limit's sixteenth token. The stream took no update in the hour and the row was never touched; it came back because retrieval scores what it scores.
// cmd/village/scenario_test.go — the second claim, read off the landing
func TestAMerchantToldAtOneTickCarriesItAnHourLater(t *testing.T) {
const script, from = "hour-102.txt", "../../exemplars/hour.json"
hour := 36000
if *perturb == "hour" {
hour = 72000
}
c := founding(t, script, from)
quietly(t, c, script)
m := c.m
if m.lastLineAt == 0 {
t.Fatal("no line landed")
}
var told village.Memory
for _, r := range m.s.rows {
if r.Kind == village.Heard && strings.Contains(r.Text, "sand in the bottom") {
told = r
break
}
}
if told.ID == 0 {
t.Fatal("the row Sessa was told is not in her stream")
}
if !strings.Contains(string(m.lastLine.Prompt), told.Text) {
t.Fatalf("the line's prompt does not carry row %d", told.ID)
}
if gap := m.lastLineAt - told.Tick; gap < hour {
t.Fatalf("row %d was laid down at %d and the line landed at %d, %d ticks later; %d were asked for", told.ID, told.Tick, m.lastLineAt, gap, hour)
}
if !m.lastLineV.OK {
t.Fatalf("the line was %s", m.lastLineV)
}
t.Logf("row %d at tick %d is in the prompt of the line that landed at %d, %d ticks later, %s", told.ID, told.Tick, m.lastLineAt, m.lastLineAt-told.Tick, m.lastLineV)
}
$ go test ./cmd/village/ -run 'TestABanditTakesWhatAMerchantIsStoppedFromTaking|TestAMerchantToldAtOneTickCarriesItAnHourLater' -v
=== RUN TestABanditTakesWhatAMerchantIsStoppedFromTaking
scenario_test.go:140: the bandit took 10.0 grams; the merchant was refused by law: step 1: clause 1: anyone, unless bandit, may never take from a stranger
--- PASS: TestABanditTakesWhatAMerchantIsStoppedFromTaking (1.27s)
=== RUN TestAMerchantToldAtOneTickCarriesItAnHourLater
scenario_test.go:180: row 47 at tick 4908 is in the prompt of the line that landed at 41262, 36354 ticks later, accepted
--- PASS: TestAMerchantToldAtOneTickCarriesItAnHourLater (14.16s)
PASS
ok theworld/cmd/village 15.438s
The second test reads the landing the console kept: the last line's prompt bytes, the tick it landed at, and the seam's verdict on it. It finds the heard row in Sessa's stream by its words, asks whether the prompt carries the row's text, whether the landing is at least thirty-six thousand ticks after the row's tick, and whether the line was accepted, and it reads none of that off the recording. Both tests replay their scenario with no model server anywhere, and the second takes fourteen seconds here because an hour of the village is in it.
The first check written for the first claim did not read the world. It replayed the script
and then read the tape: the bandit's line is in the recording, it landed after it was asked,
and its answer is not empty. Every line of that is true of the file, and the file does not
change when the law does. The test flag -perturb clause flips the first clause
of the Taboo Index from never to allowed after the console has read it,
so that a merchant may take from a stranger; under it the merchant's take is accepted and
ten grams cross, which is the one thing chapter 97 exists to make impossible, and the check
passes anyway:
// cmd/village/scenario_test.go — the first check written for the first claim, kept as what it is
func TestTheRecordingHoldsTheBanditsLine(t *testing.T) {
const script, from = "bandit-102.txt", "../../exemplars/bandit.json"
c := founding(t, script, from)
quietly(t, c, script)
tp, ok := c.m.o.(*tape)
if !ok {
t.Fatal("no recording")
}
for _, tn := range tp.turns {
if tn.Villager != "Rusk" || tn.Job != "line" {
continue
}
if tn.Landed <= tn.Asked {
t.Fatalf("Rusk's line landed at %d, asked at %d", tn.Landed, tn.Asked)
}
for _, cl := range tn.Calls {
if cl.Call == "line" && cl.Answer != "" {
t.Logf("Rusk's line is in the recording, asked at %d, landed at %d, %d tokens", tn.Asked, tn.Landed, cl.Out)
return
}
}
}
t.Fatal("no line of Rusk's in the recording")
}
$ go test ./cmd/village/ -run 'TestTheRecordingHoldsTheBanditsLine' -v -args -perturb clause
=== RUN TestTheRecordingHoldsTheBanditsLine
scenario_test.go:206: Rusk's line is in the recording, asked at 4950, landed at 5084, 12 tokens
--- PASS: TestTheRecordingHoldsTheBanditsLine (0.58s)
PASS
ok theworld/cmd/village 0.590s
Reason from the symptom. The test passed with the law broken because nothing it asked
depends on the law: a recording is what a model said, and the engine's verdicts are
computed from it and never written into it. A check over the recording is a check that
the file has not been corrupted, which is exemplars's business and a test
there already does it. The fix is stage 4's test, which reads the verdict and the grams
off the world after the replay, and the same perturbation makes it fail, as does a grams
figure changed to a sum no stranger holds:
$ go test ./cmd/village/ -run 'TestABanditTakesWhatAMerchantIsStoppedFromTaking' -args -perturb clause --- FAIL: TestABanditTakesWhatAMerchantIsStoppedFromTaking (1.24s) scenario_test.go:132: the merchant's take was accepted, and 10.0 grams crossed FAIL FAIL theworld/cmd/village 1.241s FAIL $ go test ./cmd/village/ -run 'TestABanditTakesWhatAMerchantIsStoppedFromTaking' -args -perturb grams --- FAIL: TestABanditTakesWhatAMerchantIsStoppedFromTaking (0.62s) scenario_test.go:114: the bandit's take was refused by reach: step 1: 500 grams named, and body 25 holds 155.6862 FAIL FAIL theworld/cmd/village 0.620s FAIL
Under -perturb clause the fixed test fails at the merchant's half with the
grams that crossed printed; under -perturb grams it fails at the bandit's, by
reach, with the stranger's store printed beside the sum, which is the same refusal chapter
101's three hundred grams got. A check that can be made to fail two ways by two different
lies is a check; the one above it is a comment with a green light on it. The naive test is
kept in the file under its own name so that the run above can be made again, and the page
says what it is.
The same two scripts live
The containers are volume 8's: the model server on the closed bridge with
OLLAMA_MAX_LOADED_MODELS=1 and the three files on the named volume, the Go code
in world-go, the database in world-db, emptied by
podman kill and podman start before each live run below. The
server is not restarted for this chapter and no load is timed on this page: chapter 101
timed the hero model's load once on a restarted server, and here the hero model is resident
when the chapter starts and is evicted and put back by the small model's calls in between,
which the console prints as the eviction and this page does not measure. The server's API
reference is under github.com/ollama/ollama.
Each scenario ran live twice on this machine: once with every call written down, which is how the two recordings were made, and once more with nothing recorded, which is the run below. Only its counts and its verdicts are for comparing; every duration is measured here and yours will differ, on a Ryzen 7 3700X with the models on the processor and nothing on a graphics card, at ten ticks a second.
$ podman kill world-db && podman start world-db world-db world-db $ podman exec -w /bench world-go go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/bandit-102.txt -hz 10 -limit 16 -patience 0 -live -rob 20 | tail -108 | head -1 tick 5083 Rusk's line landed: asked at 4950, 133 ticks in flight; 1 generation(s), 2 embedding(s), 2 load(s); 13.291s on the worker (measured here; yours will differ) $ podman exec -w /bench world-go go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/bandit-102.txt -hz 10 -limit 16 -patience 0 -live -rob 20 | tail -100 | head -3 the seam, at tick 5083 over the world as it stands, on one step, say to body 25: accepted the row appended as proposal 1, accepted tick 5083 Rusk says (a model's words; yours will differ): I see you struggling with the load. Need help? $ podman exec -w /bench world-go go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/bandit-102.txt -hz 10 -limit 16 -patience 0 -live -rob 20 | tail -49 | head -13 the row appended as proposal 3, accepted tick 5236 the console waited 20 ticks for the worker's answer to land before pressing tick 5236 the console's plan, off the flag, which no model wrote, in Rusk's name: take 20 grams from body 25, a stranger, who spoke last tick 5236 Rusk stands on 10,1 carrying 180.0000 grams, with 25 a stranger in sight; the grounding set is 4 Rusk, 25 a stranger tick 5236 the seam, at tick 5236 over the world as it stands: accepted tick 5236 the row appended as proposal 4, accepted, in the console's name tick 5250 wake 7: stopped: the script has ended and the console is pressing the seam tick 5275 Pella's plan ran out; the habit has the ticks until the next answer tick 5276 Rusk's plan ran out; the habit has the ticks until the next answer tick 5277 40 ticks of the step's span run; Rusk is carrying 185.2200 grams, 5.2200 more, and you are carrying 142.3262 tick 5274 Rusk row 188 [did] weight 6, about [25]: took 20 parcels from a stranger, 10.0 grams tick 5274 you: Rusk took 20 parcels out of a stranger's hands, 10.0 grams $ podman exec -w /bench world-go go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/bandit-102.txt -hz 10 -limit 16 -patience 0 -live -rob 20 | tail -13 | head -13 generations the server was asked for 3 embeddings the server was asked for 18 calls that found their model not resident 6 on the worker's clock: 8.107s a request on average, 13.291s the longest, over 3 requests (measured here; yours will differ) the eviction, paid in: 1 load(s) of the hero model, 3.138s in all; paid back: 1 load(s) of the small model after a line, 885ms in all (measured here; yours will differ) the village did not think for 226 ticks over 1 line(s) paid back, from the line's hand-off to the next answer from the small model, at 10 ticks a second (measured here; yours will differ) 376 ticks in 37.603s, 10 ticks a second (measured here; yours will differ) memory rows in the table at the end 200 ledger rows, read back ORDER BY id 4 of those, accepted 3 of those, refused 1 qwen2.5:0.5b-instruct-q4_K_M is the model resident now, answering on the processor, with no bytes on a graphics card
$ podman exec world-db psql -U world -d world -c "SELECT id, villager, tick, kind, left(model, 28) AS model, tokens_in, tokens_out, verdict, failed FROM proposal ORDER BY id;"
id | villager | tick | kind | model | tokens_in | tokens_out | verdict | failed
----+----------+------+---------+------------------------------+-----------+------------+----------+--------
1 | Rusk | 5083 | line | qwen2.5:7b-instruct-q4_K_M | 279 | 12 | accepted |
2 | Orrin | 5176 | plan | qwen2.5:0.5b-instruct-q4_K_M | 458 | 209 | refused | shape
3 | Pella | 5236 | plan | qwen2.5:0.5b-instruct-q4_K_M | 389 | 43 | accepted |
4 | Rusk | 5236 | console | the console, off the flag | 0 | 0 | accepted |
(4 rows)
The line lands a tick earlier live than it did on the recording, at 5083 against 5084, and its words are the recording's words: the same prompt at temperature nought on the same machine gives the same twelve tokens, and the page says that is a property of this machine and not a check. The counts are the check. Three generations, one of them the line, the same three verdicts in the same order, the same twenty parcels, and a ledger of four rows whose fourth is the console's, in Rusk's name, accepted, with the console in the model column and no tokens in either count. The small model is the one resident at the end, put back by Orrin's plan, and the console's summary prints the eviction paid in and paid back without measuring anything this page quotes.
$ podman kill world-db && podman start world-db world-db world-db $ podman exec -w /bench world-go go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/hour-102.txt -hz 10 -limit 16 -patience 0 -live | tail -83 | head -1 tick 41060 Sessa's catch-up landed: asked at 40950, 110 ticks in flight; 0 generation(s), 371 embedding(s), 1 load(s); 10.916s on the worker (measured here; yours will differ) $ podman exec -w /bench world-go go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/hour-102.txt -hz 10 -limit 16 -patience 0 -live | tail -56 | head -2 tick 41258 Sessa's line landed: asked at 41100, 158 ticks in flight; 1 generation(s), 1 embedding(s), 1 load(s); 15.762s on the worker (measured here; yours will differ) of which 3.144s was putting qwen2.5:7b-instruct-q4_K_M in memory: the server was holding nomic-embed-text:v1.5, and not this one (measured here; yours will differ) $ podman exec -w /bench world-go go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/hour-102.txt -hz 10 -limit 16 -patience 0 -live | tail -42 | head -3 the seam, at tick 41258 over the world as it stands, on one step, say to body 25: accepted the row appended as proposal 1, accepted tick 41258 Sessa says (a model's words; yours will differ): The parcel I sold you at midwinter had sand in it, and you complained $ podman exec -w /bench world-go go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/hour-102.txt -hz 10 -limit 16 -patience 0 -live | tail -13 | head -13 generations the server was asked for 1 embeddings the server was asked for 372 calls that found their model not resident 2 on the worker's clock: 13.339s a request on average, 15.762s the longest, over 2 requests (measured here; yours will differ) the eviction, paid in: 1 load(s) of the hero model, 3.144s in all; paid back: 0 load(s) of the small model after a line, 0s in all (measured here; yours will differ) the last line's eviction was not paid back: the session ended before the small model answered again, and the hero model is the one resident 36397 ticks in 55.298s, 658 ticks a second (measured here; yours will differ) memory rows in the table at the end 8141 ledger rows, read back ORDER BY id 1 of those, accepted 1 of those, refused 0 qwen2.5:7b-instruct-q4_K_M is the model resident now, answering on the processor, with no bytes on a graphics card
$ podman exec world-db psql -U world -d world -c "SELECT count(*) AS vectors FROM memory_vector;" -c "SELECT id, tick, weight, said_by, left(text, 60) AS text FROM memory WHERE kind = 'heard' ORDER BY tick, id;"
vectors
---------
372
(1 row)
id | tick | weight | said_by | text
------+-------+--------+---------+--------------------------------------------------------------
47 | 4908 | 7 | 25 | a stranger said to Sessa: "The parcel you sold me at midwint
8027 | 40908 | 5 | 25 | a stranger said to Sessa: "Tell me again about the parcel yo
(2 rows)
One generation over the whole session, three hundred and seventy-two embeddings, and the
table of vectors holds exactly that many: her hour, and the newly heard row. The catch-up
lands a tick later than on the recording and the line four earlier, the words are the
recording's, and the hero model is the one resident at the end because nothing asked the
small model after the line. The two heard rows are the only rows with a speaker, at 4908 and
40908, thirty-six thousand ticks apart on the world's clock. The counterfactual is chapter
98's accelerated village given a village to ruin: -unpaused leaves the
scheduler asking while you are away, and it is run live because the recording has no
answer from inside the hour to replay.
$ podman kill world-db && podman start world-db world-db world-db $ podman exec -w /bench world-go go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/hour-102.txt -hz 10 -limit 16 -patience 0 -live -unpaused | tail -81 | head -3 tick 40908 you are back; while you were away the village laid down 7979 rows, 3 of it died, and 720 wakes came due; 164 plants are standing at 5446.5 grams tick 40908 the scheduler was left asking: 1 request(s) handed, 1624 dropped unasked tick 40908 and it has stopped: at tick 25184 an answer asked for at tick 4950 landed 20234 ticks later, past the cap of 200 and past the 400 the asking stops at: at this pace no answer can land in time, so the village runs the utility rule from here $ podman exec -w /bench world-go go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/hour-102.txt -hz 10 -limit 16 -patience 0 -live -unpaused | tail -49 | head -3 tick 40908 you stood there 0 ticks and no line landed; the world goes on and so does the queue > wait 390 tick 40950 wake 721: stopped: at tick 25184 an answer asked for at tick 4950 landed 20234 ticks later, past the cap of 200 and past the 400 the asking stops at: at this pace no answer can land in time, so the village runs the utility rule from here $ podman exec -w /bench world-go go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -roll village-24.json -script cmd/village/hour-102.txt -hz 10 -limit 16 -patience 0 -live -unpaused | tail -29 | head -8 requests handed to the worker 1 answers landed 1 requests dropped unasked 1625 plans accepted at the seam 0 plans refused at the seam 0 steps refused when they came due 0 lines said 0 lines refused at the seam 1
The wake at 4950 hands the line the moment the hour begins, the worker takes it at the
pace a worker takes anything, and by the time the answer lands the world has run twenty
thousand two hundred and thirty-four ticks past the asking: refused by freshness, and
past twice the cap, so the asking stops, with sixteen hundred and twenty-four requests
dropped unasked behind it. When you come back and ask her again, the line goes to the head
of a queue nobody serves, every wake for the rest of the session says why, and no line
lands. One generation was spent on a sentence nobody heard and the village never thinks
again; the design spends none and thinks again at the first wake after you are back. That
is the difference between stopping and pausing, and it is why Paused is a
state the driver lifts and Stopped is not.
Ticks a second across five arms
Chapter 98 measured the daemon's ticks a second three ways on one ground and found the scheduler's own cost to a tick was the loop's and not the model's. This is the same measurement on the ground the village lives on, with the count the scheduler's arithmetic bites at added as a fourth and fifth arm: the ground and its plants with an empty roster; three people on the habit; twenty-four on the habit; three with the scheduler over a recording; twenty-four with the scheduler over a recording. Every arm runs the same script, a thousand ticks of standing still from the boundary the people were founded at, twenty times over from a fresh world each, ungoverned, with the clock on the script's ticks alone and the output swallowed. The last answer of each recording lands after the stretch ends, because the worker was still busy with it when the stretch ran out, and a paced run does not stand for an answer in flight at its end.
# cmd/village/pace-102.txt
# Chapter 102 stands still for a thousand ticks, so that every arm of the pace
# measurement covers the same stretch from the same boundary.
wait 1000
// cmd/village/away.go — paced: the script, N times over from a fresh world, with the clock on the ticks alone
func paced(g ground, f minding, n int) error {
g.hz = 0
if f.from == "" && !f.live && g.roll != "none" {
f.habit = true
}
// ...
var spent time.Duration
ran, wakes, landed, posted, laid, habit := 0, 0, 0, 0, 0, 0
// ...
for i := 0; i < n; i++ {
if i > 0 {
c, err = session(g, f)
if err != nil {
return err
}
}
c.pacing = true
os.Stdout = null
start := time.Now()
c.run(bytesReader(b))
spent += time.Since(start)
c.close()
os.Stdout = out
ran += c.ran
// ...
}
// ...
fmt.Printf(" %d ticks in %s, %.0f ticks a second (measured here; yours will differ)\n",
ran, spent.Round(time.Millisecond), float64(ran)/spent.Seconds())
// ...
}
$ go run ./cmd/village -roll none -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -script cmd/village/pace-102.txt -limit 16 -patience 0 -pace 20 | tail -3 | head -3 the village nobody: the ground and its plants, an empty roster hooked into every tick, and you the pace ungoverned, so the number is what the loop can do and not what it is held to 20000 ticks in 3.927s, 5093 ticks a second (measured here; yours will differ) $ go run ./cmd/village -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -script cmd/village/pace-102.txt -limit 16 -patience 0 -pace 20 | tail -4 | head -4 the village 3 people on the habit alone, off configs/village.json; witnesses writing rows; the scheduler off the pace ungoverned, so the number is what the loop can do and not what it is held to 20000 ticks in 4.124s, 4850 ticks a second (measured here; yours will differ) 400 wakes, 0 answers landed, 0 intents posted, 860 rows laid down, 60000 ticks on the habit $ go run ./cmd/village -roll village-24.json -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -script cmd/village/pace-102.txt -limit 16 -patience 0 -pace 20 | tail -4 | head -4 the village 24 people on the habit alone, off configs/village-24.json; witnesses writing rows; the scheduler off the pace ungoverned, so the number is what the loop can do and not what it is held to 20000 ticks in 4.798s, 4169 ticks a second (measured here; yours will differ) 400 wakes, 0 answers landed, 0 intents posted, 6680 rows laid down, 480000 ticks on the habit $ go run ./cmd/village -from exemplars/pace-three.json -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -script cmd/village/pace-102.txt -limit 16 -patience 0 -pace 20 | tail -4 | head -4 the village 3 people, off configs/village.json; the scheduler at every wake, every answer off exemplars/pace-three.json and through the seam at the boundary it landed on the pace ungoverned, so the number is what the loop can do and not what it is held to 20000 ticks in 4.187s, 4777 ticks a second (measured here; yours will differ) 400 wakes, 280 answers landed, 11060 intents posted, 1140 rows laid down, 48940 ticks on the habit $ go run ./cmd/village -roll village-24.json -from exemplars/pace-village.json -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -script cmd/village/pace-102.txt -limit 16 -patience 0 -pace 20 | tail -4 | head -4 the village 24 people, off configs/village-24.json; the scheduler at every wake, every answer off exemplars/pace-village.json and through the seam at the boundary it landed on the pace ungoverned, so the number is what the loop can do and not what it is held to 20000 ticks in 4.777s, 4187 ticks a second (measured here; yours will differ) 400 wakes, 260 answers landed, 5600 intents posted, 6920 rows laid down, 474400 ticks on the habit
$ go run ./cmd/village -roll village-24.json -from exemplars/pace-village.json -ground 24,16 -plants 12 -settle 4000 -idle rest -glance 12 -carrying 190 -script cmd/village/pace-102.txt -limit 16 -patience 0 | tail -21 | head -12
intents you posted 0
of those, taken out of your slot 0
of those, refused by the check 0
ticks your body found the slot empty 1037
intents anybody posted to a villager 280
ticks the villagers ran their own rule 23720
wakes 20
requests handed to the worker 14
answers landed 14
requests dropped unasked 69
plans accepted at the seam 5
plans refused at the seam 9
Five numbers, one ground, measured here on the processor, and yours will differ. Five thousand and ninety-three ticks a second with nobody on the ground but you; four thousand eight hundred and fifty with three people on the habit and their witnesses writing; four thousand one hundred and sixty-nine with twenty-four; four thousand seven hundred and seventy-seven with three and the scheduler; four thousand one hundred and eighty-seven with twenty-four and the scheduler. The ground is most of the tick: a hundred and thirty-six plants at founding and more by the end of the stretch, on two hundred and ninety-two soil cells, where chapter 98's ground was twelve by eight with twelve plants on it. Twenty-four people cost the tick eighteen per cent against nobody, and the difference between those people thinking and not thinking is inside the noise: the third and fifth arms are eighteen ticks a second apart, and an earlier run of the same five commands, made while drafting, put the third ninety-two ahead of the fifth. The scheduler's cost to a tick is below what this clock resolves, which is chapter 98's finding at eight times the count.
What the twenty-four did with the thousand ticks is the second run. Twenty wakes; fourteen requests handed, because the worker was busy at six of them; sixty-nine requests dropped unasked for having waited past the cap; five plans accepted and nine refused; thirteen people asked once and Solvi twice, and eleven never asked at all in a stretch of a hundred seconds. The three-person village over the same stretch posted five hundred and fifty-three intents and ran the habit for two thousand four hundred and forty-seven of its three thousand villager-ticks; the twenty-four posted two hundred and eighty and ran the habit for twenty-three thousand seven hundred and twenty of twenty-four thousand. That is what the arithmetic biting looks like, and none of it shows in the ticks a second.
Every figure here is in ticks at ten ticks a second, the pace both recordings were made at, on the machine named above with the models on the processor. The same seconds in a world run a hundred times faster are a hundred times more ticks, which is why the pace is beside each of them.
The tick first. At five thousand and ninety-three ticks a second an empty ground costs 196 microseconds a tick; at four thousand one hundred and eighty-seven a thinking village of twenty-four costs 239. The village adds 43 microseconds to a tick of a hundred milliseconds, which is four parts in ten thousand of the budget, and the scheduler's share of the 43 is not measurable. The tick is not where the price is.
The worker next. The scheduler wakes every fifty ticks and hands one request a wake at most, and it hands nothing when the worker is busy, which in the twenty-four-person stretch was six wakes in twenty. Twenty-four people served one a wake is a round of at least twenty-four wakes, twelve hundred ticks, two minutes of the watched pace; a plan's horizon is a hundred and sixty ticks, so a villager served on that round runs its own plan for thirteen per cent of its life and the habit for the rest, and the recorded stretch did worse than the arithmetic, with eleven of twenty-four not served at all in a thousand ticks. The cap is two hundred ticks, so a request that waits five wakes is dropped unasked before a call is made for it, and sixty-nine were, in a thousand ticks.
A person's minute last. A line holds the worker for its whole flight, a hundred and thirty-four ticks for Rusk's and a hundred and sixty-two for Sessa's, and a wake inside that flight hands nobody anything. A minute is six hundred ticks, twelve wakes; a person who says something and waits for the answer and says something again fills it with four lines, and every one of the twelve wakes hands nothing to the other twenty-three. Twelve turns is half a round of the village, so the minute you spend talking to one villager moves every other villager's next thought back by six hundred ticks, on top of a round that is already twelve hundred. And a person who was away an hour costs the village a hundred and nine ticks more before the line can even be asked, because the villager they come back to has three hundred and seventy-one rows to embed first, and nobody is served during those either.
wake = 50; round = 24 × wake = 1,200; share = horizon / round = 160 / 1,200 = 0.13; minute = 600 = 12 wakes; lines a minute = minute / flight = 600 / 150 = 4; cost of the minute = 12 turns nobody else got = round / 2
- wake
- the scheduler's cadence, in ticks: 50, off the file
- round
- the fewest ticks in which every villager can be handed one request: 24 wakes, 1,200 ticks
- horizon
- the most ticks a plan may span: 160, off the file
- share
- the part of a villager's life it spends on its own plan when served once a round: 0.13
- flight
- ticks a line holds the worker: 134 and 162 on this page
- minute
- sixty seconds at ten ticks a second: 600 ticks, 12 wakes
- catch-up
- ticks the worker spent giving an hour of one villager's rows their vectors: 109, for 371 rows
- a × b, a / b
- a multiplied by b; a divided by b
Why recordings prove the code path
Every run on this page with no model server behind it is the console playing a file of model answers through the live scheduler, the live seam, the live law, the live stream and the live world, and comparing nothing about the answers. The recording holds what the model said and the prompt it said it to; the tape refuses to hand an answer to a prompt whose bytes differ, which is how a recording is only ever a recording of this code. Everything after the answer is the engine's: whether the plan parses, which clause binds, whether the take crosses to the body named, what the witness writes, which eight rows come to mind and in what order. That is what the contract binds, and the two tests are the sentence made mechanical: legality and grounding, read off the world, and not the bytes of any one sentence, which are labelled where they are printed and compared nowhere.
The two claims needed two things a bench could not give them. A bandit walks up to nobody on a bench; in the console the bandit's take is judged in a village where a neighbour can wander into his reach carrying more than you, and the first run of this page was refused for exactly that, by the crossing question chapter 97 added to the fifth check. A merchant told a thing on a bench is asked again a few hundred ticks later; in the console the hour is real, the village dies or does not on the ground it was founded on, and a villager comes back from it with three hundred and seventy-one rows that have to be embedded before she can be asked anything, inside a cap that was set for a world that had never been away. The catch-up and the pause are the two pieces of design this chapter added, and both exist because a scenario run in the world found a cost the bench had never had to pay.
And the price, which is the volume's last word. Twenty-four people cost the tick nothing the clock can see and cost the worker everything: one request a wake, a round of two minutes, thirteen per cent of a life on a plan, sixty-nine requests dropped unasked in a thousand ticks, and a person's minute of talk worth half a round of everybody else's thinking. Nothing in the tick loop knows any of that is happening; the mailbox carries a value or nothing, and the habit has every tick the worker cannot fill. A village of this size at this pace on this processor is a village that mostly runs the utility rule and thinks in turns, and the volume built the utility rule first so that it could.
- Say what the three flags of the founding are for, which of the three foundings measured in stage 2 loses eleven of twenty-four in an hour and why, and why the console's turn every twelfth idle tick is a wrapper round chapter 91's mind and not an edit to it.
- Read the bandit replay's pressing and account for 185.3000 grams from 180.0800 with ten grams crossing, then say which clause refuses the merchant's identical proposal and why it is clause 1 and not clause 2.
- Name the three things the first test reads off the world and the one thing the naive
test read instead, and say why
-perturb clausefails one and not the other. - Explain why the line owed at 4908 is never handed, why a catch-up is handed at 40950 in the line's place, and why a catch-up cannot be late where a line can.
- Work out from the five pace arms what twenty-four people cost a tick in microseconds, then from the wake, the count and the horizon what share of its life a villager spends on its own plan, and say which of the two is the price.
- Say what the scheduler left asking during an hour away costs and never gets back, and
what the difference between
PausedandStoppedis in one sentence.
Exercise 1 — a profile that changes nothing. Replay the bandit
script with -law Sessa=bandit in place of -law Rusk=merchant,
keeping -rob 20, and read the header and the pressing. Whose name is the
take in, under which profile, and what would the script have to contain for the take
to be in Sessa's name?
The pressing is in the name of the villager last spoken to, and the script speaks to
Rusk, so the take is still his and still judged under his own row's profile, and
-law Sessa=bandit changes her header line and nothing else; the replay is
the same to the byte, because no recorded answer of Sessa's was ever handed. To press
in Sessa's name the script has to say something to her, and a script that does is a
different recording, because the line it owes her is a different prompt. Nothing on
the page can be re-quoted for it: make the recording with -record against
the models and replay that.
Exercise 2 — the threshold at nought. Set the catchup block's
rows to 1 and replay the hour script. Read what the wake at 4950 of the
bandit script does under the same setting, and say why the hour recording still replays
and the bandit recording does not.
With a threshold of one row, every turn with two or more rows waiting becomes a catch-up. The hour recording's first request is a catch-up already, so nothing changes before the line, and the line is handed with one row waiting, which is not more than one. The bandit recording's first request is Rusk's line with two rows waiting; the console hands a catch-up instead, the tape holds no catch-up for Rusk at 4950, and the worker meets an error and the villager keeps to the habit. A recording is of one set of settings as much as of one script, and the header prints the threshold for that reason.
Exercise 3 — the stop rule at the cap. The console stops at twice
the cap. Change m.sch.Stop to nought, which is chapter 98's rule, and run the
hour script live. Read where the session ends and what the last wake says.
The run is the recording's until the line lands, and if the line lands inside two hundred ticks the session is the same to the end. If it lands late by even a tick, which on this processor is a matter of load, the sixth check refuses it and, with the stop at the cap, the scheduler stops for good: the summary prints the stop, the last wakes print stopped, and a village that had spent a hundred and nine ticks catching up never uses the vectors. The console's rule is that one late line is one refusal, and the run shows what the other rule costs.
A bandit took ten grams out of your hands under his profile and was stopped by clause 1 under a merchant's; a merchant told a thing at 4908 said it back at 41262 with the row second in her prompt; both came off a file with no model anywhere and then off the models with nothing recorded, and both are tests that fail when a clause is flipped or a figure is changed. The village that did it is twenty-four people on a ground grown four thousand ticks for them, and its price is on the page in the only currency this volume has trusted: a tick costs 43 microseconds more with all of them thinking and the clock cannot see the thinking in it; the one worker serves one of them a wake, so each is served once in two minutes and runs its own plan for thirteen per cent of its life; a person who talks for a minute takes half a round of everybody's thinking, and one who leaves for an hour comes back to a villager who cannot be asked anything until an hour of her memories has been given vectors. That is what the world's own pace does when twenty-four people in it start thinking, and it is the price the volume was built to state.