fix(anthropic-subscription): repair a damaged seat salt and store it without hard links
Merged
CO
2d ago+93+93+01234567890123456789-7-7-0123456789
Part of code-yeongyu/oh-my-openagent#10304. Follow-up to #3947 (its two review LOWs).
What
anthropic-subscription/seat-digest.ts, the per-install salt behind the seat digests in continuity logs:
- A salt file of the wrong length is replaced. Before, a truncated or foreign file sent every later process to the process-only fallback forever, so digests stopped matching across restarts on that install. Now the file is removed (only if it is still the file that was read, by inode) and recreated through the same link-into-place path.
- Filesystems without hard links store the salt. When
linkSyncfails with EPERM, ENOTSUP or ENOSYS (FAT/exFAT, some network and FUSE mounts, sandboxes), the salt is written with an exclusive create instead of giving up. Failing to store it still never fails a turn, and the digest stays salted.
Tests (test/anthropic-subscription-seat-digest.test.ts, 7/7)
- "replaces a salt file of the wrong length": RED on main (the file stays 5 bytes), GREEN here.
- "stores the salt on a filesystem without hard links" (a Node child with
linkSyncthrowing EPERM): RED before the fallback, GREEN here. - The 12-process convergence test now also asserts that no staged
seat-digest-salt.*files are left behind (review nit).
tsc --noEmit passes; the changelog gate passes. Thanks to 욜로개발조아 for the original measured report.
Summary by cubic
Repairs a damaged seat-digest salt file so continuity digests keep matching across restarts, and stores the salt even on filesystems without hard links.
- A salt file of the wrong length is now removed (only if it is still the file that was read, by inode) and recreated through the same link-into-place path, instead of being ignored in favour of a process-only salt on every launch.
- When
linkSyncfails with EPERM, ENOTSUP, or ENOSYS (FAT/exFAT, some network and FUSE mounts, sandboxes), the salt is written with an exclusive create instead of giving up. - Both paths can diverge under concurrent first starts; since digests are diagnostics, that costs a mismatch, never secrecy.
- Failing to store the salt still never fails a turn, and the digest stays salted.
- Adds tests for both cases and asserts no staged
seat-digest-salt.*files are left behind.