Run the verifying backfill: every blob published by emitter 1 is still unreadable by a client #88
Notifications
Due Date
No due date set.
Blocks
#75 Acceptance gate: a real NWN client syncs from an assembled manifest on the Bunny zone
ShadowsOverWestgate/sow-tools
Reference: ShadowsOverWestgate/sow-tools#88
Reference in New Issue
Block a user
#86 fixed the encoder and #85 built the repair path (PR #87). Neither has been applied. The mechanism exists; nothing has invoked it.
Every blob under 256 bytes already in the
sow-synczone was written by emitter version 1 and still omits its zstdFrame_Content_Size.emitskips an object that already exists on the strength of a 1-byte range GET, so re-running the ordinary backfill changes nothing at all — it skips exactly the blobs that need replacing. Roughly 6% of blobs are affected, and one is enough to stop a sync dead, so the live manifest is still unsyncable until this runs.What to do
crucible nwsync emit --verify. That reads each existing blob back, hashes it against its own name, asserts the frame declares a content size, and re-uploads the ones that fail. It costs a full GET per existing blob, which is why it is not the default.emitter_version: 1andassemblenow refuses to merge them, so this is not optional — and the merged manifest sha1 will change, which means the channel catalog andNWN_NWSYNCHASHmove with it.crucible nwsync verify <new-manifest-sha1>— a full sweep, not a sample, before declaring anything fixed.Watch for
zstd -dcas proof of anything. It streams a frame with no declared size happily; that is precisely how this defect survived an audit.Blocks #75. Refs #85, #86, sow-platform#79.
Two corrections to the plan above, before anyone runs it.
Step 2 is not needed, and the manifest sha1 does not move. The merged manifest hashes NSYM bytes, and an NSYM entry is
(uncompressed sha1, uncompressed size, resref, restype)—emitResourcesfills it fromsha1.Sum(payload)beforecompressBlobis ever called, so blob framing appears nowhere in that chain. Re-emitting under emitter 2 rewrites every blob's bytes and leaves every index's bytes identical, soAssemblemerges to the same sha1. Nothing re-pins: the channel catalog,releases/module/<tag>/nwsync.jsonandNWN_NWSYNCHASHall stay as they are, and a release that already has a manifest needs no re-assemble.What the backfill does change is the per-artifact sidecars,
emitter_version1 to 2. That matters for the next release rather than this one —Assemblerefuses to merge a v1 index, so until the backfill has run, no new module release can assemble at all. The staleemitter_version: 1in the already-published merged sidecar is inert; assemble only checks the indexes it reads.Step 3 runs after the purge, not before it.
verifyreads the pull zone on purpose, so between a repair and a purge it reports whatever the PoP that answered happens to hold. #89 is now decided: purge the whole zone, one call. Confirmed while there — the zone does not negative-cache. A missing key answers 404 withcache-control: no-cacheandcdn-cache: MISS, still MISS on an immediate retry.Mechanism, now open for review. An ordinary backfill would have skipped exactly the blobs this exists to replace, so both owning repos take
NWSYNC_VERIFYand expose it as averifyinput onbackfill-nwsync:Order to run, once those merge: topdata backfill with verify (minutes) -> haks backfill with verify (hours) -> purge pull zone 6046370 ->
crucible nwsync verify <sha1>, full sweep, no--sample.Run, and done
1. Re-emit with
--verify. topdata first (minutes), then haks (hours). 2,603 blobs rewritten at the origin under emitter 2.2. Re-assemble — not needed. The 01:05 correction held: the merged manifest hashes NSYM bytes, so re-emitting changed only blob bytes and the manifest sha1 did not move. The channel catalog,
releases/module/<tag>/nwsync.jsonandNWN_NWSYNCHASHall stayed as they were. Nothing was re-pinned.3. Purge, then verify — and the purge got much smaller. #90's whole-zone purge turned out to be unnecessary.
verifyreads the edge, so the run straight after the repair names the stale keys itself: 8 blobs, all of them ones the failed player sync had pulled ninety minutes earlier. The edge only caches what someone fetched, so purging the whole zone would have cooled 69,169 objects to fix 8. Purged those eight. Corrections landed in #91 here and sow-platform#139 in the runbook.Full sweep afterwards, no
--sample:A retail client then synced to completion and entered the module. Closing; the gate itself is #75.