From 6bc2d6653067f10fd46f9915c4489e6fc97825b1 Mon Sep 17 00:00:00 2001 From: Alex Southwell <4596216+saphid@users.noreply.github.com> Date: Tue, 3 Nov 2026 13:08:16 +1100 Subject: [PATCH] fix(server): a link card the user moved past no longer blocks auto-settle Co-Authored-By: Claude Opus 5.5 --- apps/server/src/orchestration-v2/ProjectionStore.ts | 10 ++++++++++ apps/server/src/peer/PeerLinkRequests.test.ts | 3 +++ 2 files changed, 13 insertions(+) diff --git a/apps/server/src/orchestration-v2/ProjectionStore.ts b/apps/server/src/orchestration-v2/ProjectionStore.ts index 3cffce15b70d6..72141aa0e2365 100644 --- a/apps/server/src/orchestration-v2/ProjectionStore.ts +++ b/apps/server/src/orchestration-v2/ProjectionStore.ts @@ -6428,6 +6428,16 @@ export const layer: Layer.Layer = INDEXED BY orchestration_v2_projection_turn_items_waiting_link_idx WHERE link.thread_id = t.thread_id AND link.type = 'link_request' AND link.status = 'waiting' + -- linkCardStillAsks: once the user writes after the card, it stops asking. + AND NOT EXISTS ( + SELECT 1 FROM orchestration_v2_projection_messages message + WHERE message.thread_id = t.thread_id AND message.role = 'user' + AND json_extract(message.payload_json, '$.createdBy') = 'user' + AND NOT ${isIdleCompactionMessage("message")} + AND message.updated_at > COALESCE( + json_extract(link.payload_json, '$.startedAt'), link.updated_at + ) + ) ) ORDER BY t.updated_at ASC, t.thread_id ASC `; diff --git a/apps/server/src/peer/PeerLinkRequests.test.ts b/apps/server/src/peer/PeerLinkRequests.test.ts index ccc7a8d8bd0eb..c3ca78cbcb6a7 100644 --- a/apps/server/src/peer/PeerLinkRequests.test.ts +++ b/apps/server/src/peer/PeerLinkRequests.test.ts @@ -528,6 +528,9 @@ it.live("the agent asks without waiting, and the user links the box after its tu yield* a.orchestrator.getThreadProjection(threadId), ).pendingRuntimeRequest, ).toBeNull(); + expect( + (yield* a.projections.getSettlementCandidates(threadId)).map((thread) => thread.id), + ).toEqual([threadId]); expect(yield* cardOf(a)).toMatchObject({ status: "waiting", linkStatus: "pending" }); // The user's client mints a code on the box and picks more than the agent suggested.