#2394

Replica writer lease across stdio MCP sessions — prefer oldest-live lease, no hard reject

Openxxxn3m3s1sxxxopened 2mo ago

Summary

When multiple stdio MCP server replicas share one palace on the same host (e.g. 3 opencode sessions: dev / suckz / atlas_core, PIDs 16248 / 16996 / 16264 observed 30.08.), exactly one holds the per-palace single-writer lease via flock and every other replica is correctly refused for mutating tools. The lease serializes writes correctly — but the identity of the lease holder was previously opaque.

PR #2391 (feat: name the stdio MCP writer in peer-writer refusal) fixes the diagnosability gap: the writer replica now publishes a small marker next to serverinfo.json (pid + started_at, guarded by _pid_alive) and the refusal message includes \writer: pid X since Y\ + a \writer\ data field. This is purely informational — no change to the write/deny behavior.

The deeper issue remains: replica dedup per host. Each opencode session instantiates its own \mcp_server\ replica; the single-writer lease protects against parallel writes but not against multiple replicas being started in the first place. The 3-live-replica case is live peer contention, not a stale record — stale-reap (#2389) does not help because all PIDs are live (confirmed in diagnosis drawer 3396263c).

Proposal — prefer oldest-live lease, no hard reject

  • Do not add a hard singleton guard that rejects a second replica outright. That would break the legitimate case where several sessions read one palace concurrently with a single writer (read-only replicas must remain usable).
  • Instead, if a lease already exists, keep the oldest live writer lease stable: a newer replica that starts while a live writer holds the lease stays read-only and never steals the lease. Only when the current writer's PID is no longer alive (or its flock is released) does the next oldest live replica become eligible.
  • Implementation sketch: reuse the marker + flock authority already introduced in #2391; on _acquire_mcp_writer_lock, if
    ead_stdio_writer()\ returns a live PID, the newcomer skips acquire and remains read-only. Lease handover is strictly liveness-driven — no periodic stealing.

Why this helps

  • No behavior change for single-replica users.
  • Multi-session users keep concurrent read access while writes stay deterministic (oldest writer wins, no flip-flop).
  • The marker from #2391 already provides the visibility; this issue would make the scheduling policy explicit and testable.

Relation to #2391

#2391 is the minimal diagnostic fix (VERIFIED, MERGEABLE, verifier evidence posted as comment). This issue is the follow-up scheduling guarantee that the same 3-replica scenario needs — intentionally filed separately so #2391 can merge without coupling.

Alternatives considered

  • Hard singleton guard (second replica fails to start) — rejected: breaks concurrent reads (Skap decision, team consensus).
  • Periodic lease stealing / youngest-wins — rejected: causes writer flip-flop when sessions restart.

Happy to provide a reproducer (spawn N stdio replicas against one palace, assert exactly one writer + stable oldest) if maintainers want it as a test.

Activity

0

No activity yet.