mirror of
https://github.com/Jeuners/ECC.git
synced 2026-09-09 15:02:30 +02:00
`writeBridgeAtomic` wrote to a fixed `${target}.tmp` path before
calling `renameSync`. When two processes write to the same session
bridge concurrently (e.g. PostToolUse `ecc-metrics-bridge` + the
background `ecc-statusline`, both calling `writeBridgeAtomic(sessionId, ...)`),
the canonical atomic-rename race fires:
1. Process A: writeFileSync(target.tmp, JSON_A) — tmp file exists.
2. Process B: writeFileSync(target.tmp, JSON_B) — tmp file overwritten.
3. Process A: renameSync(target.tmp, target) — succeeds; target = JSON_B
(A's payload silently corrupted en-route).
4. Process B: renameSync(target.tmp, target) — throws ENOENT (the
rename consumed the file).
Every caller in the repo wraps `writeBridgeAtomic` in `try {} catch {}`,
so the ENOENT exception is swallowed and the user-visible symptom is
just "the bridge file occasionally contains the wrong process's
payload" with no diagnostic.
Reproduced before this commit:
$ # two concurrent writers, each calling writeBridgeAtomic 500 times
$ # against the same session ID
[A] errors=244 # 244 ENOENT exceptions swallowed
[B] errors=248 # ditto
After this commit the same workload reports 0 errors in both
subprocesses: tmp paths no longer collide.
Fix: change `${target}.tmp` to
`${target}.${process.pid}.${crypto.randomBytes(4).toString('hex')}.tmp`,
matching the pattern already used by `writeCostWarningIfChanged` in
`scripts/hooks/ecc-metrics-bridge.js` (commit
|
||
|---|---|---|
| .. | ||
| install | ||
| install-targets | ||
| session-adapters | ||
| skill-evolution | ||
| skill-improvement | ||
| state-store | ||
| agent-compress.js | ||
| cost-estimate.js | ||
| cursor-agent-names.js | ||
| ecc_dashboard_runtime.py | ||
| github-discussions.js | ||
| harness-adapter-compliance.js | ||
| hook-flags.js | ||
| inspection.js | ||
| install-executor.js | ||
| install-lifecycle.js | ||
| install-manifests.js | ||
| install-state.js | ||
| mcp-config.js | ||
| observer-sessions.js | ||
| orchestration-session.js | ||
| package-manager.d.ts | ||
| package-manager.js | ||
| project-detect.js | ||
| resolve-ecc-root.js | ||
| resolve-formatter.js | ||
| session-aliases.d.ts | ||
| session-aliases.js | ||
| session-bridge.js | ||
| session-manager.d.ts | ||
| session-manager.js | ||
| shell-split.js | ||
| shell-substitution.js | ||
| tmux-worktree-orchestrator.js | ||
| utils.d.ts | ||
| utils.js | ||