// SPEC: PJ2026-0104010803 Workbench唯一投影 draft-2026-06-20-p2-terminal-outbox-recovery; PJ2026-01060505 Workbench Performance draft-2026-06-17-p0.
// Responsibility: Cloud API AgentRun read lifecycle, Codex fallback, inspect, and cancel regression tests.

import assert from "node:assert/strict";
import { createServer as createHttpServer } from "node:http";
import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { test } from "bun:test";

import { createCloudApiServer } from "./server.ts";
import { createCloudRuntimeStore } from "../db/runtime-store.ts";
import { validateCodeAgentChatSchema } from "./code-agent-chat.ts";
import { createCodexStdioSessionManager } from "./codex-stdio-session.ts";
import { createCodeAgentTraceStore } from "./code-agent-trace-store.ts";
import { submitAgentRunChatTurn } from "./code-agent-agentrun-adapter.ts";
import {
  codexStdioChatFixture,
  codexStdioReadyFixture,
  createFakeAppServerClient,
  createFakeCodexCommand,
  createManualAgentSession,
  delay,
  ensureTestAgentAuth,
  pollAgentResult,
  postAgent,
  postAgentRaw,
  prepareFakeCodexHome
} from "./server-test-helpers.ts";

const TEST_AGENT_ACTOR = { id: "usr_agent_owner", username: "agent-owner", displayName: "Agent Owner", role: "user", status: "active" };
const TEST_AUTH_SESSION = { id: "auth_ses_agent_owner" };

function testAgentSessionRecord(input = {}) {
  const sessionId = input.sessionId ?? input.id;
  return {
    id: sessionId,
    sessionId,
    projectId: input.projectId ?? "pikasTech/HWLAB",
    agentId: input.agentId ?? "hwlab-code-agent",
    status: input.status ?? "idle",
    ownerUserId: input.ownerUserId ?? TEST_AGENT_ACTOR.id,
    ownerRole: input.ownerRole ?? TEST_AGENT_ACTOR.role,
    conversationId: input.conversationId ?? null,
    threadId: input.threadId ?? null,
    lastTraceId: input.traceId ?? input.lastTraceId ?? null,
    session: input.session ?? {},
    updatedAt: input.updatedAt ?? "2026-06-03T00:00:00.000Z"
  };
}

test("cloud api trace skips AgentRun refresh when terminal snapshot is already complete (#1422)", async () => {
  const calls = [];
  const traceId = "trc_issue1422_trace_terminal_snapshot";
  const runId = "run_issue1422_trace_terminal_snapshot";
  const commandId = "cmd_issue1422_trace_terminal_snapshot";
  const finalText = "trace endpoint should reuse the local terminal snapshot.";
  const agentRunServer = createHttpServer(async (request, response) => {
    const url = new URL(request.url || "/", "http://127.0.0.1");
    calls.push({ method: request.method, path: url.pathname, search: url.search });
    response.writeHead(500, { "content-type": "application/json" });
    response.end(`${JSON.stringify({ ok: false, message: `unexpected refresh ${request.method} ${url.pathname}` })}\n`);
  });
  await new Promise((resolve) => agentRunServer.listen(0, "127.0.0.1", resolve));

  const agentRunPort = agentRunServer.address().port;
  const traceStore = createCodeAgentTraceStore();
  traceStore.append(traceId, {
    type: "backend",
    status: "running",
    label: "agentrun:backend:runner-job-created",
    source: "agentrun",
    sourceSeq: 1,
    runId,
    commandId,
    valuesPrinted: false
  });
  traceStore.append(traceId, {
    type: "result",
    status: "completed",
    label: "agentrun:terminal:completed",
    source: "agentrun",
    sourceSeq: 3,
    runId,
    commandId,
    terminal: true,
    valuesPrinted: false
  });
  const codeAgentChatResults = new Map([[traceId, {
    accepted: true,
    status: "completed",
    shortConnection: true,
    traceId,
    conversationId: "cnv_issue1422_trace_terminal_snapshot",
    sessionId: "ses_issue1422_trace_terminal_snapshot",
    threadId: "thread-issue1422-trace-terminal-snapshot",
    ownerUserId: TEST_AGENT_ACTOR.id,
    ownerRole: TEST_AGENT_ACTOR.role,
    finalResponse: { text: finalText, textChars: finalText.length, role: "assistant", status: "completed", traceId, valuesPrinted: false },
    traceSummary: {
      traceId,
      source: "agentrun-command-result",
      sourceEventCount: 3,
      terminalStatus: "completed",
      agentRun: { runId, commandId, lastSeq: 3, valuesPrinted: false },
      valuesPrinted: false
    },
    agentRun: {
      adapter: "agentrun-v01",
      managerUrl: `http://127.0.0.1:${agentRunPort}`,
      runId,
      commandId,
      traceId,
      lastSeq: 3,
      status: "completed",
      commandState: "completed",
      terminalStatus: "completed",
      providerTrace: { traceId, runId, commandId, terminalStatus: "completed", valuesPrinted: false },
      valuesPrinted: false
    },
    providerTrace: { traceId, runId, commandId, terminalStatus: "completed", valuesPrinted: false },
    valuesPrinted: false
  }]]);
  const server = createCloudApiServer({
    traceStore,
    codeAgentChatResults,
    env: {
      HWLAB_CODE_AGENT_ADAPTER: "agentrun-v01",
      AGENTRUN_MGR_URL: `http://127.0.0.1:${agentRunPort}`,
      HWLAB_CODE_AGENT_AGENTRUN_ALLOW_NON_K3S_URL: "1",
      HWLAB_CODE_AGENT_AGENTRUN_PROVIDER_ID: "D601",
      HWLAB_ENVIRONMENT: "v02",
      HWLAB_GITOPS_PROFILE: "v02"
    },
    accessController: {
      required: false,
      async authenticate() {
        return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION };
      }
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const response = await fetch(`http://127.0.0.1:${port}/v1/agent/traces/${traceId}?limit=1`, {
      headers: { cookie: "hwlab_session=test-stub-session" }
    });
    assert.equal(response.status, 200);
    const body = await response.json();
    assert.equal(body.status, "completed");
    assert.equal(body.eventCount, 2);
    assert.equal(body.agentRun.commandId, commandId);
    assert.equal(body.finalResponse.text, finalText);
    assert.deepEqual(calls, []);
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
    await new Promise((resolve, reject) => {
      agentRunServer.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("cloud api trace does not schedule terminal side effects from GET reads (#1519)", async () => {
  const ownerCalls = [];
  const factCalls = [];
  let releaseOwnerWrite;
  let ownerWriteReleased = false;
  const ownerWrite = new Promise((resolve) => {
    releaseOwnerWrite = () => {
      if (ownerWriteReleased) return;
      ownerWriteReleased = true;
      resolve();
    };
  });
  const traceId = "trc_issue1422_trace_effects_async";
  const runId = "run_issue1422_trace_effects_async";
  const commandId = "cmd_issue1422_trace_effects_async";
  const finalText = "trace reads should not wait for terminal side effects.";
  const traceStore = createCodeAgentTraceStore();
  traceStore.append(traceId, {
    type: "backend",
    status: "running",
    label: "agentrun:backend:run-created",
    source: "agentrun",
    sourceSeq: 1,
    runId,
    commandId,
    valuesPrinted: false
  });
  traceStore.append(traceId, {
    type: "result",
    status: "completed",
    label: "agentrun:terminal:completed",
    source: "agentrun",
    sourceSeq: 3,
    runId,
    commandId,
    terminal: true,
    valuesPrinted: false
  });
  const codeAgentChatResults = new Map([[traceId, {
    accepted: true,
    status: "completed",
    shortConnection: true,
    traceId,
    conversationId: "cnv_issue1422_trace_effects_async",
    sessionId: "ses_issue1422_trace_effects_async",
    threadId: "thread-issue1422-trace-effects-async",
    ownerUserId: TEST_AGENT_ACTOR.id,
    ownerRole: TEST_AGENT_ACTOR.role,
    finalResponse: { text: finalText, textChars: finalText.length, role: "assistant", status: "completed", traceId, valuesPrinted: false },
    traceSummary: {
      traceId,
      source: "agentrun-command-result",
      sourceEventCount: 3,
      terminalStatus: "completed",
      finalAssistantRow: { role: "assistant", status: "completed", textChars: finalText.length, textPreview: finalText, messageId: `msg_${traceId.slice(4)}`, valuesPrinted: false },
      agentRun: { runId, commandId, lastSeq: 3, valuesPrinted: false },
      valuesPrinted: false
    },
    agentRun: {
      adapter: "agentrun-v01",
      managerUrl: "http://127.0.0.1:1",
      runId,
      commandId,
      traceId,
      lastSeq: 3,
      status: "completed",
      commandState: "completed",
      terminalStatus: "completed",
      providerTrace: { traceId, runId, commandId, terminalStatus: "completed", valuesPrinted: false },
      valuesPrinted: false
    },
    providerTrace: { traceId, runId, commandId, terminalStatus: "completed", valuesPrinted: false },
    valuesPrinted: false
  }]]);
  const server = createCloudApiServer({
    traceStore,
    codeAgentChatResults,
    env: {
      HWLAB_CODE_AGENT_ADAPTER: "agentrun-v01",
      HWLAB_CODE_AGENT_AGENTRUN_PROVIDER_ID: "D601",
      HWLAB_ENVIRONMENT: "v02",
      HWLAB_GITOPS_PROFILE: "v02"
    },
    sessionRegistry: {
      recordFact(conversationId, fact) {
        factCalls.push({ conversationId, fact });
        return { ok: true };
      }
    },
    accessController: {
      required: false,
      async authenticate() {
        return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION };
      },
      async recordAgentSessionOwner(input) {
        ownerCalls.push(input);
        await ownerWrite;
        return { ok: true, sessionId: input.sessionId };
      }
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const fetchTrace = async () => {
      const response = await Promise.race([
        fetch(`http://127.0.0.1:${port}/v1/agent/traces/${traceId}?limit=1`, {
          headers: { cookie: "hwlab_session=test-stub-session" }
        }),
        delay(250).then(() => null)
      ]);
      assert.ok(response, "trace read should not wait for terminal side effects to finish");
      assert.equal(response.status, 200);
      const body = await response.json();
      assert.equal(body.status, "completed");
      assert.equal(body.eventCount, 2);
      assert.equal(body.finalResponse.text, finalText);
    };
    for (let i = 0; i < 2; i += 1) {
      await fetchTrace();
    }
    for (let i = 0; i < 20 && ownerCalls.length < 1; i += 1) await delay(10);
    assert.equal(ownerCalls.length, 0);
    assert.equal(factCalls.length, 0);
    assert.equal(codeAgentChatResults.get(traceId).turnStatusTerminalEffects, undefined);
    releaseOwnerWrite();
    assert.equal(codeAgentChatResults.get(traceId).turnStatusTerminalEffects, undefined);
  } finally {
    releaseOwnerWrite?.();
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("cloud api turn status skips AgentRun refresh for complete terminal evidence (#1422)", async () => {
  const calls = [];
  const traceId = "trc_issue1422_terminal_fast_path";
  const runId = "run_issue1422_terminal_fast_path";
  const commandId = "cmd_issue1422_terminal_fast_path";
  const finalText = "终态结果已经由 AgentRun command result 投影完成。";
  const agentRunServer = createHttpServer(async (request, response) => {
    const url = new URL(request.url || "/", "http://127.0.0.1");
    calls.push({ method: request.method, path: url.pathname, search: url.search });
    response.writeHead(500, { "content-type": "application/json" });
    response.end(`${JSON.stringify({ ok: false, message: `unexpected refresh ${request.method} ${url.pathname}` })}\n`);
  });
  await new Promise((resolve) => agentRunServer.listen(0, "127.0.0.1", resolve));

  const agentRunPort = agentRunServer.address().port;
  const codeAgentChatResults = new Map([[traceId, {
    accepted: true,
    status: "completed",
    shortConnection: true,
    traceId,
    conversationId: "cnv_issue1422_terminal_fast_path",
    sessionId: "ses_issue1422_terminal_fast_path",
    threadId: "thread-issue1422-terminal-fast-path",
    ownerUserId: TEST_AGENT_ACTOR.id,
    ownerRole: TEST_AGENT_ACTOR.role,
    finalResponse: { text: finalText, textChars: finalText.length, role: "assistant", status: "completed", traceId, valuesPrinted: false },
    traceSummary: {
      traceId,
      source: "agentrun-command-result",
      sourceEventCount: 3,
      terminalStatus: "completed",
      finalAssistantRow: { role: "assistant", status: "completed", textChars: finalText.length, textPreview: finalText, messageId: `msg_${traceId.slice(4)}`, valuesPrinted: false },
      agentRun: { runId, commandId, lastSeq: 3, valuesPrinted: false },
      valuesPrinted: false
    },
    agentRun: {
      adapter: "agentrun-v01",
      managerUrl: `http://127.0.0.1:${agentRunPort}`,
      runId,
      commandId,
      traceId,
      lastSeq: 3,
      status: "completed",
      commandState: "completed",
      terminalStatus: "completed",
      providerTrace: { traceId, runId, commandId, terminalStatus: "completed", valuesPrinted: false },
      valuesPrinted: false
    },
    providerTrace: { traceId, runId, commandId, terminalStatus: "completed", valuesPrinted: false },
    valuesPrinted: false
  }]]);
  const server = createCloudApiServer({
    traceStore: createCodeAgentTraceStore(),
    codeAgentChatResults,
    env: {
      HWLAB_CODE_AGENT_ADAPTER: "agentrun-v01",
      AGENTRUN_MGR_URL: `http://127.0.0.1:${agentRunPort}`,
      HWLAB_CODE_AGENT_AGENTRUN_ALLOW_NON_K3S_URL: "1",
      HWLAB_CODE_AGENT_AGENTRUN_PROVIDER_ID: "D601",
      HWLAB_ENVIRONMENT: "v02",
      HWLAB_GITOPS_PROFILE: "v02"
    },
    accessController: {
      required: false,
      async authenticate() {
        return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION };
      }
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const response = await fetch(`http://127.0.0.1:${port}/v1/agent/turns/${traceId}`, {
      headers: { cookie: "hwlab_session=test-stub-session" }
    });
    assert.equal(response.status, 200);
    const body = await response.json();
    assert.equal(body.status, "completed");
    assert.equal(body.terminal, true);
    assert.equal(body.finalResponse.text, finalText);
    assert.equal(body.traceSummary.agentRun.commandId, commandId);
    assert.deepEqual(calls, []);
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
    await new Promise((resolve, reject) => {
      agentRunServer.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("cloud api turn status does not record terminal side effects from GET reads (#1519)", async () => {
  const ownerCalls = [];
  const factCalls = [];
  let releaseOwnerWrite;
  let ownerWriteReleased = false;
  const ownerWrite = new Promise((resolve) => {
    releaseOwnerWrite = () => {
      if (ownerWriteReleased) return;
      ownerWriteReleased = true;
      resolve();
    };
  });
  const traceId = "trc_issue1422_terminal_effects_once";
  const runId = "run_issue1422_terminal_effects_once";
  const commandId = "cmd_issue1422_terminal_effects_once";
  const finalText = "终态副作用只需要收敛一次。";
  const codeAgentChatResults = new Map([[traceId, {
    accepted: true,
    status: "completed",
    shortConnection: true,
    traceId,
    conversationId: "cnv_issue1422_terminal_effects_once",
    sessionId: "ses_issue1422_terminal_effects_once",
    threadId: "thread-issue1422-terminal-effects-once",
    ownerUserId: TEST_AGENT_ACTOR.id,
    ownerRole: TEST_AGENT_ACTOR.role,
    finalResponse: { text: finalText, textChars: finalText.length, role: "assistant", status: "completed", traceId, valuesPrinted: false },
    traceSummary: {
      traceId,
      source: "agentrun-command-result",
      sourceEventCount: 3,
      terminalStatus: "completed",
      finalAssistantRow: { role: "assistant", status: "completed", textChars: finalText.length, textPreview: finalText, messageId: `msg_${traceId.slice(4)}`, valuesPrinted: false },
      agentRun: { runId, commandId, lastSeq: 3, valuesPrinted: false },
      valuesPrinted: false
    },
    agentRun: {
      adapter: "agentrun-v01",
      managerUrl: "http://127.0.0.1:1",
      runId,
      commandId,
      traceId,
      lastSeq: 3,
      status: "completed",
      commandState: "completed",
      terminalStatus: "completed",
      providerTrace: { traceId, runId, commandId, terminalStatus: "completed", valuesPrinted: false },
      valuesPrinted: false
    },
    providerTrace: { traceId, runId, commandId, terminalStatus: "completed", valuesPrinted: false },
    valuesPrinted: false
  }]]);
  const server = createCloudApiServer({
    traceStore: createCodeAgentTraceStore(),
    codeAgentChatResults,
    env: {
      HWLAB_CODE_AGENT_ADAPTER: "agentrun-v01",
      HWLAB_CODE_AGENT_AGENTRUN_PROVIDER_ID: "D601",
      HWLAB_ENVIRONMENT: "v02",
      HWLAB_GITOPS_PROFILE: "v02"
    },
    sessionRegistry: {
      recordFact(conversationId, fact) {
        factCalls.push({ conversationId, fact });
        return { ok: true };
      }
    },
    accessController: {
      required: false,
      async authenticate() {
        return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION };
      },
      async recordAgentSessionOwner(input) {
        ownerCalls.push(input);
        await ownerWrite;
        return { ok: true, sessionId: input.sessionId };
      }
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const fetchTurnStatus = async () => {
      const response = await Promise.race([
        fetch(`http://127.0.0.1:${port}/v1/agent/turns/${traceId}`, {
          headers: { cookie: "hwlab_session=test-stub-session" }
        }),
        delay(250).then(() => null)
      ]);
      assert.ok(response, "turn status should not wait for terminal side effects to finish");
      assert.equal(response.status, 200);
      const body = await response.json();
      assert.equal(body.status, "completed");
      assert.equal(body.finalResponse.text, finalText);
    };
    for (let i = 0; i < 2; i += 1) {
      await fetchTurnStatus();
    }
    for (let i = 0; i < 20 && ownerCalls.length < 1; i += 1) await delay(10);
    assert.equal(ownerCalls.length, 0);
    assert.equal(factCalls.length, 0);
    assert.equal(codeAgentChatResults.get(traceId).turnStatusTerminalEffects, undefined);
    releaseOwnerWrite();
    assert.equal(codeAgentChatResults.get(traceId).turnStatusTerminalEffects, undefined);
  } finally {
    releaseOwnerWrite?.();
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("cloud api legacy trace read does not repair historical AgentRun trace after lastTraceId advances (#1519)", async () => {
  const calls = [];
  const ownerSessions = new Map();
  const runId = "run_issue955_historical";
  const firstTraceId = "trc_issue955_historical_first";
  const secondTraceId = "trc_issue955_historical_second";
  const firstCommandId = "cmd_issue955_historical_first";
  const secondCommandId = "cmd_issue955_historical_second";
  const firstFinalText = "目前只有一个 HWPOD 可用：\n\n- d601-f103-v2 (board: D601-F103-V2 / STM32F103)\n\nAPI 返回 count=1, availableCount=1。";
  const secondFinalText = "编译成功！hwpod build completed。";
  const events = [
    { id: "evt_issue955_hist_first_created", runId, seq: 1, type: "command_created", payload: { commandId: firstCommandId }, createdAt: "2026-06-06T01:43:23.000Z" },
    { id: "evt_issue955_hist_first_tool", runId, seq: 25, type: "tool_call", payload: { method: "item/completed", type: "commandExecution", toolName: "commandExecution", itemId: "call_issue955_hwpod_list", command: "/bin/sh -lc 'hwpod list --available'", status: "completed", exitCode: 0, outputSummary: '{\"count\":1,\"availableCount\":1}', commandId: firstCommandId }, createdAt: "2026-06-06T01:43:46.000Z" },
    { id: "evt_issue955_hist_first_message", runId, seq: 34, type: "assistant_message", payload: { commandId: firstCommandId, itemId: "msg_issue955_first", text: firstFinalText }, createdAt: "2026-06-06T01:46:19.000Z" },
    { id: "evt_issue955_hist_first_done", runId, seq: 35, type: "terminal_status", payload: { commandId: firstCommandId, terminalStatus: "completed" }, createdAt: "2026-06-06T01:46:19.000Z" },
    { id: "evt_issue955_hist_second_created", runId, seq: 36, type: "command_created", payload: { commandId: secondCommandId }, createdAt: "2026-06-06T01:46:11.000Z" },
    { id: "evt_issue955_hist_second_message", runId, seq: 58, type: "assistant_message", payload: { commandId: secondCommandId, itemId: "msg_issue955_second", text: secondFinalText }, createdAt: "2026-06-06T01:46:28.000Z" },
    { id: "evt_issue955_hist_second_done", runId, seq: 67, type: "terminal_status", payload: { commandId: secondCommandId, terminalStatus: "completed" }, createdAt: "2026-06-06T01:46:28.000Z" }
  ];
  const agentRunServer = createHttpServer(async (request, response) => {
    const url = new URL(request.url || "/", "http://127.0.0.1");
    calls.push({ method: request.method, path: url.pathname, search: url.search });
    const send = (data) => {
      response.writeHead(200, { "content-type": "application/json" });
      response.end(`${JSON.stringify({ ok: true, data, traceId: "trc_fake_issue955_historical" })}\n`);
    };
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/commands`) {
      return send({ items: [
        { id: firstCommandId, runId, state: "completed", idempotencyKey: firstTraceId, createdAt: "2026-06-06T01:43:30.040Z", updatedAt: "2026-06-06T01:43:46.360Z", payload: { traceId: firstTraceId, conversationId: "cnv_issue955_historical", hwlabSessionId: "ses_issue955_historical", threadId: "thread-issue955-historical", providerProfile: "deepseek" } },
        { id: secondCommandId, runId, state: "completed", idempotencyKey: secondTraceId, createdAt: "2026-06-06T01:46:11.000Z", updatedAt: "2026-06-06T01:46:28.000Z", payload: { traceId: secondTraceId, conversationId: "cnv_issue955_historical", hwlabSessionId: "ses_issue955_historical", threadId: "thread-issue955-historical", providerProfile: "deepseek" } }
      ] });
    }
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/commands/${firstCommandId}/result`) {
      return send({ runId, commandId: firstCommandId, status: "completed", runStatus: "completed", commandState: "completed", terminalStatus: "completed", completed: true, reply: firstFinalText, lastSeq: 35, eventCount: 35, sessionRef: { sessionId: "ses_agentrun_deepseek_issue955", conversationId: "cnv_issue955_historical", threadId: "thread-issue955-historical" } });
    }
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/commands/${secondCommandId}/result`) {
      return send({ runId, commandId: secondCommandId, status: "completed", runStatus: "completed", commandState: "completed", terminalStatus: "completed", completed: true, reply: secondFinalText, lastSeq: 67, eventCount: 67, sessionRef: { sessionId: "ses_agentrun_deepseek_issue955", conversationId: "cnv_issue955_historical", threadId: "thread-issue955-historical" } });
    }
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/events`) {
      return send({ items: events });
    }
    response.writeHead(404, { "content-type": "application/json" });
    response.end(`${JSON.stringify({ ok: false, message: `unexpected ${request.method} ${url.pathname}` })}\n`);
  });
  await new Promise((resolve) => agentRunServer.listen(0, "127.0.0.1", resolve));

  const agentRunPort = agentRunServer.address().port;
  ownerSessions.set("ses_issue955_historical", testAgentSessionRecord({
    sessionId: "ses_issue955_historical",
    projectId: "prj_v02_code_agent",
    conversationId: "cnv_issue955_historical",
    threadId: "thread-issue955-historical",
    lastTraceId: secondTraceId,
    status: "active",
    session: {
      messages: [
        { id: "msg_issue955_user_first", role: "user", text: "看看有几个hwpod可用", traceId: firstTraceId, status: "submitted" },
        { id: "msg_issue955_user_second", role: "user", text: "试一下编译 d601-f103-v2", traceId: secondTraceId, status: "submitted" },
        { id: "msg_issue955_second", role: "agent", text: firstFinalText, traceId: secondTraceId, status: "idle" }
      ],
      agentRun: { adapter: "agentrun-v01", managerUrl: `http://127.0.0.1:${agentRunPort}`, runId, commandId: firstCommandId, backendProfile: "deepseek", terminalStatus: "completed", lastSeq: 35, valuesPrinted: false },
      finalResponse: { text: firstFinalText, textChars: firstFinalText.length, role: "assistant", status: "completed", traceId: secondTraceId, valuesPrinted: false },
      traceSummary: { traceId: secondTraceId, source: "code-agent-derived-session-evidence", sourceEventCount: 36, terminalStatus: "completed", agentRun: { runId, commandId: firstCommandId, lastSeq: 35, valuesPrinted: false }, valuesPrinted: false },
      traceResults: {
        [secondTraceId]: {
          traceId: secondTraceId,
          status: "completed",
          conversationId: "cnv_issue955_historical",
          sessionId: "ses_issue955_historical",
          threadId: "thread-issue955-historical",
          finalResponse: { text: firstFinalText, textChars: firstFinalText.length, role: "assistant", status: "completed", traceId: secondTraceId, valuesPrinted: false },
          traceSummary: { traceId: secondTraceId, source: "agent-session-trace-repair", sourceEventCount: 4, terminalStatus: "completed", agentRun: { runId, commandId: firstCommandId, lastSeq: 35, valuesPrinted: false }, valuesPrinted: false },
          agentRun: { adapter: "agentrun-v01", managerUrl: `http://127.0.0.1:${agentRunPort}`, runId, commandId: firstCommandId, backendProfile: "deepseek", terminalStatus: "completed", lastSeq: 35, valuesPrinted: false },
          valuesRedacted: true
        }
      },
      valuesRedacted: true
    }
  }));

  const server = createCloudApiServer({
    traceStore: createCodeAgentTraceStore(),
    env: {
      HWLAB_CODE_AGENT_ADAPTER: "agentrun-v01",
      AGENTRUN_MGR_URL: `http://127.0.0.1:${agentRunPort}`,
      HWLAB_CODE_AGENT_AGENTRUN_ALLOW_NON_K3S_URL: "1",
      HWLAB_CODE_AGENT_AGENTRUN_PROVIDER_ID: "D601",
      HWLAB_ENVIRONMENT: "v02",
      HWLAB_GITOPS_PROFILE: "v02"
    },
    accessController: {
      required: false,
      async authenticate() {
        return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION };
      },
      async getAgentSessionByTraceId(traceId) {
        return [...ownerSessions.values()].find((session) => session.lastTraceId === traceId || session.session?.messages?.some((message) => message.traceId === traceId)) ?? null;
      },
      async recordAgentSessionOwner(input) {
        const existing = ownerSessions.get(input.sessionId) ?? testAgentSessionRecord(input);
        const nextSession = { ...(existing.session ?? {}), ...(input.session ?? {}) };
        nextSession.traceResults = { ...(existing.session?.traceResults ?? {}), ...(input.session?.traceResults ?? {}) };
        const record = testAgentSessionRecord({ ...existing, ...input, session: nextSession });
        ownerSessions.set(record.id, record);
        return record;
      }
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const response = await fetch(`http://127.0.0.1:${port}/v1/agent/traces/${firstTraceId}`, {
      headers: { cookie: "hwlab_session=test-stub-session" }
    });
    assert.equal(response.status, 200);
    const body = await response.json();
    assert.equal(body.traceId, firstTraceId);
    assert.equal(body.status, "missing");
    assert.equal(body.projectionStatus, "unknown");
    assert.equal(body.eventCount, 0);
    assert.deepEqual(calls, []);
    assert.equal(ownerSessions.get("ses_issue955_historical").session.traceResults[firstTraceId], undefined);

    const secondResultResponse = await fetch(`http://127.0.0.1:${port}/v1/agent/chat/result/${secondTraceId}`, {
      headers: { cookie: "hwlab_session=test-stub-session" }
    });
    assert.equal(secondResultResponse.status, 200);
    const secondResult = await secondResultResponse.json();
    assert.equal(secondResult.traceId, secondTraceId);
    assert.equal(secondResult.projectionStatus, "caught-up");
    assert.equal(secondResult.agentRun.commandId, firstCommandId);
    assert.deepEqual(calls, []);
    assert.equal(ownerSessions.get("ses_issue955_historical").session.traceResults[secondTraceId].agentRun.commandId, firstCommandId);
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
    await new Promise((resolve, reject) => {
      agentRunServer.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("cloud api result polling does not repair polluted completed AgentRun memory cache (#1519)", async () => {
  const calls = [];
  const runId = "run_issue955_live_cache";
  const firstTraceId = "trc_issue955_live_cache_first";
  const secondTraceId = "trc_issue955_live_cache_second";
  const firstCommandId = "cmd_issue955_live_cache_first";
  const secondCommandId = "cmd_issue955_live_cache_second";
  const firstFinalText = "目前只有一个 HWPOD 可用：d601-f103-v2。";
  const secondFinalText = "编译成功！hwpod build completed，Keil MDK USART atk_f103.hex queued。";
  const events = [
    { id: "evt_issue955_live_first_message", runId, seq: 10, type: "assistant_message", payload: { commandId: firstCommandId, itemId: "msg_issue955_live_first", text: firstFinalText }, createdAt: "2026-06-06T01:46:19.000Z" },
    { id: "evt_issue955_live_first_done", runId, seq: 11, type: "terminal_status", payload: { commandId: firstCommandId, terminalStatus: "completed" }, createdAt: "2026-06-06T01:46:19.000Z" },
    { id: "evt_issue955_live_second_message", runId, seq: 20, type: "assistant_message", payload: { commandId: secondCommandId, itemId: "msg_issue955_live_second", text: secondFinalText }, createdAt: "2026-06-06T01:46:28.000Z" },
    { id: "evt_issue955_live_second_done", runId, seq: 21, type: "terminal_status", payload: { commandId: secondCommandId, terminalStatus: "completed" }, createdAt: "2026-06-06T01:46:28.000Z" }
  ];
  const agentRunServer = createHttpServer(async (request, response) => {
    const url = new URL(request.url || "/", "http://127.0.0.1");
    calls.push({ method: request.method, path: url.pathname, search: url.search });
    const send = (data) => {
      response.writeHead(200, { "content-type": "application/json" });
      response.end(`${JSON.stringify({ ok: true, data, traceId: "trc_fake_issue955_live_cache" })}\n`);
    };
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/commands`) {
      return send({ items: [
        { id: firstCommandId, runId, state: "completed", idempotencyKey: firstTraceId, payload: { traceId: firstTraceId, conversationId: "cnv_issue955_live_cache", hwlabSessionId: "ses_issue955_live_cache", threadId: "thread-issue955-live-cache" } },
        { id: secondCommandId, runId, state: "completed", idempotencyKey: secondTraceId, payload: { traceId: secondTraceId, conversationId: "cnv_issue955_live_cache", hwlabSessionId: "ses_issue955_live_cache", threadId: "thread-issue955-live-cache" } }
      ] });
    }
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/commands/${firstCommandId}/result`) {
      return send({ runId, commandId: firstCommandId, status: "completed", runStatus: "completed", commandState: "completed", terminalStatus: "completed", completed: true, reply: firstFinalText, lastSeq: 11, eventCount: 11 });
    }
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/commands/${secondCommandId}/result`) {
      return send({ runId, commandId: secondCommandId, status: "completed", runStatus: "completed", commandState: "completed", terminalStatus: "completed", completed: true, reply: secondFinalText, lastSeq: 21, eventCount: 21 });
    }
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/events`) {
      return send({ items: events });
    }
    response.writeHead(404, { "content-type": "application/json" });
    response.end(`${JSON.stringify({ ok: false, message: `unexpected ${request.method} ${url.pathname}` })}\n`);
  });
  await new Promise((resolve) => agentRunServer.listen(0, "127.0.0.1", resolve));

  const agentRunPort = agentRunServer.address().port;
  const codeAgentChatResults = new Map();
  codeAgentChatResults.set(secondTraceId, {
    accepted: true,
    status: "completed",
    shortConnection: true,
    traceId: secondTraceId,
    conversationId: "cnv_issue955_live_cache",
    sessionId: "ses_issue955_live_cache",
    threadId: "thread-issue955-live-cache",
    ownerUserId: TEST_AGENT_ACTOR.id,
    ownerRole: TEST_AGENT_ACTOR.role,
    reply: { role: "assistant", content: firstFinalText },
    finalResponse: { text: firstFinalText, textChars: firstFinalText.length, role: "assistant", status: "completed", traceId: secondTraceId, valuesPrinted: false },
    traceSummary: { traceId: secondTraceId, source: "code-agent-derived-session-evidence", sourceEventCount: 11, terminalStatus: "completed", agentRun: { runId, commandId: firstCommandId, lastSeq: 11, valuesPrinted: false }, valuesPrinted: false },
    agentRun: {
      adapter: "agentrun-v01",
      managerUrl: `http://127.0.0.1:${agentRunPort}`,
      runId,
      commandId: firstCommandId,
      traceId: secondTraceId,
      lastSeq: 11,
      terminalStatus: "completed",
      providerTrace: { traceId: secondTraceId, runId, commandId: firstCommandId, terminalStatus: "completed", valuesPrinted: false },
      valuesPrinted: false
    },
    providerTrace: { traceId: secondTraceId, runId, commandId: firstCommandId, terminalStatus: "completed", valuesPrinted: false },
    valuesPrinted: false
  });

  const server = createCloudApiServer({
    traceStore: createCodeAgentTraceStore(),
    codeAgentChatResults,
    env: {
      HWLAB_CODE_AGENT_ADAPTER: "agentrun-v01",
      AGENTRUN_MGR_URL: `http://127.0.0.1:${agentRunPort}`,
      HWLAB_CODE_AGENT_AGENTRUN_ALLOW_NON_K3S_URL: "1",
      HWLAB_CODE_AGENT_AGENTRUN_PROVIDER_ID: "D601",
      HWLAB_ENVIRONMENT: "v02",
      HWLAB_GITOPS_PROFILE: "v02"
    },
    accessController: {
      required: false,
      async authenticate() {
        return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION };
      }
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const response = await fetch(`http://127.0.0.1:${port}/v1/agent/chat/result/${secondTraceId}`, {
      headers: { cookie: "hwlab_session=test-stub-session" }
    });
    assert.equal(response.status, 200);
    const body = await response.json();
    const text = JSON.stringify(body);
    assert.equal(body.traceId, secondTraceId);
    assert.equal(body.status, "completed");
    assert.equal(body.projectionStatus, "caught-up");
    assert.equal(body.agentRun.commandId, firstCommandId);
    assert.equal(body.agentRun.traceId, secondTraceId);
    assert.equal(body.terminalEvidence.available, true);
    assert.equal(body.terminalEvidence.agentRun.commandId, firstCommandId);
    assert.equal(body.terminalEvidence.finalResponse.traceId, secondTraceId);
    assert.equal(body.reply.content, firstFinalText);
    assert.match(text, /目前只有一个 HWPOD 可用/u);
    assert.doesNotMatch(text, /编译成功/u);
    assert.equal(text.includes('"fallback"'), false);
    assert.deepEqual(calls, []);
    assert.equal(codeAgentChatResults.get(secondTraceId).agentRun.commandId, firstCommandId);
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
    await new Promise((resolve, reject) => {
      agentRunServer.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("cloud api result polling does not query AgentRun registry when projection is stale (#1519)", async () => {
  const calls = [];
  const runId = "run_issue955_registry_missing";
  const traceId = "trc_issue955_registry_missing";
  const staleCommandId = "cmd_issue955_registry_stale";
  const staleFinalText = "目前只有一个 HWPOD 可用：d601-f103-v2。";
  const agentRunServer = createHttpServer(async (request, response) => {
    const url = new URL(request.url || "/", "http://127.0.0.1");
    calls.push({ method: request.method, path: url.pathname });
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/commands`) {
      response.writeHead(200, { "content-type": "application/json" });
      response.end(`${JSON.stringify({ ok: true, data: { items: [] }, traceId: "trc_fake_issue955_missing" })}\n`);
      return;
    }
    response.writeHead(404, { "content-type": "application/json" });
    response.end(`${JSON.stringify({ ok: false, message: `unexpected ${request.method} ${url.pathname}` })}\n`);
  });
  await new Promise((resolve) => agentRunServer.listen(0, "127.0.0.1", resolve));

  const agentRunPort = agentRunServer.address().port;
  const codeAgentChatResults = new Map();
  codeAgentChatResults.set(traceId, {
    accepted: true,
    status: "completed",
    shortConnection: true,
    traceId,
    conversationId: "cnv_issue955_registry_missing",
    sessionId: "ses_issue955_registry_missing",
    threadId: "thread-issue955-registry-missing",
    ownerUserId: TEST_AGENT_ACTOR.id,
    ownerRole: TEST_AGENT_ACTOR.role,
    reply: { role: "assistant", content: staleFinalText },
    finalResponse: { text: staleFinalText, textChars: staleFinalText.length, role: "assistant", status: "completed", traceId, valuesPrinted: false },
    agentRun: { adapter: "agentrun-v01", managerUrl: `http://127.0.0.1:${agentRunPort}`, runId, commandId: staleCommandId, traceId, terminalStatus: "completed", valuesPrinted: false },
    valuesPrinted: false
  });

  const server = createCloudApiServer({
    traceStore: createCodeAgentTraceStore(),
    codeAgentChatResults,
    env: {
      HWLAB_CODE_AGENT_ADAPTER: "agentrun-v01",
      AGENTRUN_MGR_URL: `http://127.0.0.1:${agentRunPort}`,
      HWLAB_CODE_AGENT_AGENTRUN_ALLOW_NON_K3S_URL: "1",
      HWLAB_CODE_AGENT_AGENTRUN_PROVIDER_ID: "D601",
      HWLAB_ENVIRONMENT: "v02",
      HWLAB_GITOPS_PROFILE: "v02"
    },
    accessController: {
      required: false,
      async authenticate() {
        return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION };
      }
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const response = await fetch(`http://127.0.0.1:${port}/v1/agent/chat/result/${traceId}`, {
      headers: { cookie: "hwlab_session=test-stub-session" }
    });
    assert.equal(response.status, 200);
    const body = await response.json();
    const text = JSON.stringify(body);
    assert.equal(body.traceId, traceId);
    assert.equal(body.status, "completed");
    assert.equal(body.projectionStatus, "caught-up");
    assert.equal(body.agentRun.commandId, staleCommandId);
    assert.match(text, /目前只有一个 HWPOD 可用/u);
    assert.deepEqual(calls, []);
    assert.equal(calls.some((call) => call.path.includes("/result")), false);
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
    await new Promise((resolve, reject) => {
      agentRunServer.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("cloud api result polling compacts large runnerTrace while preserving providerTrace", async () => {
  const workspace = await mkdtemp(path.join(os.tmpdir(), "hwlab-agent-result-compact-"));
  const codexHome = await mkdtemp(path.join(os.tmpdir(), "hwlab-agent-result-compact-codex-home-"));
  const server = createCloudApiServer({
    env: {
      PATH: process.env.PATH,
      CODEX_HOME: codexHome,
      HWLAB_CODE_AGENT_CODEX_WORKSPACE: workspace,
      HWLAB_CODE_AGENT_CODEX_SANDBOX: "danger-full-access",
      HWLAB_CODE_AGENT_PROVIDER: "codex-stdio",
      HWLAB_CODE_AGENT_MODEL: "gpt-test",
      HWLAB_CODE_AGENT_RESULT_TRACE_EVENT_LIMIT: "32",
      OPENAI_API_KEY: "test-openai-key-material",
      HWLAB_CODE_AGENT_OPENAI_BASE_URL: "http://127.0.0.1:65535/v1/responses"
    },
    codexStdioManager: {
      describe() {
        return {
          ...codexStdioReadyFixture({ workspace, codexHome }),
          sandbox: "danger-full-access"
        };
      },
      async probe() {
        return {
          ...codexStdioReadyFixture({ workspace, codexHome }),
          sandbox: "danger-full-access"
        };
      },
      async chat(params = {}) {
        const base = codexStdioChatFixture({ workspace, codexHome, params });
        const events = Array.from({ length: 160 }, (_, index) => ({
          seq: index + 1,
          traceId: params.traceId,
          type: "assistant_message",
          status: "chunk",
          label: index === 159 ? "assistant:completed" : "assistant:chunk",
          createdAt: "2026-05-23T00:00:00.000Z",
          waitingFor: index === 159 ? null : "turn/completed",
          valuesPrinted: false
        }));
        return {
          ...base,
          sandbox: "danger-full-access",
          session: {
            ...base.session,
            sandbox: "danger-full-access"
          },
          runnerTrace: {
            ...base.runnerTrace,
            events,
            eventLabels: events.map((event) => event.label),
            eventCount: events.length,
            lastEvent: events.at(-1)
          }
        };
      },
      cancel() {},
      reapIdle() {}
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const traceId = "trc_server-test-result-compact";
    const manualSession = await createManualAgentSession(port, {
      conversationId: "cnv_server-test-result-compact"
    });
    const submit = await fetch(`http://127.0.0.1:${port}/v1/agent/chat`, {
      method: "POST",
      headers: {
        "content-type": "application/json",
        cookie: manualSession.cookie,
        "x-trace-id": traceId,
        "prefer": "respond-async",
        "x-hwlab-short-connection": "1"
      },
      body: JSON.stringify({
        conversationId: manualSession.conversationId,
        sessionId: manualSession.sessionId,
        message: "生成大量 trace 后返回"
      })
    });
    assert.equal(submit.status, 202);

    const payload = await pollAgentResult(port, traceId);
    validateCodeAgentChatSchema(payload);
    assert.equal(payload.status, "completed");
    assert.equal(payload.traceId, traceId);
    assert.equal(payload.providerTrace.protocol, "codex-app-server-jsonrpc-stdio");
    assert.equal(payload.providerTrace.command, "codex app-server --listen stdio://");
    assert.equal(payload.runnerTrace.eventCount, 160);
    assert.equal(payload.runnerTrace.eventsCompacted, true);
    assert.equal(payload.runnerTrace.events.length, 32);
    assert.equal(payload.runnerTrace.events.some((event) => event.label === "trace:compacted"), true);
    assert.equal(payload.runnerTrace.lastEvent.label, "assistant:completed");
    assert.equal(payload.runnerTrace.eventLabels.includes("trace:compacted"), true);
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
    await rm(workspace, { recursive: true, force: true });
    await rm(codexHome, { recursive: true, force: true });
  }
});

test("cloud api /v1/agent/chat answers skills prompt through real Codex stdio and retains trace", async () => {
  const workspace = await mkdtemp(path.join(os.tmpdir(), "hwlab-agent-stdio-skills-"));
  const codexHome = path.join(workspace, "codex-home");
  const skillsDir = path.join(workspace, "skills");
  const fakeCodex = await createFakeCodexCommand();
  await mkdir(path.join(skillsDir, "hwlab-test-skill"), { recursive: true });
  await prepareFakeCodexHome(codexHome);
  await writeFile(path.join(skillsDir, "hwlab-test-skill", "SKILL.md"), [
    "---",
    "name: hwlab-test-skill",
    "description: Test skill mounted for Codex stdio discovery.",
    "version: v-test",
    "---",
    "",
    "# HWLAB Test Skill"
  ].join("\n"));
  const server = createCloudApiServer({
    env: {
      PATH: process.env.PATH,
      OPENAI_API_KEY: "test-openai-key-material",
      CODEX_HOME: codexHome,
      HWLAB_CODE_AGENT_PROVIDER: "codex-stdio",
      HWLAB_CODE_AGENT_MODEL: "gpt-test",
      HWLAB_CODE_AGENT_CODEX_COMMAND: fakeCodex.command,
      HWLAB_CODE_AGENT_CODEX_STDIO_ENABLED: "1",
      HWLAB_CODE_AGENT_CODEX_STDIO_SUPERVISOR: "repo-owned",
      HWLAB_CODE_AGENT_CODEX_WORKSPACE: workspace,
      HWLAB_CODE_AGENT_SKILLS_DIRS: skillsDir,
      HWLAB_CODE_AGENT_SKILLS_STRICT: "1",
      HWLAB_CODE_AGENT_OPENAI_BASE_URL: "http://127.0.0.1:65535/v1/responses"
    },
    codexStdioManager: createCodexStdioSessionManager({
      idFactory: () => "ses_server_stdio_skills",
      createRpcClient: async () => createFakeAppServerClient({
        text: "模型泛化回答不应成为 skills 最终回复。"
      })
    })
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const payload = await postAgent(port, {
      conversationId: "cnv_server_stdio_skills",
      traceId: "trc_server_stdio_skills",
      message: "列出你可用的skills"
    });

    validateCodeAgentChatSchema(payload);
    assert.equal(payload.status, "completed");
    assert.equal(payload.provider, "codex-stdio");
    assert.equal(payload.backend, "hwlab-cloud-api/codex-app-server-stdio");
    assert.equal(payload.capabilityLevel, "long-lived-codex-stdio-session");
    assert.equal(payload.providerTrace.sidecarOnly, undefined);
    assert.equal(payload.providerTrace.toolName, "codex-app-server.thread/start+turn/start");
    assert.equal(payload.skills.status, "ready");
    const discovered = payload.skills.items.find((skill) => skill.name === "hwlab-test-skill");
    assert.ok(discovered);
    assert.equal(discovered.source, path.join(skillsDir, "hwlab-test-skill", "SKILL.md"));
    assert.equal(discovered.manifest.path, path.join(skillsDir, "hwlab-test-skill", "SKILL.md"));
    assert.equal(discovered.version, "v-test");
    assert.ok(payload.toolCalls.some((toolCall) => toolCall.name === "skills.discover" && toolCall.status === "completed"));
    assert.match(payload.reply.content, /hwlab-test-skill/u);
    assert.match(payload.reply.content, /真实 skill manifest 清单/u);
    assert.doesNotMatch(payload.reply.content, /模型泛化回答/u);
    assert.ok(payload.runnerTrace.events.some((event) => event.label === "prompt:sent"));
    assert.ok(payload.runnerTrace.events.some((event) => event.label === "tool:codex-app-server.thread/start+turn/start:started"));
    assert.equal(JSON.stringify(payload).includes("test-openai-key-material"), false);
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
    await rm(workspace, { recursive: true, force: true });
    await rm(fakeCodex.root, { recursive: true, force: true });
  }
});

test("cloud api /v1/agent/chat returns structured skills blocker without local skills manifest", async () => {
  const workspace = await mkdtemp(path.join(os.tmpdir(), "hwlab-agent-stdio-skills-missing-"));
  const codexHome = path.join(workspace, "codex-home");
  const fakeCodex = await createFakeCodexCommand();
  await prepareFakeCodexHome(codexHome);
  const server = createCloudApiServer({
    env: {
      PATH: process.env.PATH,
      OPENAI_API_KEY: "test-openai-key-material",
      CODEX_HOME: codexHome,
      HWLAB_CODE_AGENT_PROVIDER: "codex-stdio",
      HWLAB_CODE_AGENT_MODEL: "gpt-test",
      HWLAB_CODE_AGENT_CODEX_COMMAND: fakeCodex.command,
      HWLAB_CODE_AGENT_CODEX_STDIO_ENABLED: "1",
      HWLAB_CODE_AGENT_CODEX_STDIO_SUPERVISOR: "repo-owned",
      HWLAB_CODE_AGENT_CODEX_WORKSPACE: workspace,
      HWLAB_CODE_AGENT_SKILLS_DIRS: path.join(workspace, "missing-skills"),
      HWLAB_CODE_AGENT_SKILLS_STRICT: "1",
      HWLAB_CODE_AGENT_OPENAI_BASE_URL: "http://127.0.0.1:65535/v1/responses"
    },
    codexStdioManager: createCodexStdioSessionManager({
      idFactory: () => "ses_server_stdio_skills_missing",
      createRpcClient: async () => createFakeAppServerClient({
        text: "模型泛化回答：alpha-skill"
      })
    })
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const payload = await postAgent(port, {
      conversationId: "cnv_server_stdio_skills_missing",
      traceId: "trc_server_stdio_skills_missing",
      message: "列出你可用的skills"
    });

    validateCodeAgentChatSchema(payload);
    assert.equal(payload.status, "failed");
    assert.equal(payload.provider, "codex-stdio");
    assert.equal(payload.backend, "hwlab-cloud-api/codex-app-server-stdio");
    assert.equal(payload.capabilityLevel, "blocked");
    assert.equal(payload.error.code, "skills_unavailable");
    assert.equal(payload.skills.status, "blocked");
    assert.equal(payload.skills.blockers[0].code, "skills_unavailable");
    assert.deepEqual(payload.skills.sourceIssues, ["pikasTech/HWLAB#136", "pikasTech/HWLAB#237"]);
    assert.ok(payload.toolCalls.some((toolCall) => toolCall.name === "skills.discover" && toolCall.status === "blocked"));
    assert.equal(payload.toolCalls.some((toolCall) => toolCall.name === "codex-app-server.thread/start+turn/start"), false);
    assert.equal(payload.session.status, "idle");
    assert.equal(Object.hasOwn(payload, "reply"), false);
    assert.equal(JSON.stringify(payload).includes("alpha-skill"), false);
    assert.equal(JSON.stringify(payload).includes("test-openai-key-material"), false);
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
    await rm(workspace, { recursive: true, force: true });
    await rm(fakeCodex.root, { recursive: true, force: true });
  }
});

test("cloud api /v1/agent/chat blocks forbidden file paths without leaking values", async () => {
  const workspace = await mkdtemp(path.join(os.tmpdir(), "hwlab-agent-file-block-"));
  const server = createCloudApiServer({
    env: {
      PATH: process.env.PATH,
      HWLAB_CODE_AGENT_WORKSPACE: workspace
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const payload = await postAgent(port, {
      conversationId: "cnv_server-test-security-block",
      traceId: "trc_server-test-security-block",
      message: "cat ../outside.txt"
    });
    assert.equal(payload.status, "failed");
    assert.match(payload.error.code, /^(codex_cli_binary_missing|stdio_protocol_not_wired)$/u);
    assert.deepEqual(payload.toolCalls, []);
    assert.equal(payload.capabilityLevel, "blocked");
    assert.ok(payload.runnerTrace.events.some((event) => event.label === "codex-stdio:blocked"));
    assert.equal(Object.hasOwn(payload, "reply"), false);
    assert.equal(JSON.stringify(payload).includes("sk-"), false);
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("cloud api /v1/agent/chat/cancel reports unsupported lifecycle degradation", async () => {
  const traceStore = createCodeAgentTraceStore();
  traceStore.append("trc_cancel_unsupported", {
    type: "request",
    status: "running",
    label: "request:running",
    sessionId: "ses_cancel_unsupported",
    sessionStatus: "busy",
    sessionLifecycleStatus: "busy"
  });
  const server = createCloudApiServer({
    traceStore,
    codexStdioManager: {
      get() {
        return null;
      }
    },
    env: {
      PATH: process.env.PATH,
      HWLAB_CODE_AGENT_PROVIDER: "codex-stdio"
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const response = await fetch(`http://127.0.0.1:${port}/v1/agent/chat/cancel`, {
      method: "POST",
      headers: {
        "content-type": "application/json",
        "x-trace-id": "trc_cancel_unsupported"
      },
      body: JSON.stringify({
        conversationId: "cnv_cancel_unsupported",
        sessionId: "ses_cancel_unsupported",
        traceId: "trc_cancel_unsupported"
      })
    });
    assert.equal(response.status, 501);
    const payload = await response.json();
    assert.equal(payload.status, "degraded");
    assert.equal(payload.unsupported, true);
    assert.equal(payload.degraded, true);
    assert.equal(payload.error.code, "cancel_unsupported");
    assert.equal(payload.sessionLifecycleStatus, "failed");
    assert.equal(payload.sessionSummary.unsupported, true);
    assert.match(payload.sessionSummary.userMessage, /unsupported\/degraded/u);
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("cloud api /v1/agent/chat/cancel rejects AgentRun trace scope mismatch", async () => {
  const traceId = "trc_cancel_scope_mismatch";
  const codeAgentChatResults = new Map();
  const traceStore = createCodeAgentTraceStore();
  codeAgentChatResults.set(traceId, {
    traceId,
    status: "running",
    conversationId: "cnv_cancel_scope",
    sessionId: "ses_cancel_scope",
    threadId: "thread-cancel-scope",
    agentRun: {
      runId: "run_cancel_scope",
      commandId: "cmd_cancel_scope",
      sessionId: "ses_agentrun_cancel_scope",
      conversationId: "cnv_cancel_scope",
      threadId: "thread-cancel-scope",
      managerUrl: "http://127.0.0.1:65535",
      status: "running",
      commandState: "running"
    }
  });
  const server = createCloudApiServer({
    traceStore,
    codeAgentChatResults,
    env: {
      PATH: process.env.PATH,
      HWLAB_CODE_AGENT_ADAPTER: "agentrun-v01",
      HWLAB_CODE_AGENT_PROVIDER: "agentrun-v01",
      HWLAB_CODE_AGENT_AGENTRUN_ALLOW_NON_K3S_URL: "1"
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const response = await fetch(`http://127.0.0.1:${port}/v1/agent/chat/cancel`, {
      method: "POST",
      headers: {
        "content-type": "application/json",
        "x-trace-id": traceId
      },
      body: JSON.stringify({
        conversationId: "cnv_cancel_scope_other",
        sessionId: "ses_cancel_scope_other",
        threadId: "thread-cancel-scope-other",
        traceId
      })
    });
    assert.equal(response.status, 409);
    const payload = await response.json();
    assert.equal(payload.status, "blocked");
    assert.equal(payload.canceled, false);
    assert.equal(payload.error.code, "cancel_scope_mismatch");
    assert.equal(codeAgentChatResults.get(traceId)?.status, "running");
    assert.ok(traceStore.snapshot(traceId)?.events?.some((event) => event.label === "agentrun:cancel:scope_mismatch"));
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("cloud api /v1/agent/chat/cancel keeps already terminal AgentRun result instead of overwriting", async () => {
  const traceId = "trc_cancel_already_terminal";
  const codeAgentChatResults = new Map();
  const traceStore = createCodeAgentTraceStore();
  codeAgentChatResults.set(traceId, {
    traceId,
    status: "completed",
    finalResponse: "OK",
    conversationId: "cnv_cancel_already_terminal",
    sessionId: "ses_cancel_already_terminal",
    threadId: "thread-cancel-already-terminal",
    agentRun: {
      runId: "run_cancel_already_terminal",
      commandId: "cmd_cancel_already_terminal",
      sessionId: "ses_agentrun_cancel_already_terminal",
      conversationId: "cnv_cancel_already_terminal",
      threadId: "thread-cancel-already-terminal",
      status: "completed",
      commandState: "completed",
      terminalStatus: "completed"
    }
  });
  const accessController = {
    required: false,
    async authenticate() { return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION }; }
  };
  const server = createCloudApiServer({
    traceStore,
    codeAgentChatResults,
    accessController,
    env: {
      PATH: process.env.PATH,
      HWLAB_CODE_AGENT_ADAPTER: "agentrun-v01",
      HWLAB_CODE_AGENT_PROVIDER: "agentrun-v01"
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const response = await fetch(`http://127.0.0.1:${port}/v1/agent/chat/cancel`, {
      method: "POST",
      headers: {
        "content-type": "application/json",
        "x-trace-id": traceId
      },
      body: JSON.stringify({
        conversationId: "cnv_cancel_already_terminal",
        sessionId: "ses_cancel_already_terminal",
        threadId: "thread-cancel-already-terminal",
        traceId
      })
    });
    assert.equal(response.status, 200);
    const payload = await response.json();
    assert.equal(payload.status, "completed");
    assert.equal(payload.finalResponse, "OK");
    assert.equal(payload.cancelDisposition.status, "already_terminal");
    assert.equal(payload.cancelDisposition.forwarded, false);
    assert.equal(codeAgentChatResults.get(traceId).status, "completed");
    assert.ok(traceStore.snapshot(traceId)?.events?.some((event) => event.label === "agentrun:cancel:already-terminal"));
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("cloud api /v1/agent/chat/cancel returns already-terminal when AgentRun result completed", async () => {
  const calls = [];
  const traceId = "trc_cancel_terminal_result_authority";
  const runId = "run_cancel_terminal_result_authority";
  const commandId = "cmd_cancel_terminal_result_authority";
  const finalText = "Cancel did not overwrite the completed AgentRun result.";
  const agentRunServer = createHttpServer(async (request, response) => {
    const url = new URL(request.url || "/", "http://127.0.0.1");
    calls.push({ method: request.method, path: url.pathname });
    const send = (body, status = 200) => {
      response.writeHead(status, { "content-type": "application/json" });
      response.end(`${JSON.stringify(body)}\n`);
    };
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/events`) return send({ items: [] });
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/commands/${commandId}/result`) {
      return send({ runId, commandId, status: "completed", runStatus: "completed", commandState: "completed", terminalStatus: "completed", completed: true, reply: finalText, lastSeq: 7, eventCount: 7 });
    }
    if (request.method === "POST" && url.pathname === `/api/v1/commands/${commandId}/cancel`) return send({ ok: true, canceled: true });
    return send({ ok: false, message: `unexpected ${request.method} ${url.pathname}` }, 404);
  });
  await new Promise((resolve) => agentRunServer.listen(0, "127.0.0.1", resolve));
  const agentRunPort = agentRunServer.address().port;
  const traceStore = createCodeAgentTraceStore();
  const codeAgentChatResults = new Map();
  codeAgentChatResults.set(traceId, {
    traceId,
    status: "running",
    conversationId: "cnv_cancel_terminal_result_authority",
    sessionId: "ses_cancel_terminal_result_authority",
    threadId: "thread-cancel-terminal-result-authority",
    agentRun: {
      adapter: "agentrun-v01",
      managerUrl: `http://127.0.0.1:${agentRunPort}`,
      runId,
      commandId,
      traceId,
      providerTrace: { traceId, runId, commandId, valuesPrinted: false },
      lastSeq: 6,
      status: "running",
      commandState: "running",
      valuesPrinted: false
    },
    valuesRedacted: true
  });
  const server = createCloudApiServer({
    traceStore,
    codeAgentChatResults,
    env: {
      PATH: process.env.PATH,
      HWLAB_CODE_AGENT_ADAPTER: "agentrun-v01",
      HWLAB_CODE_AGENT_PROVIDER: "agentrun-v01",
      HWLAB_CODE_AGENT_AGENTRUN_ALLOW_NON_K3S_URL: "1"
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const response = await fetch(`http://127.0.0.1:${port}/v1/agent/chat/cancel`, {
      method: "POST",
      headers: { "content-type": "application/json", "x-trace-id": traceId },
      body: JSON.stringify({ traceId, conversationId: "cnv_cancel_terminal_result_authority", sessionId: "ses_cancel_terminal_result_authority", threadId: "thread-cancel-terminal-result-authority" })
    });
    assert.equal(response.status, 200);
    const payload = await response.json();
    assert.equal(payload.status, "completed");
    assert.equal(payload.cancelDisposition.status, "already_terminal");
    assert.equal(payload.cancelDisposition.forwarded, false);
    assert.equal(payload.finalResponse.text, finalText);
    assert.equal(calls.some((call) => call.method === "POST" && call.path === `/api/v1/commands/${commandId}/cancel`), false);
    assert.equal(codeAgentChatResults.get(traceId)?.status, "completed");
  } finally {
    await new Promise((resolve, reject) => server.close((error) => (error ? reject(error) : resolve())));
    await new Promise((resolve, reject) => agentRunServer.close((error) => (error ? reject(error) : resolve())));
  }
});

test("cloud api /v1/agent/chat reports Codex stdio blocker instead of structured skills fallback", async () => {
  const root = await mkdtemp(path.join(os.tmpdir(), "hwlab-agent-no-skills-"));
  const skillsDir = path.join(root, "missing-skills");
  const server = createCloudApiServer({
    env: {
      PATH: process.env.PATH,
      HWLAB_CODE_AGENT_WORKSPACE: root
    },
    skillsDirs: [skillsDir],
    skillsDirsExact: true
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const manualSession = await createManualAgentSession(port, {
      conversationId: "cnv_server-test-skills-missing"
    });
    const response = await fetch(`http://127.0.0.1:${port}/v1/agent/chat`, {
      method: "POST",
      headers: {
        "content-type": "application/json",
        cookie: manualSession.cookie
      },
      body: JSON.stringify({
        conversationId: manualSession.conversationId,
        sessionId: manualSession.sessionId,
        message: "列出你可用的skills"
      })
    });
    assert.equal(response.status, 200);
    const payload = await response.json();
    assert.equal(payload.status, "failed");
    assert.equal(payload.provider, "codex-stdio");
    assert.notEqual(payload.error.code, "skills_unavailable");
    assert.equal(payload.capabilityLevel, "blocked");
    assert.equal(payload.skills.status, "not_requested");
    assert.deepEqual(payload.toolCalls, []);
    assert.ok(payload.runnerLimitations.includes("no-controlled-readonly-fallback"));
    assert.equal(Object.hasOwn(payload, "reply"), false);
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("cloud api /v1/agent/chat does not run unsupported local grep fallback", async () => {
  const workspace = await mkdtemp(path.join(os.tmpdir(), "hwlab-agent-tool-blocked-"));
  const server = createCloudApiServer({
    env: {
      PATH: process.env.PATH,
      HWLAB_CODE_AGENT_WORKSPACE: workspace
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const manualSession = await createManualAgentSession(port, {
      conversationId: "cnv_server-test-tool-unavailable"
    });
    const response = await fetch(`http://127.0.0.1:${port}/v1/agent/chat`, {
      method: "POST",
      headers: {
        "content-type": "application/json",
        cookie: manualSession.cookie
      },
      body: JSON.stringify({
        conversationId: manualSession.conversationId,
        sessionId: manualSession.sessionId,
        message: "请用grep搜索 package.json"
      })
    });
    assert.equal(response.status, 200);
    const payload = await response.json();
    assert.equal(payload.status, "failed");
    assert.notEqual(payload.error.code, "tool_unavailable");
    assert.equal(payload.provider, "codex-stdio");
    assert.equal(payload.capabilityLevel, "blocked");
    assert.deepEqual(payload.toolCalls, []);
    assert.ok(payload.runnerLimitations.includes("no-controlled-readonly-fallback"));
    assert.equal(Object.hasOwn(payload, "reply"), false);
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("cloud api /v1/agent/chat does not call delayed provider fallback beyond legacy 4500ms UI timeout", async () => {
  let providerCalled = false;
  const server = createCloudApiServer({
    callCodeAgentProvider: async ({ providerPlan, message, traceId }) => {
      providerCalled = true;
      await delay(4700);
      return {
        provider: providerPlan.provider,
        model: providerPlan.model,
        backend: providerPlan.backend,
        content: `延迟真实 provider stub: ${message} / ${traceId}`,
        usage: null,
        providerTrace: {
          source: "delayed-test-provider"
        }
      };
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const manualSession = await createManualAgentSession(port, {
      conversationId: "cnv_server-test-agent-chat-delayed"
    });
    const startedAt = Date.now();
    const response = await fetch(`http://127.0.0.1:${port}/v1/agent/chat`, {
      method: "POST",
      headers: {
        "content-type": "application/json",
        cookie: manualSession.cookie,
        "x-trace-id": "trc_server-test-agent-chat-delayed"
      },
      body: JSON.stringify({
        conversationId: manualSession.conversationId,
        sessionId: manualSession.sessionId,
        message: "请用一句话说明当前 HWLAB 工作台可以做什么，稍后回答"
      })
    });
    assert.equal(response.status, 200);
    const payload = await response.json();
    assert.equal(Date.now() - startedAt < 4500, true);
    assert.equal(payload.status, "failed");
    assert.equal(payload.conversationId, "cnv_server-test-agent-chat-delayed");
    assert.equal(payload.traceId, "trc_server-test-agent-chat-delayed");
    assert.equal(payload.provider, "codex-stdio");
    assert.equal(payload.capabilityLevel, "blocked");
    assert.equal(providerCalled, false);
    assert.equal(Object.hasOwn(payload, "reply"), false);
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("cloud api /v1/agent/chat does not call OpenAI provider 502/503 fallback", async () => {
  for (const status of [502, 503]) {
    const providerServer = createHttpServer((request, response) => {
      request.resume();
      response.writeHead(status, { "content-type": "application/json" });
      response.end(JSON.stringify({
        error: {
          message: `upstream ${status}`
        }
      }));
    });
    await new Promise((resolve) => providerServer.listen(0, "127.0.0.1", resolve));
    const providerPort = providerServer.address().port;

    const server = createCloudApiServer({
      env: {
        OPENAI_API_KEY: "test-openai-key-material",
        HWLAB_CODE_AGENT_PROVIDER: "openai",
        HWLAB_CODE_AGENT_ALLOW_TEXT_FALLBACK: "true",
        HWLAB_CODE_AGENT_MODEL: "gpt-test",
        HWLAB_CODE_AGENT_OPENAI_BASE_URL: `http://127.0.0.1:${providerPort}/v1/responses`
      }
    });
    await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

    try {
      const { port } = server.address();
      const manualSession = await createManualAgentSession(port, {
        conversationId: `cnv_server-test-agent-chat-provider-${status}`
      });
      const response = await fetch(`http://127.0.0.1:${port}/v1/agent/chat`, {
        method: "POST",
        headers: {
          "content-type": "application/json",
          cookie: manualSession.cookie,
          "x-trace-id": `trc_server-test-agent-chat-provider-${status}`
        },
        body: JSON.stringify({
          conversationId: manualSession.conversationId,
          sessionId: manualSession.sessionId,
          message: `provider ${status}`
        })
      });
      assert.equal(response.status, 200);
      const payload = await response.json();
      assert.equal(payload.status, "failed");
      assert.equal(payload.traceId, `trc_server-test-agent-chat-provider-${status}`);
      assert.match(payload.error.code, /^(codex_cli_binary_missing|codex_cli_native_dependency_missing|codex_stdio_supervisor_disabled|stdio_protocol_not_wired)$/u);
      assert.match(payload.error.layer, /^(runner|api)$/u);
      assert.equal(typeof payload.error.retryable, "boolean");
      assert.equal(payload.error.blocker.traceId, `trc_server-test-agent-chat-provider-${status}`);
      assert.equal(typeof payload.error.blocker.retryable, "boolean");
      assert.equal(payload.error.blocker.capabilityLevel, "blocked");
      assert.equal(payload.provider, "codex-stdio");
      assert.equal(Object.hasOwn(payload, "reply"), false);
    } finally {
      await new Promise((resolve, reject) => {
        server.close((error) => (error ? reject(error) : resolve()));
      });
      await new Promise((resolve, reject) => {
        providerServer.close((error) => (error ? reject(error) : resolve()));
      });
    }
  }
});

test("cloud api /v1/agent/chat does not call empty provider text fallback", async () => {
  let providerCalled = false;
  const server = createCloudApiServer({
    callCodeAgentProvider: async () => {
      providerCalled = true;
      throw new Error("empty provider fallback must not be used");
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const manualSession = await createManualAgentSession(port, {
      conversationId: "cnv_empty-provider-text"
    });
    const response = await fetch(`http://127.0.0.1:${port}/v1/agent/chat`, {
      method: "POST",
      headers: {
        "content-type": "application/json",
        cookie: manualSession.cookie
      },
      body: JSON.stringify({
        conversationId: manualSession.conversationId,
        sessionId: manualSession.sessionId,
        message: "你好"
      })
    });
    assert.equal(response.status, 200);
    const payload = await response.json();
    assert.equal(payload.conversationId, "cnv_empty-provider-text");
    assert.equal(payload.status, "failed");
    assert.match(payload.error.code, /^(codex_cli_binary_missing|stdio_protocol_not_wired)$/u);
    assert.equal(payload.provider, "codex-stdio");
    assert.equal(Object.hasOwn(payload, "reply"), false);
    assert.equal(providerCalled, false);
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
  }
});
