Repository navigation
Description
Relocated from dezren39/darwin-nix#339 on 2026-10-28 (placement audit): mcpx's single source lives in developing-today/code (pkgs/mcpx); re-home tracked at #309. Original body below; issue references inside it are historical (dezren39/nix numbering).
If a call to a non-read-only tool is cancelled, times out, or loses its upstream after dispatch, mcpx cannot know whether it took effect. Retrying can duplicate it.
codex-connectors-mcp marks that outcome unknown and refuses further writes until someone checks the app. Proposed for mcpx: record such calls (server, tool, arguments hash, time), refuse further non-read-only calls to that server until cleared (mcpx writes clear <server> or a /v1 route), and say why in the error. Scope: per server, persisted across daemon restarts, unlike theirs.
Related: #77 (cancellation), the destructive-call confirmation (elicit.confirmDestructive), the write-policy issue.
Reference: https://github.com/wileai/codex-connectors-mcp#writes
Acceptance criteria
- A non-read-only tool call whose outcome is unknown (cancelled, timed out, or upstream lost after dispatch) is recorded with server, tool, arguments hash, and time.
- Further non-read-only calls to that server are refused with an error that says why, until the record is cleared (
mcpx writes clear <server>or a/v1route). - The block persists across daemon restarts; read-only calls are unaffected.
- Tests cover: unknown-outcome write blocks the next write, clearing unblocks, restart preserves the block.
Activity
developing-today commentedon Oct 28, 2026
CODE-902
dezren39 commentedon Oct 28, 2026
History carried over from dezren39/darwin-nix#339 (verbatim, oldest first):
@dezren39 · 2026-10-27T11:46:50Z
Intake review
Fleet monitor intake enrichment, 2026-10-27.
Liveness: still live — no merged PR in dezren39/nix implements unknown-outcome write blocking (checked this run). Related: #77 (cancellation), #254 (write policy), and the destructive-call confirmation.
Notes: Safety feature: duplicated side effects are worse than a blocked server. Scope is deliberately per-server and persisted, unlike the codex-connectors-mcp in-memory version the body cites. Note mcpx also lives in developing-today/code — per the cross-repo rule, implementation should be tracked as one set with the origin issue here.
Risks: misclassifying a known-failed write as unknown would wedge a server until manual clear; the clear path must be obvious in the error text.
dezren39 commentedon Oct 29, 2026
Design architect (pass 12, 2026-10-29): this issue is Phase 3 of design #2126 (mcpx write policy — one gate for writes), adopted as a sub-issue of #2126; design doc:
files/designs/code-mcpx-write-policy.mdin the keep-the-four-repos-healthy goal workspace. Labelledstatus/blocked: gated on Phase 1 (#1979), whose shared write classification decides which calls count as writes for the ledger.Design decisions that bind it (recorded on #2126 and in the doc): the ledger is a versioned JSON file in the daemon state dir (
DefaultStateDir(),internal/daemon/paths.go:248-253), written atomically, recording server, tool, SHA-256 of the canonical arguments (never the arguments themselves), time, and calling surface; nothing auto-clears it — clearing ismcpx writes clear <server>or the/v1route in this issue's acceptance. "Unknown" is conservative: the client/pool layer marks an error post-dispatch only once the request bytes were written; pre-dispatch failures record nothing (and a test must prove one records nothing). Recording sits inRegistryabove #1634's client-internal recovery (landed), so a recovered call never reaches the ledger and a write that still fails after recovery records exactly once. Read-only calls are never recorded and never blocked. On landing, post evidence on tracker #1984 for its #1977 checkbox.Triage note: this issue already has a queued triage packet (relocation). Triage should NOT re-file or split this scope — the implementation issue is this one; verdict should point at #2126, record the Phase 1 gate, and leave
status/blockedin place until #1979 lands.27 remaining items
mcpx: address Codex findings on unknown-outcome ledger (#1977)
Merge pull request #4721 from developing-today/queue/6667-1977-unknow…
dezren39 commentedon Nov 3, 2026
🤖 Agent note · handed_off
dezren39 commentedon Nov 3, 2026
🤖 Agent note · handed off
handed_off— the next claimant resumes from that checkpoint, it does not restart from zero.handed_off.developing-today commentedon Nov 3, 2026
agent-note:v1
state: reviewed (coverage loop-back)
Coverage pass 2026-11-03, loop-back review: this issue was re-reviewed (drift / overlap / already-handled / stale / blockers / ordering) so every open issue in the four repos is reviewed and in the system. Verdict: still live; in the system as task 6667 (small_fix, queued, priority 70) in repo-health-code-pilot. Labels audited and synced. If it is already handled at current main, its triage closes it with evidence; if oversized, the triage files the split; blockers belong on this issue.
Found via: coverage loop-back 2026-11-03
dezren39 commentedon Nov 4, 2026
🤖 Agent note · closing with evidence (from tracker triage task 8571, lane code-h)
Verified at current main
1c1aa4a79: PR #4721 ("mcpx: guard unknown write outcomes (#1977)", task 6667) MERGED 2026-11-03T06:59:06Z, mergea41cba35d. Against this issue's acceptance criteria:pkgs/mcpx/internal/daemon/write_ledger.go—unknownWriteRecord{Server, Tool, ArgsSHA256, At, Surface};registry.go:2354 recordUnknownOutcome.ErrUnknownOutcome(write_ledger.go:28), enforced inconsumer.go:549-573andregistry.go:2205-2311; clear path inapi/ops_writes.go+clearUnknownOutcome.OpenWriteLedger), per-config fingerprinted filename.pkgs/mcpx/internal/daemon/write_ledger_test.go(143 lines in PR mcpx: guard unknown write outcomes (#1977) #4721).Closing as completed. Tracker #1984 closes with this, per its own acceptance.