Surfaced during #114 Phase 2 code review (pre-existing, NOT introduced by #114).
mureo/context/state.py:243 append_action_log does read → rebuild → write_state_file. _atomic_write makes the file replace atomic, but the surrounding read-modify-write is not a critical section. Two concurrent mutating calls (built-in↔built-in, or now built-in↔plugin after #114 Phase 2 widened the caller set to the plugin dispatch path) can lose an action_log entry (last-writer-wins on the whole StateDocument).
Impact today is low (the MCP server is effectively single-flighted), so this does not block #114. Tracking for a proper fix.
Options
- File lock (e.g.
fcntl.flock / a .lock sidecar) around the RMW.
- Append-oriented action_log storage (separate JSONL) instead of rewriting the whole STATE.json.
- An in-process async lock in the MCP server serialising STATE.json mutations.
Acceptance
Surfaced during #114 Phase 2 code review (pre-existing, NOT introduced by #114).
mureo/context/state.py:243 append_action_logdoes read → rebuild →write_state_file._atomic_writemakes the file replace atomic, but the surrounding read-modify-write is not a critical section. Two concurrent mutating calls (built-in↔built-in, or now built-in↔plugin after #114 Phase 2 widened the caller set to the plugin dispatch path) can lose an action_log entry (last-writer-wins on the wholeStateDocument).Impact today is low (the MCP server is effectively single-flighted), so this does not block #114. Tracking for a proper fix.
Options
fcntl.flock/ a.locksidecar) around the RMW.Acceptance
_atomic_writedurability semantics.