Repository navigation
Conversation
…upstream retirement Design for #1558, #1559, #1560, #1562, #1563 and #1564: one config commit (configCommitMu) used by every server writer, with the live config as the only source (SaveConfiguration stops rebuilding from storage), per-server generations and incarnations, a synchronous removal that purges every name-keyed bucket in one bbolt transaction, generation-checked manager mutators for workers and the supervisor, and a per-instance dial gate that retires stale clients at the byte level (stdio, HTTP/SSE, OAuth, retries) before the commit publishes. Ships as four PRs from main. Also records two defects found on main while researching: MCP quarantine_server skips the index purge, and ClearOAuthState("foo") deletes foo_bar's tokens.
Deploying mcpproxy-docs with
|
| Latest commit: |
d67c954
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://13b8fa0e.mcpproxy-docs.pages.dev |
| Branch Preview URL: | https://116-config-commit-consistenc.mcpproxy-docs.pages.dev |
Sol spec review r1 (six findings, all accepted): - R5.1 dial gate registers conns inside the admitted dial section, latch checked/set under connsMu, second sweep after the barrier (T4.16) - R5.2 instance-targeted actions bind to (gen, InstanceID); stale disconnect cannot hit a same-generation replacement (T3.9) - R5.3 OAuthEpoch + CredentialBinding so an OAuth-config clear cannot be undone by a parked token/DCR write (T2.13) - R5.4 single unregisterLocked retires every instance leaving the manager, incl. restart/ForceReconnectAll/Docker recovery (T4.15) - R5.5 compensating disk write restores pendingAwareDiskConfig(base), not base, so pending restart changes survive (T1.16) - R5.6 T2.5 parks after the approval-lock section, before the unquarantine commit
…credential binding, binding-conditional OAuth deletes)
…efresh flights, commitview leaf package, record revision for bound clears)
…erving transport wrapper, explicit same-commit replacement, standalone CLI logout clear)
…ce restamp in PR1, raw-byte disk compensation, per-row commit stamps, field-clearing bound DCR clear, commit-bound baseline promotion, boot Bootstrap)
Contributor
📦 Build ArtifactsWorkflow Run: View Run Available Artifacts
How to DownloadOption 1: GitHub Web UI (easiest)
Option 2: GitHub CLI gh run download 38151645311 --repo smart-mcp-proxy/mcpproxy-go
|
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This is the design spec (speckit) for the six concurrency and consistency issues Sol 6.1 found while reviewing UX-01 and UX-02: #1558, #1559, #1560, #1562, #1563 and #1564. It is documentation only. The implementation follows as four PRs.
Root cause. A server's state lives in four stores: the live config, bbolt storage, the config file and the upstream manager. Changes reach them in different orders, and only some steps hold
configCommitMu. Two flows run in opposite directions:LoadConfiguredServerscopies config to storage, andSaveConfigurationrebuilds the config from storage. Asynchronous workers act on stale snapshots. The rejected branchfix/qa070-ux01-create-only-addpatched each reader of that model in turn and needed ten review rounds. This spec removes the second source of truth instead.Design in one paragraph. Every server writer goes through
Runtime.Commit. It reads the live config insideconfigCommitMu, mutates a copy, then runs: gate → prepare generations → disk → one bbolt transaction (purge included on removal) → advance the manager (unregister and retire stale instances) → publish. The live config is the only source, soSaveConfigurationno longer reads storage and there is nothing left to resurrect a removed server from. Each server has a generation, which changes on any change to its entry. Workers and the supervisor check it inside the manager's registration lock. Each server also has an incarnation, which changes only on remove followed by create. Approval writers check it under the per-server approval lock against the storage row. Each client instance owns a dial gate. Retirement closes the gate at the byte level (stdioStart, gated dialer, gated connWrite), and the instance's OAuth client andnet/httpretries share the same gated transport.PR split (each one merges from
mainindependently)Commit/CommitTx, two-phaseconfigsvcwith per-server generations, reconcile inside the commit,SaveConfigurationpersists the live config, all writers converted (REST/MCP add, update, patch, enable, quarantine, remove; Apply; Reload; registry sources; sharing),createMuremoved, CI write-site guardexpected_incarnation(optional) plus 409server_replacedManager.desired,AddServerConfigAt/RemoveServerAt/ConnectServerAt,AdvanceGenerationsat commit step 6, supervisor/restart/capture carry the generationinternal/upstream/dialgate, per-instance transport, stdio/Docker/launcher admission, OAuthWithBaseTransport, retire before publishEach PR has failing-first hook-gated
-racetests (quickstart.md T1–T4) and a live check on the qa070 harness (L1–L4). tasks.md groups the tasks by PR in TDD order.Key decisions
scripts/check-upstream-write-sites.shfails CI on anyupstreamswrite outside the commit.Writegate on a per-instancehttp.Transportcovers TLS, HTTP/2,net/httpinternal retries and the OAuth client. Sol rejected the RoundTripper and flag approaches in r8–r10.configCommitMu→ approval locks (sorted; released before step 6) → storage/index. ThenconfigCommitMu→captureMu(W) →Manager.mu→ gate. Thenconfigsvc.updateMuandRuntime.muas leaves. This respects the existing capture ordercaptureMu(R) → approval lock.createMuis deleted.New findings recorded while researching (verified on
mainee7834e)quarantine_security quarantine_serverdoes not purge the index. The tool descriptions were still returned byretrieve_tools35 s after a successful quarantine. This bypasses the security: quarantining a server via the config file leaves its tools in the search index, so retrieve_tools still discloses their descriptions #1061 TPA control. Fixed in PR1 (FR-008).ClearOAuthState("foo")deletesfoo_bar's OAuth tokens because it matches on the prefixname_. Reproduced with a throwaway storage test. Fixed in PR2 (FR-011).Design review (opencode
github-copilot/gpt-6.1-sol)Four rounds were run on this design PR, using 4 of the 10-round cap. 25 findings were each verified against the code and resolved in the spec. research.md §7-§10 has the finding-by-finding table. The main design changes from review:
Bootstrap/ForceDisk(D13).ReplaceConfigandReconcileLiveare separate operations (D14).WrapTransportis lock-free. stdio launch and registration are one admitted section. Windows processes are created suspended and assigned to their Job. The gate also covers the OAuth preflight helpers, the browser launch, the launcher readiness probe and Docker diagnostic execs. Teardown commands are exempt.DisconnectServerAtandReplaceInstanceAt(coveringForceReconnectAlland Docker recovery) are added. Instance generation stamping moves to PR1.Round 4 still reported findings (2 high, 2 medium), and all four are resolved in the spec. No round has returned PASS yet, so the next rounds run per implementation PR, against the code.
Coordination with Spec 117
Spec 117 (#1565-#1567) is being designed in parallel. research.md §6 defines the integration points:
Commit+UnderApprovalLock;Retire()per instance;Open questions (default taken; see research §5)
expected_incarnationbe required on approval endpoints? Default: optional, with the handler falling back to the incarnation read at request start.meta.config_commit_generation.Retiretake? Default: it is bounded by design, and anything over 1 s is logged as a warning.#1569 (tray) is handled separately in #1572. This spec does not touch
native/.🤖 Generated with Claude Code