From 0dcb28a2b0dfe6f18309d85ba15087438016688b Mon Sep 17 00:00:00 2001 From: Dotta Date: Sun, 27 Sep 2026 20:56:50 -0500 Subject: [PATCH] test(chat): verify concurrent explicit X publication and harden CI installs Keep the invoking message available beyond the bounded history window. Disable dependency lifecycle scripts in the Sentry install path. Co-Authored-By: Paperclip --- .github/workflows/sentry-contract.yml | 4 +-- .../chat-channels.integration.test.ts | 26 ++++++++++++++++++- server/src/services/x/service.ts | 1 + 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sentry-contract.yml b/.github/workflows/sentry-contract.yml index b836f3039f3..23a3365685e 100644 --- a/.github/workflows/sentry-contract.yml +++ b/.github/workflows/sentry-contract.yml @@ -50,10 +50,10 @@ jobs: # Dependency-changing PRs leave lockfile updates to CI, as the main PR # lanes do. Resolve the merge tree locally before the frozen install. run: | - if ! pnpm install --frozen-lockfile; then + if ! pnpm install --ignore-scripts --frozen-lockfile; then echo '::notice title=Lockfile::checked-in lockfile is stale for this merge tree; resolving it inline' pnpm install --resolution-only --ignore-scripts --no-frozen-lockfile - pnpm install --frozen-lockfile + pnpm install --ignore-scripts --frozen-lockfile fi - name: Install the audited optional SDK outside the workspace diff --git a/server/src/__tests__/chat-channels.integration.test.ts b/server/src/__tests__/chat-channels.integration.test.ts index 8bb1fb7c155..9803b78fc3e 100644 --- a/server/src/__tests__/chat-channels.integration.test.ts +++ b/server/src/__tests__/chat-channels.integration.test.ts @@ -72320,7 +72320,7 @@ describeEmbeddedPostgres("chat channel control-plane integration", () => { await expect(executeConnectorTool(db, binding, "x_reply", { replyToPostId: "10", text: "wrong target", idempotencyKey: randomUUID() })).rejects.toThrow("invoking post"); await expect(executeConnectorTool(db, { ...binding, companyId: randomUUID() }, "x_read_thread", {})).rejects.toThrow(); const request = { replyToPostId: "200", text: "Here is the answer.", idempotencyKey: randomUUID() }; - const result = await executeConnectorTool(db, binding, "x_reply", request) as { publicationId: string; status: string }; + const result = await native.execute({ tool: "x_reply", callId: randomUUID(), arguments: request }) as { publicationId: string; status: string }; expect(result.status).toBe("pending"); expect(await executeConnectorTool(db, binding, "x_reply", request)).toEqual(result); await expect(executeConnectorTool(db, binding, "x_reply", { ...request, idempotencyKey: randomUUID() })).rejects.toThrow("already has a reply"); @@ -72340,6 +72340,30 @@ describeEmbeddedPostgres("chat channel control-plane integration", () => { expect(f.sends).toHaveLength(1); }, 60_000); + it("X concurrent reply intents and workers preserve each branch's exact target after restart", async () => { + const f = await configuredXEndpoint(); + const { executeConnectorTool } = await import("../services/connector-runtime.js"); + await f.deliver([f.event("210"), f.event("211")]); + await f.drain(); + const first = await f.binding("210"); + const second = await f.binding("211"); + expect(first.issueId).not.toBe(second.issueId); + const request = { replyToPostId: "210", text: "First branch", idempotencyKey: randomUUID() }; + const [one, duplicate] = await Promise.all([ + executeConnectorTool(db, first, "x_reply", request), + executeConnectorTool(db, first, "x_reply", request), + executeConnectorTool(db, second, "x_reply", { replyToPostId: "211", text: "Second branch", idempotencyKey: randomUUID() }), + ]); + expect(one).toEqual(duplicate); + await f.restart(); + await Promise.all([f.service().processPendingPublications(), f.service().processPendingPublications()]); + expect(f.sends).toHaveLength(2); + expect(f.sends).toEqual(expect.arrayContaining([ + { text: "First branch", reply: { in_reply_to_tweet_id: "210" } }, + { text: "Second branch", reply: { in_reply_to_tweet_id: "211" } }, + ])); + }, 60_000); + it("X opt-out and current authority stop work and sends; uncertain sends never retry", async () => { const f = await configuredXEndpoint(); const { executeConnectorTool } = await import("../services/connector-runtime.js"); diff --git a/server/src/services/x/service.ts b/server/src/services/x/service.ts index dd01d2e08c8..f8ac2818950 100644 --- a/server/src/services/x/service.ts +++ b/server/src/services/x/service.ts @@ -398,6 +398,7 @@ export function xChannelService(db: Db, hooks: XHooks, fetchImpl = fetch) { })), replyablePostIds: [messageId(source.delivery)], invokingPostId: messageId(source.delivery), + invokingMessage: source.delivery.normalizedEvent.message, }; } if (tool === "x_delivery") {