From 31a72990904cd3ea78ba3c78e20308df919c83d8 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 10 Aug 2026 11:11:15 +0000 Subject: [PATCH] fix(asap): isolate inbound task.request sessions by sender URN All POST /asap task.request calls shared the hardcoded session "asap:inbound", leaking conversation history across unrelated clients. Derive per-sender session ids from the envelope sender field. Co-authored-by: esadrianno --- src/asap/server.c | 16 +++++++++++++++- src/asap/server.h | 7 +++++++ tests/test_asap_server.c | 23 +++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/asap/server.c b/src/asap/server.c index d681f9b..228f274 100644 --- a/src/asap/server.c +++ b/src/asap/server.c @@ -112,11 +112,25 @@ static int fill_response_envelope(asap_envelope_t *out, const asap_envelope_t *i return 0; } +const char *asap_resolve_task_session_id(const char *ctx_session_id, const char *sender, + char *buf, size_t buf_size) +{ + if (ctx_session_id && ctx_session_id[0] != '\0') + return ctx_session_id; + if (sender && sender[0] != '\0' && buf != NULL && buf_size > 0) { + snprintf(buf, buf_size, "asap:%s", sender); + buf[buf_size - 1] = '\0'; + return buf; + } + return "asap:inbound"; +} + static int handle_task_request(const asap_envelope_t *in, asap_envelope_t *out, asap_server_ctx_t *ctx, char *err_message, size_t err_message_size) { char *prompt; char *resp_buf; + char sid_buf[256]; const char *sid; int ar; cJSON *pl; @@ -134,7 +148,7 @@ static int handle_task_request(const asap_envelope_t *in, asap_envelope_t *out, return -32603; } resp_buf[0] = '\0'; - sid = ctx->session_id ? ctx->session_id : "asap:inbound"; + sid = asap_resolve_task_session_id(ctx->session_id, in->sender, sid_buf, sizeof sid_buf); if (ctx->task_request_hook) ar = ctx->task_request_hook(ctx, in, resp_buf, (size_t)ASAP_SERVER_AGENT_RESPONSE_CAP); else { diff --git a/src/asap/server.h b/src/asap/server.h index 3762d94..14d74de 100644 --- a/src/asap/server.h +++ b/src/asap/server.h @@ -56,6 +56,13 @@ typedef struct asap_server_ctx { int asap_server_handle(const asap_envelope_t *in, asap_envelope_t *out, asap_server_ctx_t *ctx, char *err_message, size_t err_message_size); +/** + * Resolve the agent session id for inbound task.request. + * Explicit @p ctx_session_id wins; otherwise derives from @p sender URN. + */ +const char *asap_resolve_task_session_id(const char *ctx_session_id, const char *sender, + char *buf, size_t buf_size); + #ifdef __cplusplus } #endif diff --git a/tests/test_asap_server.c b/tests/test_asap_server.c index 1669864..5d26af5 100644 --- a/tests/test_asap_server.c +++ b/tests/test_asap_server.c @@ -720,9 +720,32 @@ static int test_trust_sender_rejects_blank_sender_when_list_nonempty(void) return 0; } +static int test_resolve_task_session_id(void) +{ + char buf[128]; + const char *sid; + + sid = asap_resolve_task_session_id("cli:override", "urn:alice", buf, sizeof buf); + ASSERT(sid != NULL && strcmp(sid, "cli:override") == 0); + + sid = asap_resolve_task_session_id(NULL, "urn:alice", buf, sizeof buf); + ASSERT(sid == buf); + ASSERT(strcmp(sid, "asap:urn:alice") == 0); + + sid = asap_resolve_task_session_id("", "urn:bob", buf, sizeof buf); + ASSERT(sid == buf); + ASSERT(strcmp(sid, "asap:urn:bob") == 0); + + sid = asap_resolve_task_session_id(NULL, NULL, buf, sizeof buf); + ASSERT(sid != NULL && strcmp(sid, "asap:inbound") == 0); + + return 0; +} + int main(void) { int r = 0; + r |= test_resolve_task_session_id(); r |= test_task_request_hook(); r |= test_task_cancel_stub(); r |= test_state_query_hook();