Reference in New Issue
Block a user
Delete Branch "fix/33-e2e-chat-main-red"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixes #2786.
Root cause (RCA #100702)
Registry rules default external workspaces with empty
delivery_modeto poll, and the proxy short-circuits poll targets to{status:"queued"}without dispatching to the echo URL. Desktop tests then wait for inlineEcho:text that never arrives.Fixes
canvas/e2e/fixtures/chat-seed.ts: setdelivery_mode = 'push'in the direct DB update so echo-runtime workspaces receive synchronous A2A responses.canvas/e2e/chat-separation.spec.ts: default direct API probes toE2E_PLATFORM_URLwhenE2E_API_URLis not exported, resolvingconnect ECONNREFUSED ::1:8080on ephemeral-port CI runs.canvas/e2e/fixtures/chat-seed.ts: rewriteseedChatHistoryto insert canvas-origina2a_receiverows intoactivity_logs(MessageStore-backed schema) instead of the obsoletechat_messagestable.Test plan
npx tsc --noEmit e2e/fixtures/chat-seed.ts e2e/chat-separation.spec.ts— clean.npx eslint e2e/fixtures/chat-seed.ts e2e/chat-separation.spec.ts— clean.Refs #2786 / RCA #100702, #2782, #33.
REQUEST_CHANGES on head
2a4256ae.The
E2E_API_URL ?? E2E_PLATFORM_URLfallback is correct for ephemeral-port CI, and the new seed target is directionally right: MessageStore reads canvas-origin chat history fromactivity_logsrows withactivity_type='a2a_receive'andsource_id IS NULL, so moving off the obsoletechat_messagestable is the right schema fix.Blocking issue:
seedChatHistorynow embeds JSON strings inside SQL, then embeds that SQL inside a shell double-quotedpsql -c "${sql}"command. The JSON double quotes are not escaped for the shell, so the shell strips them beforepsqlreceives the SQL. For example the command shape sends'{params:{message:{parts:[{kind:text,text:hello}]}}}'::jsonb, not valid JSON. That means the fixture can still fail to seed the canvas/agent rows the spec is supposed to assert, or behave differently depending on message content.Please avoid shell-string SQL execution here: use
execFileSync/spawnSyncwith argv forpsql -c, write SQL to stdin/file, or otherwise quote the SQL with a shell-safe boundary. Add a regression that seeds a normal text message through this helper and then reads it back via the same history path, so this cannot false-green.Also holding approval because required CI is not green on this head yet (
CI / Canvasis still pending and combined status is failure due review/checklist gates).Desktop-echo fixture specifics from the #2786 RCA for Kimi:
The echo runtime itself is
canvas/e2e/fixtures/echo-runtime.ts; the shared workspace fixture that points tests at it iscanvas/e2e/fixtures/chat-seed.ts::seedWorkspace.seedWorkspacecreates the target viaPOST /workspaceswithruntime: "external"andurl: echoURL, then bypasses SSRF by DB-updatingworkspaces.urlto the loopback echo URL. It does not setdelivery_mode='push'.That is the mismatch: core registry behavior deliberately defaults external-runtime + empty delivery_mode to poll mode (
workspace-server/internal/handlers/registry_test.go:2155-2162documents this). ThenProxyA2Ashort-circuits poll targets before URL dispatch (workspace-server/internal/handlers/a2a_proxy.go:554-596), returning 200{status:"queued", delivery_mode:"poll"}instead of calling the in-process echo URL. Product HTTP/WS A2A_RESPONSE can be correct and this fixture still fails, because the echo server is never reached in push mode.The exact desktop assertions that fail are in
canvas/e2e/chat-desktop.spec.ts:send text message and receive echo responsewaits forEcho: What is the weather?at lines 70-77;history persists across reloadwaits forEcho: Persistence testat lines 80-86;file attachment round-tripwaits forEcho: Please read this fileat lines 101-117; markdown tests wait forEcho: ```jsandEcho: | A | B |at lines 180-199. The failing main log showed/workspaces/:id/a2areturning HTTP 200, but no Echo text appeared, consistent with a queued poll response being treated as a synchronous push echo.Fix shape: either make this E2E echo fixture explicitly push-mode when it DB-wires the loopback URL, or rewrite the desktop tests to exercise a real poll consumer path. For the current desktop echo specs, forcing the fixture to push-mode is the narrow match to their assertions.
Registry rules default external workspaces with empty delivery_mode to poll, and the proxy short-circuits poll targets to {status:'queued'} without dispatching to the echo URL. Desktop tests then wait for inline echo text that never arrives. Set delivery_mode = 'push' in the direct DB update in seedWorkspace so the echo fixture reliably receives synchronous A2A responses. Refs #2786 / RCA #100702, #2782, #33. Co-Authored-By: Claude <noreply@anthropic.com>APPROVED on current head
270e962f.This addresses the #2786 E2E-Chat harness RCA cleanly. The chat-separation API client now falls back from E2E_API_URL to the workflow-provided E2E_PLATFORM_URL, so the ephemeral platform port is used instead of hard-coded localhost:8080. The chat-history seed now writes canonical activity_logs rows that match PostgresMessageStore's read contract: activity_type='a2a_receive', source_id NULL, request_body.params.message.parts for user text, and response_body.result.parts for agent text. The obsolete chat_messages table path is gone.
The new head also fixes the desktop echo half of the RCA: seedWorkspace now DB-wires the loopback echo workspace to delivery_mode='push', so the desktop specs that expect inline Echo responses actually dispatch to canvas/e2e/fixtures/echo-runtime.ts instead of being short-circuited through the external-runtime poll default.
CI/code checks for this head are green: E2E Chat is green and Canvas (Next.js) completed successfully. Remaining red statuses are review/ceremony gates, not a code issue for this verdict.
sop-ack: independent 5-axis review completed for the current head.
COMMENT on head
4524e49c.Code re-review: #11517 is resolved. The psql calls now use
execFileSync("psql", ["-h", host, "-p", port, "-U", user, "-d", db, "-c", sql], { env: { ...process.env, PGPASSWORD: pass } }), so the SQL is passed as an argv element rather than through shell double-quote parsing. JSON double quotes inrequest_body/response_bodyare preserved, and the seeded chat-history regression includes messages with literal double quotes and asserts they render.The other harness fixes are also sound:
E2E_API_URLfalls back toE2E_PLATFORM_URL, avoiding localhost:8080 on ephemeral-port CI;seedChatHistorytargetsactivity_logswithactivity_type='a2a_receive'andsource_id IS NULL, matching MessageStore's canvas-origin query; andseedWorkspacenow setsdelivery_mode='push', which addresses the desktop echo fixture's push/poll mismatch. E2E Chat is green on this head.Holding approval only because required CI is not green yet: after a bounded poll,
CI / Canvas (Next.js)is still pending and the combined state remains failure with checklist/gate contexts red. Once required CI/all-required is green, this is approvable from my code review.