macros.md gains section 12.17; macros-wram.md section 9 gains the frame-by-frame trace of a step,
the three readings that come out of it and the one byte that tracks a step exactly and is recorded
unused; macros-traps.md closes rows 54 and 54b, strikes the two residuals they worked, and prints
both checkpoints' before and after whole -- including the arm where the ethos check's "fewer
flagged windows, more distinct tiles" does not hold, and why.
session_over_one_router asserted that a latest subscriber must drop
snapshots. bus-v1 section 7 says a latest subscription replaces an
undelivered value; it lets a consumer miss values, it does not oblige it
to. Under contention the publisher was slow enough that the renderer kept
up, saw all twenty snapshots and the test failed on conforming behaviour:
16 of 40 runs beside four busy loops, and 9 of 20 whole-crate runs.
The renderer is now held until the publisher's completion is observed
rather than until a timer expires, so the coalescing is forced instead of
raced for: the subscription keeps the one delivery in flight and one
replaceable queued value, and the renderer receives snapshots 1 and 20 of
20. The assertions are the guarantees that hold -- what arrives is in
publication order, the last value is the latest published, the stalled
spectator never refuses a publication or drops out of the fan-out, and
every snapshot the renderer missed is counted as a replacement to the
publisher at admission and to the renderer on delivery, so nothing is
lost silently.
Three more tests in the crate asserted the same kind of race:
- latest_replay_is_ordered_ahead_of_a_racing_publish demanded the
non-coalesced outcome of a race section 7 allows either way ("bounded
mode preserves that order, while latest mode may coalesce it"). It now
puts one racing publication to a bounded and a latest subscription at
once: bounded must deliver the replay and then the publication, and the
latest branch is chosen by that publication's own replaced count.
- collection_waits_for_every_retained_owner, and the two disconnect
cleanup tests beside it, read the store directory for the unlink that
follows the registry update outside the router lock. They use
settle_files, like every other unlink check in the suite.
- The demo example printed a root count taken before the producer's own
release had reached the router, so the line the guide quotes was a
race. It waits for the release, the same way it already waits for
collection; the printed output is unchanged.
Nothing under flybus/src is touched: no routing defect was found. The
conformance rows for the credit/queue split, the replaced count, the
replay ordering and the latest spectator that cannot refuse a publication
now cite what each rewritten test actually varies.
Keep-both everywhere the two slices met. lib.rs takes both module sets.
AgentConfig keeps worker_threads and the sensor log; EnvironmentConfig
keeps worker_threads, the render delay and the render counter.
coordinator.rs keeps the two-stage resolution and its blame() beside the
media split of the Advance reply's attachments, and its imports take both.
harness.rs is main's launcher-based file with this slice's media
instrumentation re-applied on top.
The media instrumentation is shared memory, so it now follows the
launcher's own rule for the progress counter: sensor_log and renders
return None for a participant with a process of its own rather than a
misleading zero. The launcher carries the sensor log and the render
counter to a participant in this process and the render delay and the four
media faults on the command line to one in another process, where the
child builds its own log and counter.
The media path itself is mode-agnostic and is now tested as such: one
image per boundary, forwarded to every agent and published once, asserted
over the bus in all three execution modes, with the shared-memory
assertions made only where those participants live.
Review fixes for SESSION-02.
An expired caller deadline was becoming a failed epoch without the
ipc-v1 section 6 resolution. That procedure existed and was correct and
had exactly one caller, a test injection, so the deadline this slice
introduced bypassed it and a merely slow participant lost its epoch.
Deadlines is now the two-stage shape section 6 describes -- a probe,
then a bounded resolve budget and attempt count -- call_owned returns a
typed CallOutcome so an expiry is distinguishable from a refusal, and
Prepare, Commit, Advance and the lifecycle calls all query the same
request id against the same incarnation before the epoch can fail. This
is also step-v1 section 7's Advance row, which was imperative about it.
The coordinator peak-RSS column was measuring the measuring process.
VmHWM never falls and every row shared one process, so the column was
cumulative and the mode ranking reversed when the rows were reordered.
Each row now runs in a measure-row child of its own. The corrected
numbers say the opposite of what the first report claimed: the
coordinator's own peak is roughly flat across the modes and lowest in
process mode, and the cost of the split is the children.
workers-v1 section 2 bounded Agent.Initialize's workerThreads by
"within launcher allocation" and named no wire for it. Dated amendment:
HelloResult.limits gains workerThreads, the worker reports what its
launcher gave it, and the launcher refuses one that disagrees. The
schema set, the shared fixtures and the TypeScript package move
together; contractDigest changes, which ipc-v1 section 4 provides for.
Also: the stale-epoch row now reaches the stale-epoch path against a
live agent process and asserts exact codes on both halves; the
router-restart row asserts the handle drop it claimed; frames are
counted from the behaviour trace instead of calculated; the README says
which suites run over which transports; bootstrap is fence-guarded; the
shutdown reason is an Id rather than a silent fallback; and
agent_mutations returns None rather than zero where the counter lives
in another process.
Review round two.
A restored timeline refuses a declared stream with no recorded sample
position instead of resuming it at zero, which would have restarted the
episode's audio clock silently.
A declared stream that produces no chunk for a transition now fails the
step. The contract does not say a chunk must exist; this slice requires
one, because a silently missing chunk cannot be told from a lost one.
Boundary 0 is exempt: no interval precedes it.
The fresh-epoch discontinuity refusal is dropped rather than written into
the amendment. Only the restore direction is stated, and sections 6 and 7
both have a fresh timeline publishing a discontinuity after a recovery or
a reset, so refusing the flag at an origin contradicted them. The dated
amendment now says the requirement is one-directional.
A snapshot with an unreadable chunk, or one whose handle is not attached,
is now unreadable as a whole rather than quietly carrying less audio than
was published. ViewPipeline::is_bootstrap_repeat is removed.
New tests: a missing chunk fails the step, restored timelines need every
declared stream's position, and a 7 Hz world's seven chunks sum to exactly
one second of 48 kHz samples. The bus-conformance reconnect row also cites
the test that actually replaces an incarnation.
Two readings of the section that are now checked rather than assumed: the
bootstrap window is exactly the boundaries where max(0, boundary - delay)
is zero and its repeated O[0] is the same artifact, and a chunk that
continues the previous one exactly cannot claim a discontinuity, which is
what keeps the restore rule checkable instead of advisory.
caller_disconnect_cleanup_works_before_and_after_consumption failed 37 times
in 240 runs under load: the reply raced the router's own teardown. op_reply
reports routed:false only once disconnect has marked the call detached, and
the router runs that when its connection task reads EOF, while Client::close
waits for this client's reader only. The reply could therefore reach a
connection that was still closing and be routed. Nothing escaped -- teardown
releases those roots -- but the flag was read one step early.
The test now settles on the caller's connection being gone before asserting
the section 6 sentence, which is the poll the rest of the file already uses.
360 runs after the fix, 0 failures.
bus-conformance.md records the mechanism, the counts and the two other
intermittent failures seen in the same sweep, which are left to the bus slice.
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.
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.
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 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.
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.
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.
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.
The rung-10 loop whole: which building the fly was in, why every candidate list
on that map emptied, the byte dump that named the battle menu's swapped entries,
the ROM-gated before and after, and the two arms of the trap hunt being identical
because a restore clears the ledgers the loop was built out of.
Section 13.1's tables follow: MENU off both overworld rows and off the narrow
counter row, the move list's conditional BACK, the start menu reachable only by
the raw START button, and two new rows in the pad-empty audit - the room whose
one door the ledger rests, and the map with no way out at all, which is the one
empty pad left and is asserted rather than covered.
The contract: no pair of buttons on any battle pad may undo each other with
nothing else changing, which is section 12.2's rule stated at the pad instead
of at one macro. Section 13.1's table takes NEXT off the own-turn main menu,
gives the bag a row of its own on the own turn, and records MOVE 1 as the
backstop that row keeps.
The audit carries the reproduction -- 71,673 frames in one battle, 73 of 73
windows flagged, BACK 739 starts on the move list against NEXT 739 on the main
menu -- the ROM-gated run before and after, the trap hunt before and after
(1 distinct tile to 260, 73 of 73 flagged windows to 68 of 73, 0 overworld
frames to 20,394), and the residuals: NEXT on a move list whose cursor the seam
cannot place is now the largest source of it, which is row 30b and wants a WRAM
reading rather than a pad change.
286 distinct tiles become 489 over twenty brain minutes from the rung-9
checkpoint, the median flagged window holds 55 tiles instead of 16, GO FRONTIER
runs 64 walks worth up to twelve net tiles instead of four worth one, and one
walk spends its cap where six did.
The cost is named rather than buried: flagged windows go 61 to 70 and windows
under four tiles 5 to 14, and every one of those is a window spent inside a
battle -- a fly that covers more ground walks into more grass, 48,756 battle
frames becoming 50,413 with the longest battle 9,549 frames becoming 13,411.
This is the first measurement in that file where more ground and fewer flags do
not both hold, and it is stated as such.
Section 15 is the contract for map-aware walks: what is decoded, the one ROM
read and why it is a read of the cartridge image, what the window fallback is
for and how it says so, and the proof. macros-wram.md section 9 is the bytes --
four addresses with their encodings, the bank-aware read on the seam, the corner
the cartridge settled, the two gates against a plausible-but-wrong decode, and
the survey of Pallet Town and Viridian Forest.
The rung-9 forest review: what was live, the mechanism of all three
observations, the audit rows, and the trap hunt before and after from the
release container's own checkpoint.
The hunt is brain-driven rather than stubbed, which is legitimate here and
was not for sections 13 and 14: this branch adds no macro type, so no
population is re-dealt and the two arms differ in the macro code alone.
Distinct tiles 216 to 286, windows flagged 70 of 73 to 61, windows under
four tiles 21 to 5, BACK starts with no list open 175 to 0, MOVE n starts
36 to 68.
Four residuals are named rather than buried: BACK is still 359 starts of
830 over open lists, which is row 34's contract; a NEXT/BACK two-cycle
closes the run inside one battle, from a move list whose cursor the seam
cannot place on its opening frames; a window spent in a battle is flagged
by the tile rule whatever happens in it; and the THROW BALL precondition
is inert in this run because the save carries a party of one.
Row 41 is the loop behind this one: in the before arm the fly answered the
nurse's box YES 474 times on one tile of a Pokemon Center for the last
eight brain minutes of the run. The after arm never enters it, so it is
neither reproduced nor fixed here. It is the next thing to measure.