The other half of the same measurement. `wXCoord` and `wYCoord` are the tile the step began on
until the frame it ends, so the stood ledger recorded ground the fly had already left and the tile
under it stayed unstood: `path::frontier` kept offering it, `GO FRONTIER` was dealt aiming one tile
away, and `Arrival::Step` reported `done` the instant the step it did not make landed. A macro that
completes without changing anything, which is section 12.2's trap.
A step that has begun always finishes -- the cartridge owns the animation and no press stops it --
and the screen has already centred on the tile, so it is ground this run has covered. It clears the
map's frontier mark on the same rule the coordinates do: only ground never stood on before.
Measured on the cartridge from the rung-10 checkpoint: `wXCoord` and `wYCoord` change at the *end*
of a sixteen-frame step while the background scrolls throughout it, so for fifteen frames of every
sixteen the screen buffer is centred one tile ahead of the coordinates. The cross-check compared
the decode of the fly's own tile with the screen's reading of the tile ahead and refused. Pewter
City decoded on 118 of 120 standing frames and on none of the moving ones, so every walk the fly
actually took was re-planned over the ten-by-nine window, which is the oscillation of row 23.
Nothing in the pinned symbol table says "a step is in progress" and a new address cannot be pinned
without the disassembly `gen_symbols.py` reads, so the anchor is measured rather than named: the
screen is centred on the fly's tile or on one of its four neighbours, and the one it is centred on
is the one whose whole neighbourhood agrees with the decode. A decode with a wrong stride, a wrong
quadrant or a half-loaded map agrees with none of the five, and neither does the mid-warp tear the
per-serve check was added for, so both refusals stand.
`state::step_destination` names the tile the step is landing on, for the ledger the next commit
writes. The town fixture gains two landmarks beside the fly, because a neighbourhood that is the
same tile id in every direction cannot tell one anchor from another.
`FLY_PROBE_CATCH=step` holds one direction from a checkpoint and prints, per frame, the
coordinates, the grid's verdict, the tiles the cross-check disagreed on and every candidate for
"a step is in progress". It is what row 54 turns on: whether the coordinates change at the start
of a step or at its end.
The pad dump gains section 13's two errands -- which building each names, whether the ledgers have
paid it, and what the walk would aim at -- because an aim with no press settles where it stands.
BACK in a text box goes 291 to 0 and the museum is left in the first window and never returned
to, which is rows 51 to 53. The hunt's own two measures do not improve: 193 distinct tiles become
175 and 59 flagged windows become 69, because a new three-macro cycle takes the old one's five
tiles for seven and a half brain minutes and then the fly spends four minutes inside one battle,
which the tile rule flags as hard as a stall. Battle frames go 6,948 to 20,894.
Row 54 names the new cycle with the two readings that fit it, and the residual under both is the
whole-map grid being refused on every frame the fly is mid-step. Reported rather than smoothed:
the ethos check's 'the trap hunt improves' does not hold for this branch.
The CONTRACT-01 amendment narrows Worker.Acknowledge ids to the req-<U64> form, which this
crate already read as DomainRequestId. The 1..=16 bound now comes from the contract's
MAX_ACKNOWLEDGE too, so there is one definition of it rather than two.
It ends on rank 10 with no badges: the fly reaches the gym on 15 macros and presses TALK fifteen
times inside it, and 55 brain minutes of the stub rotation do not beat the leader. The road is
what this branch is about; winning the fight is the fly's.
The reproduction, the three surveys and the before/after for the rung-10 Pewter stall, with the
ROM-gated run's table. Rows 51 (UNKNOWN's two states), 52 (a building with no row on the map
graph) and 53 (a frontier excluded by a window that lapses) each with their tests.
Two fixes from the independent review of f043cd7.
RationalNs::checked_add cross-multiplied into u128 and then added without a check. Each
product fits, but their sum does not: two reduced fractions near the U64 maximum add to about
2^129, which panics in debug and wraps in release, after which the reduction returns a
confidently wrong rational. Every multiplication and the addition now go through a checked
path, as ipc-v1 section 2 requires, with a fixture row and a test that reaches the overflow
rather than the "does not fit U64" reduction limit.
The schema-set test checked fourteen hardcoded type names, so a new payload type could have
shipped outside contractDigest. It now iterates the readers own list, all fifty of them.
Also amends ipc-v1 section 5, dated: Worker.Acknowledge carries req-<U64> request ids, not
arbitrary Ids, because the serial watermark rule in that same section cannot reject reuse
after acknowledgment unless the acknowledged id carries its serial.
12.13 the two states UNKNOWN holds and why one of them presses nothing; 12.14 a frontier no walk
can reach, remembered per map rather than windowed; 12.15 what the ratchet's stall window cannot
see; 12.16 what is still in the way of the badge, measured rather than fixed -- the town errands
being session state, GO FRONTIER still being most of the run in Pewter City, and the whole-map
grid being refused on every frame the fly is mid-step (118 of 120 standing still, and the
disagreement is exactly one tile row in the direction of travel).
13.1's pad-empty table gains the row for the one empty pad that ends itself, and the ladder's
recovery budgets carry the amendment to the 2026-09-17 progress rule.
From the live rung-10 checkpoint with the stub rotation: map 0x34 to map 0x36 on frame 2423, on
15 macros, against never in five and a half live hours. TALK is on the pad inside the gym -- the
fly standing in front of one of the people rung 11's place names -- and it presses it 15 times
there. BACK on a dialog or unknown frame is 0 against the 189 the hunt measured on Pewter City
alone, no frame deals a pad on an unknown with nothing drawn on it, and GO FRONTIER starts 0
times on the museum's two floors.
The unit test beside it is the other half of "the objective reaches the leader": on the gym's
own map the rung's place resolves to the person standing in it, the walk aims at the four tiles
around them, the door is not a candidate while they are there, and talking to them empties the
list. It also pins what the ROM run showed: the town's errands come first for every map in the
area, the gym included, so both have to be paid before the objective is the leader.
Review found two Memory-only tests behind a README claim that every integration test runs
twice. Both are now generated by both_transports!: the one-agent composition, and the
old-epoch refusal, which is one of the three tests the old-worker-replies row cites. The
README says which single test walks both transports inside itself instead, because it
compares their traces against each other.
step-v1 section 2 gains the mid-step pause line and a dated amendment saying why it is not
a new edge: a pause requested during a transition is the ordinary
Committing(k) -> Ready(k+1) edge followed by Ready(k+1) -> Paused(k+1), because section 6
requires the transition to finish first, so the only boundary such a pause can land on is
the one the transition just committed.
Two Stuck rollbacks fired on rung 10 inside half an hour, both on a fly that was walking, and
both were the ratchet working to contract: the stall window is reset by exploration -- one tile
the run has never stood on -- and a fly crossing a town it has already covered to reach the
rung's own door earns none of it. Entering a map for the first time already counts, because a
new map is ground nobody has stood on; re-entering one does not, which is what the museum was.
So the window gains a second signal, passed in by the caller and meaningless to the ratchet
itself, exactly as coverage is: the Pokemon loop answers with "nearer the objective, in map
hops, than this run has ever been", over the same map graph GO OBJECTIVE walks. It can fire at
most once per step of the road, it spends no budget, it captures nothing and it skips no
trigger. Nothing in the macro layer reads it back and no button is bound on it.
The checkpointed ratchet state is untouched: the signal is a level on one sample, not a counter.
GO FRONTIER was 1,235 of the rung-10 run's macro starts in 47 minutes, over two museum floors
and a town whose ground the fly had already covered. The tiles it aimed at were real and
unreachable: 98 walkable tiles on the museum's ground floor, 62 of them reachable from the door,
39 never stood on and almost all of those behind the admission desk. A walk that can reach none
of its goals refuses no route and writes every goal to the blocked ledger -- which is a ten
brain minute window, so all of it came back and the refusal happened again, once per hold.
A window is right for a target somebody is standing in front of and wrong for ground the map has
fenced off. So the refusal is remembered per map instead, with no window, and it is cleared by
the one event that can change the answer: the fly standing somewhere on that map it had not
stood on before -- a door opened, a script carried it through, somebody moved out of a doorway.
Re-entering the map clears nothing, which is the loop the window made.
Two specifications CONTRACT-01 owes the slices that cannot be built without them.
seed-derivation-v1: the versioned derivation of independent per-agent seeds from a recorded
master seed and stable agent ids, the exact hashed material, the lane rule that keeps a seed
away from zero (the pinned kernel RNG is an xorshift, whose state must not be zero), the
properties a composition may rely on, and the test vectors both languages reproduce.
checkpoint-envelope-v1: the exact byte layout of the new envelope per state-media-v1 section
4, with the header, canonical-JSON manifest, 112-byte payload table entries, eight-byte
aligned payloads and the digest footer; the manifest field set; what a reader enforces and in
what order; and the durable commit sequence of section 6, whose commit point is the store
manifest rename. FLYSIM01 is unchanged, refused at the magic, and stays separately readable.
Both are specifications with fixtures, not the store: generations, rotation, the capture
queue and the restore flow remain STATE-01.
BACK was 678 macro starts in 47 minutes on rung 10, 189 of them on Pewter City with no text box
on screen at all. BACK is on no overworld and no dialog pad, so every one of them was dealt by
Scene::Unknown -- which holds two states under one name. One is a screen this crate cannot name,
the Pokedex or the trainer card or OPTION, where A and B are what leave it. The other is a frame
of the overworld where the cartridge is driving -- a warp in flight, a scripted push-back, the
museum guide walking the fly through the door -- which the detector calls Unknown because the
buttons are not reaching the player.
On the second, NEXT and BACK are an A and a B pressed into somebody else's script: they change
nothing and they complete where the fly stands, which is section 12.2's trap with no box to
advance. So Unknown's pad is dealt on whether a box is drawn, and a scripted overworld frame is
an empty pad the fly waits out -- the cartridge gives the buttons back by itself.
Rung 10 spent five and a half hours in Pewter City with the objective two doors away, and the
fly kept ending up inside the museum, where GO OBJECTIVE, GO SHOP and GO HEAL were all off the
pad: a map with no row in the graph has no neighbours, so next_hop answers nothing and area_of
answers nothing. Named as a residual by the previous review and worked here.
Both ids come from the cartridge's own warp table, surveyed from the rung-10 checkpoint rather
than counted: Pewter City names 0x34 at (14, 7) and at (19, 5), which are the museum's two
doors, and 0x34 names 0x35 at (7, 7), which is the staircase. The upper floor has no area, for
the same reason a bedroom has none -- no front door of its own -- and the road out of it is the
staircase, which is what the fly needs there.
The rung-10 review needed to tell "the whole-map grid is wrong on this map" from "this frame
was mid-step", and the refusal label cannot: both read "screen disagrees". So the decode is
split from its own cross-check, the disagreement is readable tile by tile, and the map survey
stands still for a while and counts how many of those frames decode.
On Pewter City, measured from the rung-10 checkpoint: standing still it decodes on 118 of 120
frames, and the frame the survey caught disagrees on three tiles by exactly one tile row in the
direction the fly was walking. The map is fine; the reading is refused while the fly is moving.
An independent review of 4f44894 accepted the audit with two required evidence
changes, neither of which needed a code change.
"Classification is not a topic-name heuristic" cited a lane-order test that
never varies a topic name. The row is now conforms-by-construction, naming the
four scheduler functions that read only the queue an item sits in, and
a_topic_named_like_a_notice_is_still_classified_as_topic_data publishes on
topics called call.failed, route.removed and subscription.closed and asserts
each arrives as a topic.message delivery with its payload intact.
"A latest subscriber never causes BACKPRESSURE" cited a bounded-mode test and
the ignored measurement. a_latest_subscriber_never_refuses_a_publication floods
one unconsumed latest slot with 100 publications of 60 KB, six times the
per-client bounded byte pool, and asserts none is refused, 98 coalesce, the
queue stays at one and the credit never comes back. That row also underwrites
the byte-budget deviation and the first contradiction.
Both tests run over both transports.
The coordinator resolved both contradictions in the spec rather than the code,
so bus-v1 carries them as dated amendments with one line of reason each: the
section 9 table row becomes "Per-client ordinary bounded queued envelope bytes"
with a new "Latest subscription slots | subscriptions x 64 KiB" row, and the
section 2 sketch drops the budget argument and shows the deadline at the caller.
With the amended wording the byte-budget row conforms, so the report's counts
are 178 / 9 / 1 fixed / 7, and the crate README's differences 4 and 8 say they
no longer differ.
CONTRACT-01 landed its crate, so the local stand-in module goes away and the domain
scalars, method payloads, their validation, the canonical digests and the trace format
all come from the contract. `src/types.rs` is a facade over that crate plus the few
things a coordinator needs that are not part of the type contract: a session-side
DomainError, the synthetic composition's schema and event-id derivations, and the
coordinator-local ControllerIntent, PortBinding and AgentOutcome that never cross the
bus.
Consequences worth naming:
- Payloads are read and written through DomainType::from_json / to_json instead of
serde derives, so a misspelled required field fails where the contract says it
should. serde, sha2 and ryu-js leave this crate's dependencies with them.
- The step-v1 section 8 trace is the contract's TransitionTrace, with behaviour and
operational metadata already separated; the dispatch-order comparison now runs over
the contract's own behaviour encoding.
- Two things the migration found. IN_PROGRESS is raised strictly before any mutation,
so its certainty is "none", not "unknown"; the local module had it wrong.
WorldObservation::validate_against checks the views a result carries but does not
require every declared view to be present, so requiring them is made explicit in the
coordinator's phase C check, where step-v1 puts it.
- The lost-Advance-result injection now waits for the worker to report the operation
before abandoning the call, so the case it injects really is a loss after dispatch
rather than a cancellation before it.
Gates: cargo test -p fly-session (61 tests, both transports), cargo clippy
--all-targets clean, and the runnable example produces the same behaviour trace over
both transports.
bus-conformance.md audits the flybus crate against bus-v1 sections 2 to 11, one
row per normative sentence: requirement, status, code location, the test that
proves it. 195 rows, 177 conforming, 10 deviating with the sentence that allows
each, 1 must-fix (the teardown starvation, fixed in this branch) and 7 not
implemented with an owner named. It also maps every BUS-01/02/03 acceptance
bullet to its test, reconciles all ten of the crate's own differences from the
draft, records the frame measurement with the reasons it is not a capacity
claim, and lists the two contradictions inside the draft it will not guess at:
the per-client queued byte budget against the latest-mode guarantee, and
section 2's call budget against section 6's client-owned deadline. Neither
changed any code.
bus-v1 gains section 12: dated amendments for the three error codes the
implementation needs and the draft left unnamed (CONFLICT, NO_TOPIC,
ARTIFACT_MISMATCH), one line of reason each, and for the one operation it adds
(rpc.responder.release), which is how bounded call correlation ends when a
handler keeps reply authority after releasing the request delivery. Section 9's
error list is inclusive, and section 4 already provides for a digest change.
The crate README points at the report, carries the new measurement summary in
place of the old numbers, and describes the two new test files; the design index
and the flybus index point at the report too.
The guide's first deliverable is one small program with a counter RPC, a pub/sub
observer and a frame artifact held past its message object. examples/demo.rs was
already that; its body moves into run(), which returns the lines it prints, so
tests/example_demo.rs can assert all seven of them. The counter now uses the
spec's own example.counter / Counter.Increment / {"amount": 1} and pins the
registration it discovered, and the example prints the router's root count while
the frame is held and after the last handle goes, so the lifetime it
demonstrates is visible rather than implied. cargo run -p flybus --example demo
prints the same lines.
tests/perf.rs reports what BUS-03 and bus-v1 section 11.7 actually ask for.
Allocate, the producer's copy into staging, the router's seal copy, publish
admission, the RPC round trip and a consumer's readback are six separate
percentile lines instead of one. The router gets its own two-thread runtime
whose threads carry a distinct name, and per-thread CPU is sampled from /proc by
that name, so router CPU is separable from the clients' in the same process.
Store bytes, outstanding roots and queue lengths are reported live as well as
peak.
One named test per implementation-guide bullet that the existing suites did not
already cover: a lost result that leaks no roots while the endpoint's own cache
still replays it, a retransmission of one domain body under a fresh call id, no
failover onto a replacement registration, a status RPC answered while another
handler is delayed, and a disconnect that reclaims logical ownership without
touching a file the consumer still has open. Each runs over both transports.
BUS-01 also asks for equivalent behaviour traces from the two transports, so
tests/common/mod.rs gains a Trace recorder whose record() panics on any
router-issued id: a trace can hold methods, payload fields, counts, sequences,
credits, cancel states and error codes, and nothing operational. One RPC
scenario and one pub/sub-with-artifacts scenario produce 29 events, identical in
memory and over a Unix socket. FLYBUS_TRACE=1 prints them.
The sixteen bullets the older suites already prove are cited in the conformance
report rather than duplicated here.
The write gate was one mutex the writer held across every synchronous transport
poll, and close_conn took that same mutex before reclaiming a connection's
owners. Under a transport that accepts a byte per poll the writer re-acquired it
hundreds of times while teardown queued behind it, so teardown could be starved
for a whole frame and the delivery completed just before its owner was
reclaimed. bus-v1 section 9 puts release and route-health control out of reach of
telemetry starvation; tests/sol_rereview_regressions.rs's poll-gate regression
failed 6 release runs out of 6 alone, and about one debug run in five.
The gate now separates "teardown has begun" from "a poll is in progress": a
mutex plus a condvar. begin_close sets closing once without waiting, then waits
for the poll already in progress and records whether it left a frame half
written. The writer brackets each poll with enter_poll (refused once closing)
and leave_poll(bytes) instead of holding a lock across it, so teardown's window
is one poll rather than a frame, and no byte follows it. close_conn no longer
holds the gate across reclamation. Every item is pub(crate): no public
signature changed.
The regression test no longer synchronises with a sleep. The shutdown thread
announces itself on a channel, and what follows is structural: teardown cannot
pass the gate until the held poll returns, which only release() allows. Its
delivery is 50 KB now, which a writer resuming a byte per poll cannot finish
inside the window, so the test observes the ordering instead of a coin toss and
asserts the two legal shapes of the stream: cut short with nothing appended, or
never begun with exactly the closing notices following.
packages/session-types mirrors the Rust crate: canonical JSON (RFC 8785), strict parsing,
canonical digests, readers with a validate step for every payload of ipc-v1, workers-v1,
state-media-v1 and publishing-v1, the trace comparator, seed derivation and the FLYSESS1
envelope. It loads the crate fixtures/ directory rather than keeping a copy.
43 tests with node test runner, as in packages/feed. Both languages assert the same recorded
canonical bytes and digests, so agreement is checked rather than assumed; the envelope test
goes further and requires the bytes this package writes to equal the fixture the Rust crate
wrote.
Also narrows the canonical number rule to a value-based one (finite, and within the exact
integer range when integral), because JSON.parse cannot tell 1e21 from the same digits
written out, and two implementations that disagree about one number agree about no digest.
The lockstep coordinator, its phase machine and a synthetic composition, as a new
workspace member. Every worker method is a Flybus RPC to an incarnation-pinned
service; the domain request ids and result caches of ipc-v1 section 5 sit in front of
every mutation.
- coordinator: the step-v1 section 3 transaction in order -- prepare every agent
concurrently, run one executor per agent in sorted agent-id order, assemble all port
controls in descriptor order, send exactly one Environment.Advance, evaluate the task
once, commit every agent concurrently, and move the committed boundary only when all
of them succeeded. Sequential, concurrent and reversed dispatch are selectable and
must agree.
- phase: the section 2 machine as an explicit edge table, Paused and Failed included,
with a committed-boundary predicate that gates pauses, captures and publication.
- clock: checked rational accumulation. A 60 Hz world with a 1 ms model tick runs
16, 17, 17 ticks and comes back to a remainder of exactly zero.
- dedup: operation keys, the cached reply with its own artifact holds, CONFLICT,
IN_PROGRESS, RESULT_EXPIRED, STALE_STEP, the lifecycle bound and Worker.Acknowledge.
- worker: the dispatch shell. Admission order and the result cache live here; the
endpoint mutex is the worker's simulation lock, so one mutation runs at a time while
Worker.Status answers from a separate cell.
- agent, environment, task: a fake model with an explicit seed and a mutation counter
the tests read, a fixed readout stub, a counter arena that seals one immutable frame
per boundary, a deterministic task and the identity executor.
- fly_session_types: the CONTRACT-01 domain types as a local stand-in, reconciled with
the shared crate in a following commit.
Tests run twice, over the in-memory transport and over a Unix socket, through the same
router: the SESSION-01 acceptance bullets and every section 4 failure-injection row
that applies to this slice.
fixtures/ is the shared contract corpus: accepted payloads with their canonical JSON and
digest, refused payloads with the rule each breaks, raw byte sequences that must not even
parse, recipes for the payloads too large to store, the U64 and double boundaries, rational
arithmetic vectors, the identity matrix, descriptor cross-checks, operation keys and bodies,
trace comparison variants, the schema set and its digest, seed vectors and one FLYSESS1
envelope. packages/session-types loads the same files.
Tests: 45 across nine files. Round trips preserve every field and reproduce the recorded
canonical bytes; duplicate keys, invalid UTF-8, NaN, trailing data, oversize typed values and
oversize envelopes fail; U64 and double boundaries reject on the right side; the four
identities never accept one another spellings; the accumulator produces 16, 17, 17 and a zero
remainder; the trace comparator ignores wall time, request ids, callIds and delivery ids and
notices every behaviour change; the contract digest survives reformatting and moves when a
field, bound, enum member or type changes.
Also: a crate README, and the update_fixtures example that regenerates the derived files.
The CONTRACT-01 type definitions, committed early so the session slice can build on
them while the fixtures and cross-language tests are still being written.
- scalar: Scope, RationalNs (reduced, positive denominator, 0/1 zero, checked
arithmetic and the step-v1 accumulator), SchemaRef, TypedValue with its 32-KiB
canonical-JSON cap, and the four identities that must not be confused (bus callId,
domain requestId, artifact identity, delivery/hold owner token) as distinct types.
Id, U64 and Digest call into flybus::wire instead of forking the encodings.
- canonical: RFC 8785 canonical JSON, SHA-256 digests, the operation key and the
canonical body rules of ipc-v1 section 5, with bus identities refused in a body.
- rpc, workers, media, publishing: the payloads of ipc-v1, workers-v1, state-media-v1
and publishing-v1, each with a validate step for the documented ranges, uniqueness,
ordering and bounds.
- schema: the canonical schema set, whose digest is contractDigest, declared as data
so source formatting cannot change it.
- trace: the step-v1 section 8 record, behaviour separated from operational metadata.
- seed, checkpoint: the seed derivation and FLYSESS1 envelope layout.
The first run of the new ROM test failed on YES 134, and every one past
the sixth was in Pewter City or the gym the fly had walked to -- which is
the fly playing the game, not the ring. Row 41 is about the presses spent
in the room, so the harness records starts by name while the fly is still
on the map it resumed on: 6 macros there, YES 2.
Where the fly was standing, the conversation press by press, why TALK
retired nothing, the four rows this branch closes and the one it leaves,
the ROM-gated run, and the hunt: 1 distinct tile to 437, 73/73 flagged
windows to 54/73, YES in a text box on map 0x3a 1424 to 4, dialog frames
69,469 to 5,492.
The 54 that still flag are a different trap on ground the before arm
never reached -- GO FRONTIER runs and a GO OBJECTIVE/BACK/GO FRONTIER
cycle in Pewter City -- and that is the next brief.
What was live, what the survey read, and what the three candidate
readings in the brief turned out to be: not the prompt, not HEAL, but the
dialog pad dealt unconditionally with TALK to get back into it. The
scene-by-scene table splits the dialog row in two and the pad-empty sweep
gains the reopen ledger's own residual. macros-wram.md narrows its "no
observable for a choice" claim rather than withdrawing it.
Unit: HEAL is off a full party's pad, including the rung-10 party's own
numbers, which is the assertion that the loop was never the heal's; TALK
is off a rested nurse's pad and on a hurt one's, and an ordinary
villager is unaffected; her prompt deals one answer and a plain box still
deals three; a readable prompt that is not hers deals both answers and no
NEXT; an answer whose prompt reopens is excluded and one that settled the
box is not; a completed heal and a declined prompt both retire her.
ROM-gated from the live checkpoint (FLY_CENTER_CHECKPOINT): the fly
leaves map 0x3a on a bounded number of macros, YES starts stay under
five, NEXT is on no pad while a prompt is readable, and TALK is on no pad
at a rested nurse. The run also counts dialog and prompt frames, which is
what makes the forty-six-to-one ratio visible.
TALK's precondition reaches over a counter because the cartridge does;
its talked-ledger entry was read one tile ahead. So TALK was bound at the
counter and recorded nothing, 107 times, and the nurse was never retired.
The entry now comes from the same reading the precondition makes.
A completed HEAL writes her into the talked ledger: the macro has had the
conversation with its own presses, and the reached window would otherwise
expire in ten brain minutes and offer the ring again. A declined prompt
writes it too -- 12.4 inverted for one person, because the pad only ever
offers NO at her prompt when the party is already full.
And the general rule: a YES or NO whose prompt is up again on the same
map and tile within one hold did nothing, so that answer joins the
blocked ledger for its window.
On a box that is a readable YES/NO prompt, NEXT is YES under another
name -- an A press at a two-option menu confirms the option the cursor is
on -- so it is off that pad and the pad is the box's two answers. That is
12.10's pair rule in a dialog.
At the nurse's own prompt only the answer that changes something is
bound: YES with a hurt or statused party, NO with a full one, read from
the same byte HEAL's precondition has read since section 13.
And TALK is off the pad at a nurse the party has no use for. Her
conversation is a service whose need the cartridge publishes, and a ring
of text that ends where it began is section 12.2's trap. Nobody else is
narrowed.
An answer the reopened-prompt ledger excludes leaves the pad, and the
exclusion never empties one: a box nothing can answer cannot be left.
Row 41 is the Pokemon Center nurse: 2,142 YES starts on one tile of map
0x3a with a party at 70/70. The survey that names it is a new probe mode
(FLY_PROBE_CATCH=nurse) that leaves the box with B and then pulses A,
printing every state the conversation passes through with the two-option
menu's own geometry beside it. It is a ring of forty-six presses and the
box is a choice on exactly one of them.
So the reading: wFontLoaded plus the border DisplayTwoOptionMenu draws,
plus the cursor it parks inside it. Both halves are needed -- the cursor
bytes survive the box closing, so all forty-six frames carry the
geometry. It claims that box and not "a choice is open" in general.
TargetKey gains Answer { at, yes } for the reopened-prompt exclusion.