You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
writeSettings() in manager.ts does a classic read-modify-write on settings.json without atomic replace. Two concurrent failproofai policies --install runs (common in CI matrix jobs that install in parallel across shards) can clobber each other. token-store.ts already does this correctly with a temp-file + rename — applying the same pattern here makes installation bulletproof.
In CI environments (GitHub Actions matrix runs, monorepo bootstrap scripts) it's normal for two failproofai policies --install invocations to run concurrently against the same~/.claude/settings.json. Today:
Process A reads settings v1
Process B reads settings v1
Process A writes v1 + hookA
Process B writes v1 + hookB ← clobbers A's write
Atomic replace using writeFile(tmp) + rename(tmp, final) guarantees that the last write wins cleanly instead of interleaving.
Flow
BEFORE AFTER
───────────── ─────────────
read settings.json writeFile settings.json.tmp
mutate in memory renameSync settings.json.tmp → settings.json
write settings.json (POSIX rename is atomic)
(last writer clobbers)
Activity