What happened
On macOS, the ~/.local/share/xcb volume was remounted/recreated (routine sleep/wake or system remount). File contents, inodes, and ctimes were identical; only st_dev changed (e.g. 16777233 → 16777231).
The committed reauth.json journal records FilePins (digest, device, inode, ctime) for device.json and account.json. FilePin.check compares all fields, so after the remount every Snapshot::load fails with Error::Conflict("relay sign-in state changed; credentials were not replaced").
Impact
xcb link --reauth fails immediately (before the email prompt) on completed(), resume(), and prepare() — all call Snapshot::load.
custody::permit_refresh propagates the same error, so the supervisor's routine session refresh fails; the session JWT expired and the relay lane went unauthenticated until the journal was removed.
Observed on xcb 0.10.5 with journal phase committed (the reauth had already succeeded — operation 01a0e885-b086-77a2-bf6a-52676a76bda2).
Recovery used
The completed journal was moved out of cloud/ (preserved in evidence); Snapshot::load → None → permit_refresh passed and the next supervisor refresh immediately wrote a new token with the committed session identity.
Possible directions
Journal::check could skip original.check_keys/check_session when phase == Committed — a committed operation's preconditions are spent; relay_state re-validates identity/result from live data anyway.
FilePin.check could tolerate dev drift when digest + inode + ctime all match — but that weakens the "identical bytes transplanted to another filesystem" guarantee, so it's a design call.
Snapshot::load could distinguish "journal exists but failed integrity" from "no journal" so refresh isn't poisoned by a finished record.
Repro path: xcb link --reauth to completion → remount the state volume (or restore the cloud dir onto a new filesystem preserving inode/ctime) → run xcb link --reauth or wait for session refresh.
Generated with Devin
What happened
On macOS, the
~/.local/share/xcbvolume was remounted/recreated (routine sleep/wake or system remount). File contents, inodes, and ctimes were identical; onlyst_devchanged (e.g.16777233→16777231).The committed
reauth.jsonjournal recordsFilePins (digest,device,inode,ctime) fordevice.jsonandaccount.json.FilePin.checkcompares all fields, so after the remount everySnapshot::loadfails withError::Conflict("relay sign-in state changed; credentials were not replaced").Impact
xcb link --reauthfails immediately (before the email prompt) oncompleted(),resume(), andprepare()— all callSnapshot::load.custody::permit_refreshpropagates the same error, so the supervisor's routine session refresh fails; the session JWT expired and the relay lane went unauthenticated until the journal was removed.Observed on xcb 0.10.5 with journal phase
committed(the reauth had already succeeded — operation01a0e885-b086-77a2-bf6a-52676a76bda2).Recovery used
The completed journal was moved out of
cloud/(preserved in evidence);Snapshot::load→None→permit_refreshpassed and the next supervisor refresh immediately wrote a new token with the committed session identity.Possible directions
Journal::checkcould skiporiginal.check_keys/check_sessionwhenphase == Committed— a committed operation's preconditions are spent;relay_statere-validates identity/result from live data anyway.FilePin.checkcould toleratedevdrift whendigest + inode + ctimeall match — but that weakens the "identical bytes transplanted to another filesystem" guarantee, so it's a design call.Snapshot::loadcould distinguish "journal exists but failed integrity" from "no journal" so refresh isn't poisoned by a finished record.Repro path:
xcb link --reauthto completion → remount the state volume (or restore the cloud dir onto a new filesystem preserving inode/ctime) → runxcb link --reauthor wait for session refresh.Generated with Devin