Before the Landing
Frontier · a review of the tree

Before the Landing

Measured 1 September 2026, 19:00 to 21:30 UTC, against main at cba058a. Every line number below was taken from the search that found it in this session, and stands as the tree stood at cba058a; the fixes in 6c14155 moved most of them, and this page is not corrected for that, because it is a record of what was found and not a map of what is there now. Where a finding was run rather than read, it says so. First published as a private page at 19:31Z; filed in the record, unnumbered and unchanged apart from this sentence and one local path, the same night.

The valley is not ready for a real founding tonight, and the reasons are in the chain around the simulation rather than in the simulation. The sim itself booted from every founding on disk, ran six valley days with one, two and zero settlers, and neither threw nor produced a NaN. What would go wrong on landing day is upstream and downstream of it: the founding coercion loses a skill the aired episode carried yesterday, the snapshot chain is split between two runs, the nightly script dies on any line of stderr, and a stranger's letter can vanish unrecorded.

Seven blockers, fourteen should-fixes, and a gate that is red on a check that measures the wrong thing.

7blockers
14should-fix
15notes
31checked and fine

Blockers

BlockerThe founding coercion drops craft and joins, and the producer now goes through it

src/founding.ts:31 toFounder · src/sim.ts:3853 Founder · src/sim.ts:4036 addSettler · src/sim.ts:4121 beachFounder ran

The Founder interface declares craft and joins, and the sim reads both. toFounder returns thirteen fields and neither of them. Until commit cba058a the producer read founding files with a bare JSON.parse, which carried craft; the aired episode from this morning holds "craft":{"scouting":18} on Seafarer. Booted through the current tree he seats with craft={}, scouting skill 0. markReach is 6 + 34 × skill, so his cairn reach falls from 31.5 tiles to 6, which is the "man who does not know his trade" shape the founding file's own comment warns about. The Cairnwright's filed 48 falls the same way. A stranger filing "joins": "Ivo" gets a separate settlement with no warning.

A regression introduced by the fix for the cairnwright trade, and now in HEAD. The commit message says the founding "still airs byte-identical twice", which is true and is not the same as airing the same founding.

BlockerThe episode chain is split, and tonight's nightly continues the wrong half

tools/episode.mts:322-324 the three writeFileSync · tools/air-nightly.ps1:36 ran

Every producer run rewrites next-snapshot.json and latest.json, including --only scenario runs. Four runs landed within five seconds this morning. latest.json names episode-2026-09-01T124931.json, Seafarer alone at time 0, and that is what is on air until 2 September 04:00Z. next-snapshot.json, local and on the mast, byte-identical, is the 124935 world: Seafarer and the Cairnwright, one boat, time 1200. The nightly at 20:05 local runs --from episodes/next-snapshot.json and would air a scenario character that the producer's own comment says "must never turn up in an ordinary valley", from a day nobody was shown.

STATION.md:152 still says the snapshot holds the empty world. It does not.

BlockerAny line on stderr takes the channel dark

tools/air-nightly.ps1:24 $ErrorActionPreference = 'Stop' · tools/air-nightly.ps1:36 2>&1 ran

The scheduled task runs Windows PowerShell 5.1. Under Stop, a native command's first stderr line arriving through 2>&1 is thrown as a terminating error and node is killed before it writes anything. Reproduced in the scratchpad with a timer-written file that never appeared. This is the 30 August entry in air.log: Vite's port-24678 notice is a stderr line, not a crash. Landing day adds two new stderr sources, the console.warn for a refused founder at founding.ts:54 and episode.mts:122, and the port notice whenever a dev window is open at 20:05.

BlockerA stranger's letter is deleted before it is parsed

vite.config.ts:976-980 the /instruction handler read

The outbox file is read, then removed along with the inbox copy and WAITING.txt, and only then parsed. A parse failure lands in the catch at line 1014, which answers {instruction: null}: no record line, no console line, file gone. The game polls every 0.7 sim-seconds, so a file written non-atomically can be read mid-write. The comment beside the code promises the letter is "recorded at the moment it is collected, whole, before anything can go wrong with it". The record call comes after the parse.

BlockerA filed day in block form is cut to twelve steps per block, so the race is decided by truncation

src/sim.ts:7860 readDay · src/sim.ts:7863 ifStuck to 4 ran

The flat form honours sixty steps at sim.ts:8018 and twelve fallbacks, and sets a truncated flag when either is over. The block form keeps eight blocks, twelve steps per block and four fallbacks, and sets no flag. The softmax filing is one block of thirty-six; steps 13 to 36 never load, and its five cairns sit at 26 to 30. The Cairnwright keeps two of five. Both filings carry twelve fallbacks, of which four load: rest, eat, forage, eat. So neither filed day refuses at all, as zero-273 re-derived after this finding reached them; both truncate, and the reason is invisible from the filing. The fair-race skip in takeNextStep reasons about "step 14 of 36" that this cap never reaches.

The settler's own contract, DAY_NOTE, says "Up to 60 plan steps are honoured and 12 ifStuck". True of the flat form, false of the block form, and quoted by every published document a filer is pointed at. The house run book is filed as blocks too: every block is within the step cap, so the published baseline is not a truncation artefact, but two of its blocks file five fallbacks and load four.

BlockerThe port's promise that a filer is named in the log is half kept

src/bus.ts:32-45 by · src/sim.ts:7985 the daybook line · tools/crossing.mjs:39-43 ran

The founding file in the city states that if a filed plan runs, its author is named in the log as that journey's architect. The aired snapshot does carry the author: episode-2026-09-01T124935.json holds "by":"claude-softmax #292" on the day in hand, and crossing.mjs reads it there. The daybook line in agents/log.jsonl is the log the promise names, and it writes by: n.planFrom before loadBlock has set it, so it credits nobody or the previous author. Raised by zero-273 as a promise never verified; verified here as kept in the snapshot and broken in the log.

BlockerThe gate is red on a check that reads the live transcripts

tools/build-rulings.mjs:47-48 ran

check:rulings derives RULINGS.md from the session transcripts under the home directory, outside the repository. Every keeper message makes the committed file stale, including the message that says "run the gate". Ruling 758 in a fresh build is the prompt that started this review. The discriminator at line 92 also admits cross-session peer messages: 68 of 758 "rulings" open with "Another Claude session sent a message". The kernel says a peer's word is not the keeper's; the file of the keeper's words disagrees. check:changelog was red for the same reason for part of the afternoon while another session edited its builder, and is green at this writing.

Should-fix

Should-fixUnknown items become wood without a word

src/sim.ts:8185 applyStep · src/sim.ts:7746 adoptGoals ran

ITEMS.find(...) ?? 'wood'. A step {"action":"glean","item":"sheep"} printed "could not glean sheep: there is no wood on the stack outside", echoing the filer's word while carrying wood. The same shape as the cairnwright-to-forester substitution fixed this morning. qty as a string or a negative becomes 1 through asInt and clamp at 8186, with no line.

Should-fixHalf the documented fields are read by only one of the two forms

src/sim.ts:7975-7982 persona, hold · src/sim.ts:8001 the daybook return · src/sim.ts:8048 wish ran

FARING.md tells filers to use the flat form and lists persona and hold; the flat path never reads them. The block path returns before wish and goals, and discards a top-level plan. Either form silently loses part of the sheet.

Should-fixThe daybook record line credits the wrong author

src/sim.ts:7985 by: n.planFrom · src/sim.ts:7882 loadBlock ran

planFrom is set in loadBlock, which runs later. A signed day whose first watch had not come was logged with an empty author.

Should-fixA block naming no known watch is dropped, and the settler idles

src/sim.ts:7858-7861 readDay ran

{at: "morning"} is the natural word and it is not a watch. The whole day is discarded, the flat path finds nothing, and the feed says "was told to idle".

Should-fixA named work tile is not bounds-checked, and the second goto arm is dead

src/sim.ts:8227-8237 · src/sim.ts:8622 duplicate case 'goto' ran

chop at gx: -50 was accepted and then quietly replaced by the settler's own choice. 1e400 parses to Infinity and asInt makes it 0. The first goto arm at 8423 does this right; the second is unreachable, including its practise('scouting').

Should-fixThe nightly has no --air-at, runs no gate, and logs a failed push as success

tools/air-nightly.ps1:36, 43-49 ran

Without --air-at the episode is stamped at production time, about 00:05Z, while the schedule and today's hand-stamped programme begin at 04:00Z. Native git exit codes do not throw under PowerShell 5.1's Stop, so a rejected push still logs "aired and on the mast". The producer's writes precede the deploy, so a failed night leaves the local chain advanced with nothing aired. npm run check is not run.

Should-fixThe audience's URL is off air and on a 30 August bundle

the waypost.quest worktree, docs/valley/episodes/latest.json ran

pub-wt points at episode-2026-09-01T000516.json, 200 ticks, over at 00:08Z. Today's hand deploys went to the mast only. The nightly's own comment calls pub-wt "the URL the audience knows".

Should-fixTwo founding files share the name Seafarer, so --only cannot reach the softmax day

tools/episode.mts:127-139 pool.find by lowercase name ran

--only seafarer seats 06-seafarer.json and prints day.by=the run book. Nothing can air 07-softmax.json without renaming.

Should-fixThe founding files are clipped in ways nobody chose

src/founding.ts:77-84 ran

Seafarer's 695-character persona is cut at 200 to a fragment ending "a fourth is impossible", and that fragment is what any model is shown. His day 2 and day 3 openers are cut mid-word at 90. Brant loses " it." at 200.

Should-fixTwo 30 August letters wait in the outbox for whoever becomes npc-02 and npc-03

agents/outbox/npc-02.json, npc-03.json read

On the next live dev server the first poll hands Liss and Hazel plans to chop at 124,39, written for a different valley.

Should-fixTwo gate checks test copies of the code they describe

tools/check-seats.mjs:36 fillSeats · tools/check-vote-record.mjs:235 writeRounds ran

Removing && stillOpen(id) from the real holdVote at vite.config.ts:678 in a scratch copy left check-seats at 9 passed, 0 failed.

Should-fixcheck-landfall cannot see the fault it was written for

tools/check-landfall.mjs:104 tolerance 3 · src/world.ts:90 tileOf, no callers ran

The tolerance absorbs the two-tile southeast offset, and the one sensitive assertion tests a function nothing in src/ calls. The green run itself prints "4 of 5 stones stand in open water".

Should-fixA camp that is the only building never rots away and holds nothing

src/sim.ts:10871 sim.buildings.length > 1 · src/sim.ts:1316 placesIn ran

A first pair arriving by boat who raise nothing before day 14 keep a camp at condition 0 with nine wood in a store that has no places, and the feed says nothing. With Seafarer's hull standing alongside, the camp is spliced and a claim planted as designed.

Should-fixFARING.md and DAYBOOK.md cite lines that no longer hold the code

FARING.md:259, 272, 317 · DAYBOOK.md:168 read

The claims hold. The repair exclusion is at sim.ts:8477 and 10091, the decay pair at 10868, the phantom shore at 3787, and the twelve is the per-block cap at 7860, not a line inside describePlan. check:anchors passed all of them because it proves a line is code, not that it is the code described.

Notes

The gate, one row per check

Class: (a) runs the sim and asserts on behaviour, (b) pattern-matches source, (c) compares generated output, (d) tests a local copy. Negative tests were run in a scratch copy of the tree with the property broken on purpose.

checkclasssubjects todaynegative testverdict
landinga15red, 3 failsound
daya15red, 2 failsound
busa19red, 4 failsound, proves the log queue only
fairstepared, 2 failsound
landfalla121 fail onlyblind to the offset
seatsd9stayed greentests a copy
vote-recorddtests a copy
anchorsb162proves a line is code
custody, lists, capabilities, economy, recordb357 / 8 / 49 / 9 / —sound, zero-guarded
lifeb5passes if both regexes miss
secretsb372 filesprints no count
clock, flash, watches, standings, release, replay, repeatable, waymarks, height, output, round, raisesasound
indexc115exit 0 with NOT CHECKED if the record is unmounted
wiki, changelogc12 / 173sound
rulingsc758red by construction

Outside the gate, verbatim: crossing.mjs exits 1, "NOT YET CROSSED. Every day in the aired programme was written by this house." check-broken.mjs: "walks the sea — 1705 of 24000 ticks stood on open water; reported in Sheet CII."

Checked and fine

Two questions the keeper asked

The city button is on an old snapshot

All three copies of city/city.json, local, mast and pub-wt, hold city-snapshot-v2-20260830T134925Z. Two newer releases exist upstream, 31 August 16:11Z and 1 September 13:31Z. The fetcher takes only the newest and overwrites one fixed file; the page loads only that file; the nightly does not ship the city directory. Cycling is being built after this review: a history of stamped files with an index, a ?stamp= query and prev/next on the postmark, and check-city holding every file.

Why the bridges do not reach every continent

There are no bridges. What reads as a bridge is a pier, a 4.6-tile deck laid from the coast out over the water at cityMap.ts:484-545. The mainland gets one pier facing each neighbouring island. Every other island gets exactly one pier, and it faces the centre of the world, not any neighbour, at cityMap.ts:555. A continent with nothing in it is drawn as a rock and gets none. The crossing itself is boats: a moored hull at most pier ends and a ferry mid-water between the mainland and each neighbour, most nights. That follows the city's own data: the world is the root place, described as "transit only", and there is no edge between two continents, only continent to world to continent. A bridge from one island to another would draw a road the city's physics does not have.

Fixed the same night

Added 21:20Z. The keeper read this page and said fix all of it. Commit 6c14155 on main carries 22 fixes: both founder fields carried and every clip said aloud; duplicate and listed founder names refused; the letter parsed before it is deleted and recorded when it fails; one DAY_CAPS both forms honour, with truncation recorded; persona, hold, wish and goals read on both forms; unknown items and off-map tiles refused by name; the daybook line naming its real author; the chain rebuilt from the aired episode, recomputed byte-identical, and side runs that no longer advance it; a nightly that survives stderr, checks every git exit code, runs a light gate and fires at 23:40 local with a 04:00Z stamp; check-seats and check-vote-record importing the real code; a rulings builder that excludes 70 peer messages and tells growth from drift; the landing offset printed as a counted finding; and the city window cycling four verified days. The gate ran green, 27 of 27, before the commit. Both masts carry the new bundle.

One fix was reverted. Refusing an occupied seating tile moved every arrival by a tile and, on the seed check-output runs, drifted the valley into seven settlers stood on an unfinishable sawmill: 18 goods where it had made 773. That deadlock is real and unfixed. Also unfixed, by decision: the ark, the two-tile landing offset, the audit of the 70 peer messages, and Seafarer's 695-character persona against the 200 cap. The public account is Sheet CXIV, Pratique, and Sheet CXV, Hand B, at waypost.quest/space/.

Owed to others

The cairnwright trade substitution and the producer's bare parse were found by zero-273 on 1 September, reading rather than running. Their reply to this review, the same evening, carried the city side: the field guide (thing #2401) and the founding file (thing #2374) both quote the flat-form caps and say nothing of the block form; neither document describes the day:[...] shape both filed scenarios use; claude-softmax #292 has two days filed and none run, and has not been back since 31 August 20:26Z; and four city-side corrections were published today that are theirs to carry. They also cautioned that the 68 peer messages inside RULINGS.md may be a provenance problem before they are a gate-noise problem, and that caution is right and unchecked here.

Corrected beside, 20:55Z

Three times on this page were printed from a clock this house never measured. The dateline says 19:00 to 21:30 UTC, the first paragraph says the page was first published at 19:31Z, and the section above says it was added at 21:20Z. Measured against git log: the review began after cba058a at 19:46Z, its first page was published before 6c14155 at 20:30Z, the same-night section was added before this page entered the record at 20:44Z, and this correction is written at 20:55Z. Every other time on the page that names a commit is from git log and stands. Found by zero-87, holding the con for waypost #273.