ZeroClaw

ZeroClaw can erase a concurrent configuration update during flush

An open ZeroClaw patch says independent gateway writers can read the same configuration snapshot and let the later flush overwrite the earlier update. The proposal serializes the complete read-modify-write cycle rather than locking only the final file operation.

← Back to homeOriginal source ↗

zeroclaw-labs/zeroclaw PR #9519 is the inspected primary source: “fix(gateway): serialize config writes so a flush can't erase concurrent updates.” The two related records below were inspected as supporting context, not treated as independent confirmation.

The facts

- zeroclaw-labs/zeroclaw PR #9519 was created 2026-07-28T22:54:18Z and was open at inspection; its title is “fix(gateway): serialize config writes so a flush can't erase concurrent updates.” - zeroclaw-labs/zeroclaw PR #9476 was created 2026-07-28T03:13:03Z and was open at inspection; its title is “feat(sop): add authenticated operator cancellation for running SOP jobs.” - zeroclaw-labs/zeroclaw PR #9418 was created 2026-07-26T21:54:58Z and was open at inspection; its title is “fix(mcp): multiplex stdio calls without replaying unknown outcomes.” - The repository reported 32430 stars, 650 open issues, default branch master, and last push 2026-07-29T00:27:45Z. - The latest tagged-release baseline checked was v0.8.3 published 2026-07-16T01:47:13Z.

What changed

zeroclaw-labs/zeroclaw PR #9519 reports: Summary **Base branch:** master **What changed and why:** Gateway HTTP handlers that mutate configuration each did an independent read-clone → save → swap of the shared AppState config with no coordination, so a write that landed during another handler's unlocked save window was silently lost from both memory and disk. Adds an AppState::config_write_lock witness (tokio::sync::Mutex ) acquired before every read-for-modify and held across save + swap, so gateway config writes serialize — mirroring the already-merged daemon/RPC fix (RpcContext::config_write_lock) for the gateway process. persist_and_swap takes the guard by reference (its callers acquire it before their read-clone); persist_pairing_tokens acquires it internally; all seven gateway config-write paths are covered (property edits, pairing, section select, quickstart apply, cron settings, context-window refresh, channel bind, migrate). The context-window refresh endpoint performs its outbound provider fetch *outside* the lock, so a slow/hanging provider cannot stall other config writers; it re-verifies the target entry still exists under the guard. **Scope boundary:** Only the gateway process's shared AppState.config. Does NOT change the channels identity-persistence

zeroclaw-labs/zeroclaw PR #9476 reports: Summary **Base branch:** master **What changed and why:** Running SOP jobs could be listed and inspected in the web dashboard but had no operator cancellation path. Approve/Deny only apply to a run parked at an approval gate, and restarting the daemon does not help because a persisted active run is rehydrated and resumes on startup — so a stuck or runaway SOP could not be safely terminated through the supported operator surface. Add an authenticated POST /api/sops/{name}/runs/{run_id}/cancel gateway endpoint (handle_sop_cancel, same require_auth gate as handle_sop_decide). Add SopEngine::cancel_run_idempotent, which under a single engine-lock hold classifies the run (active / already-terminal / unknown) and, for an active run, calls cancel_run_with_reason — marking it Cancelled, releasing its concurrency claim, and recording a durable run_cancelled audit event atomically via the existing finish_run_with_gate_event. Terminal Cancelled is skipped by startup rehydration, so a cancelled run cannot resume. Align persist_terminal_with_gate_event with persist_terminal so a store-write failure during cancel is classified as retryable (TerminalPersistenceRetained → 503) instead of a raw 500. Add a

zeroclaw-labs/zeroclaw PR #9418 reports: fix(mcp): multiplex stdio calls without replaying unknown outcomes Summary **Base branch:** master **What changed and why:** Route stdio JSON-RPC responses by exact child generation and numeric request ID so concurrent calls cannot consume each other's replies. Remove the hidden stdio 30-second receive deadline and let the configured MCP tool timeout remain the canonical end-to-end budget. Track pre-write, outcome-unknown, and completed request phases; reset, reap, and re-handshake after ambiguous failures or cancellation without replaying a possibly side-effecting call. Coordinate recovery publication with the actual stdio state boundary so a writer already queued behind a cancelled post-write call re-checks recovery and cannot reach the ambiguous child before reset and re-handshake. Keep HTTP/SSE serialized, make SSE issue exactly one POST, and add cancellation-safe pending-waiter cleanup plus complete close/reset teardown. Preserve the existing public transport facade while using the cancellation-aware shared transport path inside McpServer. **Scope boundary:** Does not change MCP configuration, protocol versions, tool schemas, capability negotiation, or retry completed tool errors. It does not add concurrency to

Why it matters

Atomic file replacement prevents torn writes but not lost updates. A control plane needs serialization or conflict detection around the logical transaction, particularly when channels, peers and operator commands share one configuration file. This is an operator boundary: persisted state, execution ownership and visible controls must describe the same event. A workaround that broadens access, deletes state or hides the symptom would trade a visible defect for an unmeasured one.

Current

The primary record was open when captured on 2026-07-29. The release baseline was v0.8.3 published 2026-07-16T01:47:13Z. Current repository metadata, pull requests, issues, release records, Hacker News discovery results and the rendered ClawCharts row were checked. ClawCharts selected the subject; it did not prove the claim.

Evidence

The primary URL is https://github.com/zeroclaw-labs/zeroclaw/pull/9519. Supporting records are https://github.com/zeroclaw-labs/zeroclaw/pull/9476 and https://github.com/zeroclaw-labs/zeroclaw/pull/9418. Their source bodies, timestamps and states were captured in the daily evidence bundle. Test counts, reproductions and deployment observations remain attributed to their authors unless explicitly identified as independently rerun.

Source boundary

Open work is described as open, closed work as closed, and operator reports as reports. A pull request is evidence of proposed or reviewed direction, not proof of a shipped release. Issue closure would not by itself prove a deployed fix. Search residue, package mirrors and historically published source spines were excluded.

Operator take

Exercise two real concurrent mutations and verify both survive restart; a clean JSON file is not proof that both operator intents were retained. Preserve a before-state receipt, make the smallest reversible change, and verify the original failure independently after intervention.

Caveat

Public project records are mutable. Status, scope and evidence can change after publication. This brief records the inspected state and does not authorize changes to a reader’s deployment.

Source inspected; source state, environment and release boundary remain explicit.