Skip to content

refactor: one durable pending-action store — the MCP park migrates up, the bespoke mechanism retires (ADR-0047 §5.4 follow-up) - #511

Merged
alicoding merged 1 commit into
mainfrom
durable-pending-action
Aug 28, 2026
Merged

refactor: one durable pending-action store — the MCP park migrates up, the bespoke mechanism retires (ADR-0047 §5.4 follow-up)#511
alicoding merged 1 commit into
mainfrom
durable-pending-action

Conversation

@alicoding

Copy link
Copy Markdown
Owner

Summary

ADR-0047 §5.4's homed follow-up: guardrailsvc.PendingActionStore is
the generic pending-action model brought up to MCPWriteRecord's own
guarantees (restart survival, retention-window sweep, at-most-once
apply-on-approve, an opaque Payload for restart-safe re-dispatch).

  • guardrailsvc.RequestGuardedAction now parks through the shared
    store instead of an in-memory-only map.
  • mcpsvc's gated-write lifecycle (gateWrite/ResolveMCPWrite/
    CancelMCPWrite/PendingMCPWrites/ResolvedMCPWrites/
    check_write_status) migrates onto the same store.
  • MCPWriteRecord, its bespoke settings key, loadWrites, and
    persistWritesLocked are deleted.
  • A settings file carrying the old mcp-pending-writes key upgrades
    automatically (mcpsvc.MigrateLegacyPendingWrites, wired in
    main.go ahead of guardrailsvc.NewGuardrailService's own
    construction, so the shared store never loads a stale
    pre-migration view) — a user's parked write survives the upgrade.
  • Retention is now a per-caller parameter on the shared store
    (mcpsvc's own mcpWriteExpiry var), not a single global, so two
    different consumers of the store can each state their own window.

Test plan

  • Every existing MCP-write/guardrail Go test passes UNMODIFIED
    (including the two persist-failure tests, which turned out not
    to need migration — the constructor-time default store is real
    and backed by the same settings.Store already passed in).
  • New guardrailsvc tests pin the same persist-failure property
    directly against the shared store (kept alongside, not instead
    of, the still-passing mcpsvc-level ones).
  • New restart-survival, at-most-once, courtesy-window, and expiry
    tests for PendingActionStore itself, -race clean.
  • New upgrade-path test: seed the old key/shape, migrate, confirm
    the record lists, resolves, and re-dispatches correctly, and the
    old key clears.
  • Full local gates: go vet, golangci-lint, gocognit-new,
    depguard-new, comment-hygiene, file-loc-limit, go test ./... -race (one pre-existing, already-quarantined, unrelated
    clipboard flake — confirmed also present on unmodified
    origin/main on this machine).
  • Relevant e2e specs green: guardrail.spec.ts,
    guardrail-authoring.spec.ts, guardrail-review.spec.ts,
    mcp-write-approval.spec.ts, mcp-write-cancel.spec.ts,
    mcp-write-staleness.spec.ts, atlas-mcp-write-approval.spec.ts,
    approval-prompt.spec.ts (20/20).

🤖 Generated with Claude Code

https://claude.ai/code/session_012im1JxQQV2ahnXzZDdVmZq

…, the bespoke mechanism retires

guardrailsvc.PendingActionStore is the generic pending-action model
brought up to the MCP write park's own guarantees (restart survival,
retention-window sweep, at-most-once apply-on-approve, an opaque
Payload for restart-safe re-dispatch). RequestGuardedAction now parks
through it; mcpsvc's gated-write lifecycle (gateWrite/ResolveMCPWrite/
CancelMCPWrite/PendingMCPWrites/ResolvedMCPWrites/check_write_status)
migrates onto the same store, and MCPWriteRecord plus its bespoke
settings-key persistence are deleted. A settings file carrying the old
mcp-pending-writes key upgrades automatically (MigrateLegacyPendingWrites,
wired in main.go ahead of GuardrailService's own construction) so a
user's parked write survives the upgrade.

Every existing MCP-write/guardrail Go test and e2e spec passes
unmodified against the new seam.

🤖 Generated with Claude Code

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012im1JxQQV2ahnXzZDdVmZq
@alicoding
alicoding enabled auto-merge (squash) August 28, 2026 23:09
@alicoding
alicoding merged commit 5e14385 into main Aug 28, 2026
30 checks passed
@alicoding
alicoding deleted the durable-pending-action branch August 28, 2026 23:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant