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.