From 5f92f8c220ccc0106fb35142fe89c91c3290b6d7 Mon Sep 17 00:00:00 2001 From: Jinwoo-H Date: Fri, 4 Sep 2026 15:29:36 -0400 Subject: [PATCH] fix(orchestration): keep dispatch.task_id on the workerShow receipt exposeDispatchContext renamed task_id to taskId, and every shipped CLI prints value.dispatch.task_id, so an older paired CLI against an updated host printed task=undefined. Publish both spellings. exposeWorker's dropped columns have no reader in main's src/cli, which reads only state and stage. --- .../worker/worker-observation.test.ts | 28 +++++++++++++++++-- .../worker/worker-observation.ts | 3 ++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/main/runtime/rpc/methods/orchestration/worker/worker-observation.test.ts b/src/main/runtime/rpc/methods/orchestration/worker/worker-observation.test.ts index 01da4b9738f..ba920a9597a 100644 --- a/src/main/runtime/rpc/methods/orchestration/worker/worker-observation.test.ts +++ b/src/main/runtime/rpc/methods/orchestration/worker/worker-observation.test.ts @@ -119,7 +119,31 @@ describe('worker-show receipt shape', () => { expect(exposed).not.toHaveProperty('host_scope') expect(exposed).not.toHaveProperty('launch_token_hash') expect(exposed).not.toHaveProperty('capability_hash') - // The row shipped raw beside a camelCase `worker`; no snake_case key may survive. - expect(Object.keys(exposed).filter((key) => key.includes('_'))).toEqual([]) + // The row shipped raw beside a camelCase `worker`; only the one spelling an older + // paired CLI still prints may survive. + expect(Object.keys(exposed).filter((key) => key.includes('_'))).toEqual(['task_id']) + }) + + // A paired CLI and host update independently, so an older CLI reads this receipt. + // These are the fields it prints: src/cli/handlers/orchestration/ + // worker-observation-handlers.ts:18-19,25. + it('keeps every field an older paired CLI prints', () => { + const dispatch = exposeDispatchContext({ + id: DISPATCH_ID, + run_id: 'run-1', + task_id: 'task-1', + status: 'dispatched' + } as DispatchContextRow) + + expect(dispatch).toMatchObject({ id: DISPATCH_ID, task_id: 'task-1', status: 'dispatched' }) + expect( + exposeWorker({ + state: 'ready', + stage: 'input_accepted', + effects: '[]', + residual_resources: '[]', + start_options: '{}' + } as WorkerDispatchRow) + ).toMatchObject({ state: 'ready', stage: 'input_accepted' }) }) }) diff --git a/src/main/runtime/rpc/methods/orchestration/worker/worker-observation.ts b/src/main/runtime/rpc/methods/orchestration/worker/worker-observation.ts index 96aeb47c33e..a04ddf86569 100644 --- a/src/main/runtime/rpc/methods/orchestration/worker/worker-observation.ts +++ b/src/main/runtime/rpc/methods/orchestration/worker/worker-observation.ts @@ -123,6 +123,9 @@ export function exposeDispatchContext(dispatch: DispatchContextRow) { id: dispatch.id, runId: dispatch.run_id, taskId: dispatch.task_id, + // Every shipped CLI prints `dispatch.task_id`, and mixed client/host versions are the + // normal state, so the rename ships beside the spelling old clients still read. + task_id: dispatch.task_id, contractVersion: dispatch.contract_version, assigneeHandle: dispatch.assignee_handle, assigneePaneKey: dispatch.assignee_pane_key,