v0.43.2
What's new
GuildBankLedger
v0.43.2 (2026-10-03)
Full Changelog Previous Releases
- Merge pull request #353 from RussellFeinstein/fix/cleanup-reorder-under-walk
Stop the cleanup moving records under a serve's walk, and read the records where a reset overtook the map (v0.43.2) - Apply the second #342 review: ask the cache on every overtaken tick, and count the rotation line the same way
The first stage asked the cache only on the tick its restarts ran out.
Once it had given up on a walk it never looked again, so a map warmed a
tick later was ignored and the serve offered buckets from a walk that
read an id the requester no longer has. It now asks the cache whenever
there is no walk or the walk is overtaken, every tick. That also drops
the second lookup the same tick used to make, since a restart starts its
new walk directly.
The demote decision read the collected records for every key of the
last tranche once a reset had landed. A key not offered this time has no
group, so it read as nothing and stopped counting as unchanged, and the
rotation line read a reset as rotation demoting less. Such a key keeps
the map's reading. It is not a candidate either way, so no selection
changes.
Two comments corrected. The one in DeduplicateAllGuilds said the cleanup
resets at the end of its pass; it resets at the write-back. The tranche
comment now says why stage 7 hashes the stripped copies while stage 4
reads the stored records. The sync notes follow, and record the residue
on the time-filtered path.
Co-Authored-By: Claude Code noreply@anthropic.com - Pin two findings from the second #342 review (red)
Two cases fail, each on its last assertion after every fixture check:- Once the restarts are used up, the first stage stops looking at the
cache for good. A cache warmed a tick later is ignored, and the serve
offers a bucket from a walk that read an id the requester no longer
has. - After an unrelated reset, the rotation line stops counting a bucket of
the last tranche that was not offered this time, so the same unchanged
buckets read as fewer demoted.
Co-Authored-By: Claude Code noreply@anthropic.com
- Once the restarts are used up, the first stage stops looking at the
- Stamp v0.43.2
Co-Authored-By: Claude Code noreply@anthropic.com - Bring the sync notes in line with the review's changes
The sliced-serving note now says what the review changed: the cache is
taken over an overtaken walk even with no restarts left, mapOvertaken is
the one test the demote decision and the tranche share and holds only on
the bucket path, the tranche line names a reset and not an id, the
cleanup resets at its write-back, and a pass that removes records
mid-collect can leave a removed one in the send. CLAUDE.md's Fingerprint
entry follows.
Co-Authored-By: Claude Code noreply@anthropic.com - Pin that a reset alone does not switch the rotation off
The case for the demote decision proved a rewritten bucket is not
demoted. It could not tell a correct reading of the collected records
from one that never matched anything, since both demote nothing. This
case resets without changing a record and expects the bucket demoted.
Co-Authored-By: Claude Code noreply@anthropic.com - Apply the #342 review: reset at the write, and read the records wherever the map is read
Five changes, one per finding.
The cleanup resets where it writes an array back, not at the end of the
pass. The money pass and the id rebuild after it can raise on a corrupt
record, and the array has moved by then whether or not the pass gets
that far. The reset at the end went, since every array the pass removed
from has already reset and nothing in between reads either cache.
mapOvertaken is the one test for "the map can no longer vouch for a
bucket", and it holds only on the bucket path. On the time-filtered path
a session carries part of a bucket, so the hash of what was sent is not
the bucket's, and the map stays the source there whatever has moved.
The demote decision uses it as well. It read the map a stage before the
commit, so a bucket rewritten during the collect was put to the back as
unchanged. It now reads the collected records when the map is overtaken.
An empty tranche no longer writes the line about its source, and the
line says the hash cache was reset, which is what the code knows. It
does not know that an id moved.
Out of restarts, the first stage takes the cache when something has
warmed it since the reset, and goes ahead on the overtaken walk only
when it has not. Taking the cache is not counted as a restart.
The comment above the stages says plainly that the reset does not reach
the collect, and what a pass that removes records mid-collect does.
Co-Authored-By: Claude Code noreply@anthropic.com - Pin five findings from the #342 code review (red)
Five cases fail, each on its own assertion:- The cleanup resets at the end of the pass, so a raise after it has
written an array back (a corrupt record in the money pass) leaves the
generation where it was and a walk in flight is never told. - On the time-filtered path a reset after the walk makes the last stage
record the hash of the records sent, which is part of a bucket there,
so that bucket could never be demoted. - An empty diff overtaken by a reset still writes the line about the
tranche's source, with no tranche to describe. - The demote decision a stage earlier reads the same map, so a bucket
rewritten during the collect is put to the back as unchanged. - Out of restarts, the first stage goes ahead on the overtaken walk even
when a current map is sitting in the cache.
The case for a walk the serve went ahead on now asks by bucket, with one
bucket to send, since the sent records can only stand in for the map
where whole buckets go out. It passes before and after. The per-array
cleanup case's fixture moved into a helper the new cleanup case shares,
and its assertions are unchanged.
Co-Authored-By: Claude Code noreply@anthropic.com
- The cleanup resets at the end of the pass, so a raise after it has
- Record what a reset now does to a serve, and that the cleanup keeps its order
The sliced-serving note in the sync rules said the serve still diffed on
a map a reset had overtaken, and that a cleanup removing nothing still
moved the records. Both are fixed, so the note now says what stage 1 and
stage 7 do with the generation, why the tranche takes the sent records
only when something moved, and why the cleanup writes an array back only
when it removed from it. The measurements behind each are in the note:
the walk is 13 of a preparation's 39 yields at 19,799 records, and a
cleanup that removed nothing moved 4,336 of 14,057 item records.
The tranche note names the second source of its hash. CLAUDE.md's
Fingerprint entry names the two new accessors and the rule that a pass
moving records has to reset. The cleanup's own comment says it leaves an
untouched array in place. The changelog gets its two entries.
Co-Authored-By: Claude Code noreply@anthropic.com - Pin three things the mutation pass let through
Thirteen mutations of the #342 fix ran against the whole suite. Eight
were killed by the new cases on an assertion. Three survived, each a
missing test:- Dropping the guard that writes the overtaken line once. The bounded
case now seeds two ticks of walking past the budget, so the walk the
serve goes ahead on is reset under again, and counts one line. - A map taken from a warm cache carrying no generation, which made the
last stage record the tranche from the sent records on every such
preparation. The time-filtered pin now runs both ways a preparation
comes by its map. - A walked map taking the generation at its handoff instead of at its
start, which let a walk the serve went ahead on vouch for the tranche.
A new case stops resetting once the restarts are used up and expects
the tranche to come from the sent records.
The other two died on a nil instead of on an assertion, because the
restart count was created on first use. It starts at zero with the rest
of the preparation's counters now, which changes no behaviour, and both
then fail a case on its assertion.
Co-Authored-By: Claude Code noreply@anthropic.com
- Dropping the guard that writes the overtaken line once. The bounded
- Leave the arrays alone when the cleanup removes nothing, and walk again after a reset
Three changes for #342, one per defect.
CleanupWithEventCounts wrote each storage array back gathered by prefix
whether or not it had removed anything. It now writes an array back only
when it took something out of it. On the saved store a cleanup that
removed nothing moved 4,336 of 14,057 item records, because table.sort is
not stable and 8,212 records tie on prefix and timestamp. A serve's bucket
walk holding a cursor across that read one record twice and never reached
another, and since nothing reset, its stamp put that map in the cache.
The serve's first stage drops a walk that a hash cache reset overtook and
starts again, taking the cache if something has warmed it. The check sits
where a tick picks the walk up, since nothing moves the generation inside
a tick. Three restarts at most, then the serve goes ahead on the walk it
has and says so in the log. The Prep complete line names the restarts
when there were any.
The last stage records the tranche from the ids of the records it sent
when a reset has landed since the bucket map was taken. The walk is a
third of a preparation, so most resets land after it, and the map's hash
for a rewritten bucket then matched nothing a later walk produced: the
next serve to that peer read the bucket as moved and sent it again. A
preparation nothing overtook stamps from the map as before.
BucketHashesOfRecords is the walk ComputeBucketHashes already did, over
arrays handed in, so the map and the tranche cannot disagree about which
records count or which bucket each falls in.
Co-Authored-By: Claude Code noreply@anthropic.com - Pin the bucket walk against a cleanup and a reset (red)
Eight cases fail, each on its own assertion, for #342:- A cleanup that removes nothing moves records to new positions, in the
item array and the money array (two cases in the dedup spec). - A sliced scan with that cleanup in the middle stamps a map with one
bucket missing and another cancelled to zero. - The same through the serve chain: a receive with nothing new ends in
the middle of the first stage's walk, and the cached map no longer
matches the records. - A walk a reset overtook is still handed to the serve, so a requester
that already holds the rewritten id is offered its bucket anyway. - Nothing says how often a walk started again, or that a serve went
ahead on an overtaken one. - The tranche keeps the hash from before the rewrite, whether the reset
lands during the walk or after it has handed its map on.
Three cases pass today and are pins for the fix: a cleanup with no scan
in flight leaves a warm cache warm, a clean preparation's line reads as
it always has, and a preparation nothing overtook records the bucket's
own hash on the time-filtered path.
Helpers.fireZeroDelayRound is the single round drainZeroDelayTimers
already repeated, taken out so a spec can act between two hops.
Co-Authored-By: Claude Code noreply@anthropic.com
- A cleanup that removes nothing moves records to new positions, in the
- Merge pull request #352 from RussellFeinstein/chore/bank-log-names-verdict
Record what the bank log gives for a name, and correct the #332 account - Record what the bank log gives for a name, and correct the #332 account
The bank log gives a member on another realm than the viewer as
Name-Realm and a member on the viewer's own realm bare. Measured from
the maintainer's stored data, it lands as a Critical WoW API Fact, and
the ResolvePlayerName note says what follows: a bare name from the log
is a same-realm member, and the roster lookup ahead of the fallback can
only confirm that or, for a same-named member elsewhere, get it wrong
(#350).
The #332 subsection no longer says the v0.13.0 migration stamped
Nesingwary. The bare names were other scanners' own-realm members, the
stamps fall on five realms of 24, and a store at the default never ran
that migration. Section 7 records that the default trap it warns about
already fired at each of the six raises from schema 2 to 8, with the
two proofs on the maintainer's store (#351).
Co-Authored-By: Claude Code noreply@anthropic.com
This mod has no additional files