You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
v1.0.0: cherry-pick the #5097 roots refresh ordering fix onto the release branch - #5099
Targets the one-time release branch v2/release/1.0.0 (retargeted automatically after #5096 merged). The v2/main fix is #5098; this branch carries the same fix for the SDK 1.x release.
Description
Cherry-picks the #5097 fix from #5098 (git cherry-pick -x), so overlapping roots refreshes cannot apply out of order in v1.0.0:
a13e809d (from 423fe6b7): each roots refresh (the initial load and every roots/list_changed) takes a generation before it asks for roots; its answer is applied only if no newer refresh has started since, checked after both roots/list and validation. A stale answer is logged and dropped, so it cannot undo a newer update such as a revocation (filesystem: a roots update with no valid roots keeps the previous allowed directories #5094).
be9a5551: records it the release branch's way, removing the changeset and adding its text to src/filesystem/CHANGELOG.md under the unpublished 1.0.0. No version change.
b503c696 (from 564e84d6, Copilot on fix(filesystem): apply only the newest roots refresh's answer #5098): while the initial roots load is pending, a refresh that overtakes it replaces the initialization gate, so tool calls waiting for the initial roots wait for the refresh that will actually apply instead of running against the command-line directories.
0f8bfe3b: adapts the new failure test to SDK 1.x, where a client handler's error reaches the server as MCP error -32603: gone (as the existing re-fetch test on this branch already expects).
Changes to: roots refresh ordering and the initialization gate (server.ts), CHANGELOG.md (1.0.0 entry), tests
Motivation and Context
#5097, raised by Copilot on #5095 and #5096; shipped in 1.0.0 by maintainer decision on #5080.
How Has This Been Tested?
Four new protocol-level tests in server-roots.test.ts, on this SDK 1.x tree:
two overlapping updates answered out of order (the older one held back): the newer revocation stands and the stale answer is logged;
an update that overtakes a held initial load: the update wins;
a tool call started after the stale initial answer is released but before the overtaking answer arrives stays pending, then is refused once the newer roots apply (fails with the gate handoff disabled);
a failing overtaking refresh releases waiting calls, checked while the initial answer is still held.
Filesystem: 334 passed / 2 skipped. npm run local:gate: EXIT=0. The out-of-order client evidence (an older roots/list answer held 800 ms behind a newer revocation) is in #5098, and is re-run against the release tree for the ledger before #5090 merges.
Breaking Changes
None.
Types of changes
Bug fix (non-breaking change which fixes an issue)
Each roots refresh (the initial load and every roots/list_changed) takes a generation before it asks for roots; its answer is applied only if no newer refresh has started, checked after both roots/list and validation. A stale answer is logged and discarded, so it cannot undo a newer update such as a revocation.
Closes#5097
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
(cherry picked from commit 423fe6b)
Signed-off-by: cliffhall <cliff@futurescale.com>
As with #5094 on this branch: 1.0.0 is unpublished and its changesets are already folded, so the cherry-picked fix is recorded in that entry. No version change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.
This PR includes no changesets
When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types
… the initial roots
When a roots/list_changed overtakes the initial roots/list, the initial refresh's stale answer is discarded, but it used to release the tool calls waiting on the initial load, which then ran against the command-line directories before the newer roots applied. The overtaking refresh now replaces the initialization gate while the initial load is pending, and waiting calls follow it until it settles (Copilot on #5098).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
(cherry picked from commit 564e84d)
Signed-off-by: cliffhall <cliff@futurescale.com>
test
The cherry-pick of 564e84d comes from the SDK v2 tree, where a client handler's error reaches the server as "gone"; SDK 1.x wraps it as "MCP error -32603: gone", as the existing re-fetch test on this branch already expects.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Copilot round 1: clean. Since then, b503c69 cherry-picks the gate fix from #5098 round 1 (waiting tool calls follow the refresh that overtook the initial load), and 0f8bfe3 adapts its failure test to SDK 1.x (MCP error -32603: gone). Filesystem 334 passed; gate EXIT=0. Requesting round 2 for the new commits.
…l answer arrives
The failed-overtaking-refresh test released the held initial roots/list before asserting, so it would also pass if callers stayed blocked on it. Assert first, then release for cleanup (Copilot on #5098).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Copilot round 2: 1 finding (low), the PR body described the first version; updated to the five-commit branch and its four tests. Also c88c3bf cherry-picks the test fix from #5098 round 2. Gate EXIT=0. Requesting round 3.
The failed-overtaking-refresh test returned right after releasing the held initial roots/list, so its answer handling and root validation could race afterEach's teardown. Wait for the stale answer to be discarded first (Copilot on #5099).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
The failed-overtaking-refresh test returned right after releasing the held initial roots/list, so its answer handling and root validation could race afterEach's teardown. Wait for the stale answer to be discarded first (Copilot on #5099).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
This call starts only after the stale initial promise has resolved and initialization already points at the newer refresh, so it does not exercise the new retry loop at server.ts:213-216. A regression that removes that loop would still pass. Start the tool call while it is awaiting the original initialization promise, then start the refresh, release the initial answer, and assert the call remains pending until the refresh completes.
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
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.
Closes #5097
Description
Cherry-picks the #5097 fix from #5098 (
git cherry-pick -x), so overlapping roots refreshes cannot apply out of order in v1.0.0:a13e809d(from423fe6b7): each roots refresh (the initial load and everyroots/list_changed) takes a generation before it asks for roots; its answer is applied only if no newer refresh has started since, checked after bothroots/listand validation. A stale answer is logged and dropped, so it cannot undo a newer update such as a revocation (filesystem: a roots update with no valid roots keeps the previous allowed directories #5094).be9a5551: records it the release branch's way, removing the changeset and adding its text tosrc/filesystem/CHANGELOG.mdunder the unpublished1.0.0. No version change.b503c696(from564e84d6, Copilot on fix(filesystem): apply only the newest roots refresh's answer #5098): while the initial roots load is pending, a refresh that overtakes it replaces the initialization gate, so tool calls waiting for the initial roots wait for the refresh that will actually apply instead of running against the command-line directories.0f8bfe3b: adapts the new failure test to SDK 1.x, where a client handler's error reaches the server asMCP error -32603: gone(as the existing re-fetch test on this branch already expects).c88c3bff(from11394a40, Copilot on fix(filesystem): apply only the newest roots refresh's answer #5098): the failed-refresh test asserts that waiting calls are released before the held initial answer arrives.Server Details
server.ts),CHANGELOG.md(1.0.0 entry), testsMotivation and Context
#5097, raised by Copilot on #5095 and #5096; shipped in 1.0.0 by maintainer decision on #5080.
How Has This Been Tested?
Four new protocol-level tests in
server-roots.test.ts, on this SDK 1.x tree:Filesystem: 334 passed / 2 skipped.
npm run local:gate: EXIT=0. The out-of-order client evidence (an olderroots/listanswer held 800 ms behind a newer revocation) is in #5098, and is re-run against the release tree for the ledger before #5090 merges.Breaking Changes
None.
Types of changes
Checklist
🤖 Generated with Claude Code