From f02a010877b20f66d93d3634e2a9af180b8bd119 Mon Sep 17 00:00:00 2001 From: Proactive Runtime Bot Date: Thu, 6 Aug 2026 11:02:23 +0200 Subject: [PATCH] fix(mcp): stop a cleared enrollment reporting as a failed persist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reusing `persistenceWarning` for the cleared-enrollment message meant `set_workspace_key` took the failure branch on success, answering with "the workspace is active for this process" — i.e. telling the caller the key had NOT persisted — when it had, and when the only thing that happened was the enrolled node being dropped. The tool's own description promised the opposite. The two outcomes are now tracked separately: a failed write still reports the active-not-persisted wording, and a successful write that cleared an enrollment reports the persisted wording followed by the clearing notice. Test asserts both halves, including that the failure wording is absent. Refs #1432 Co-Authored-By: Claude Opus 5 --- packages/cli/src/cli/agent-relay-mcp.startup.test.ts | 4 ++++ packages/cli/src/cli/agent-relay-mcp.ts | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/cli/agent-relay-mcp.startup.test.ts b/packages/cli/src/cli/agent-relay-mcp.startup.test.ts index 94f664185..ebcca9f9b 100644 --- a/packages/cli/src/cli/agent-relay-mcp.startup.test.ts +++ b/packages/cli/src/cli/agent-relay-mcp.startup.test.ts @@ -593,6 +593,10 @@ describe('createAgentRelayMcpServer', () => { // `node up` mentioned it. expect(result.structuredContent.message).toContain('node_abc'); expect(result.structuredContent.message).toContain('relay cloud enroll'); + // A cleared enrollment means the write SUCCEEDED. Reporting it through the + // persistence-failure wording would tell the caller the key never landed. + expect(result.structuredContent.message).toContain('persisted for this project'); + expect(result.structuredContent.message).not.toContain('could not be persisted'); }); it('registers submit_result when a spawned-agent result callback is configured', async () => { diff --git a/packages/cli/src/cli/agent-relay-mcp.ts b/packages/cli/src/cli/agent-relay-mcp.ts index d24af51b3..8ef54b2d6 100644 --- a/packages/cli/src/cli/agent-relay-mcp.ts +++ b/packages/cli/src/cli/agent-relay-mcp.ts @@ -499,11 +499,15 @@ function registerAgentRelayTools( } else { setSession({ workspaceKey: key }); } + // Two distinct outcomes, never conflated: the write failed, or the write + // succeeded and dropped this project's enrolled fleet node. Reporting the + // second as the first would tell the caller the key had not persisted. let persistenceWarning: string | undefined; + let clearedEnrollmentWarning: string | undefined; try { // Joining a different workspace drops this project's enrolled fleet // node; surface that here instead of at the next `node up`. - persistenceWarning = describeClearedEnrollment(persistWorkspaceSession({ workspaceKey: key })); + clearedEnrollmentWarning = describeClearedEnrollment(persistWorkspaceSession({ workspaceKey: key })); } catch (error) { const persistenceError = error instanceof Error ? error.message : String(error); persistenceWarning = @@ -517,7 +521,9 @@ function registerAgentRelayTools( const activeMessage = switchingWorkspace ? 'Workspace key set. Call "register_agent" to join this workspace.' : 'Workspace key set.'; - const message = persistenceWarning ? `${activeMessage} ${persistenceWarning}` : persistedMessage; + const message = persistenceWarning + ? `${activeMessage} ${persistenceWarning}` + : [persistedMessage, clearedEnrollmentWarning].filter(Boolean).join(' '); return textContent(message); } );