// 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 adapter and trace observability 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, syncAgentRunChatResult } 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("manual Code Agent session create writes an empty Workbench session fact", async () => {
  const runtimeStore = createCloudRuntimeStore({ now: () => "2026-06-20T08:45:00.000Z" });
  const ownerSessions = new Map();
  const accessController = {
    required: true,
    async ensureBootstrap() {},
    async authenticate() { return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION }; },
    async recordAgentSessionOwner(input = {}) {
      const record = testAgentSessionRecord({ ...input, id: input.sessionId, sessionId: input.sessionId, updatedAt: input.now ?? "2026-06-20T08:45:00.000Z" });
      ownerSessions.set(record.id, record);
      return record;
    },
    async getAgentSession(sessionId) { return ownerSessions.get(sessionId) ?? null; },
    store: {
      async listAgentSessionsForUser() { return [...ownerSessions.values()]; },
      async getAgentSession(sessionId) { return ownerSessions.get(sessionId) ?? null; }
    }
  };
  const server = createCloudApiServer({ accessController, runtimeStore });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const create = await fetch(`http://127.0.0.1:${port}/v1/agent/sessions`, {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ providerProfile: "codex-api" })
    });
    assert.equal(create.status, 201);
    const created = await create.json();
    const sessionId = created.session.sessionId;
    assert.match(sessionId, /^ses_/u);

    const list = await fetch(`http://127.0.0.1:${port}/v1/workbench/sessions?includeSessionId=${encodeURIComponent(sessionId)}&limit=1`);
    assert.equal(list.status, 200);
    const listBody = await list.json();
    assert.equal(listBody.sessions[0].sessionId, sessionId);
    assert.equal(listBody.sessions[0].status, "idle");
    assert.equal(listBody.sessions[0].running, false);

    const detail = await fetch(`http://127.0.0.1:${port}/v1/workbench/sessions/${encodeURIComponent(sessionId)}`);
    assert.equal(detail.status, 200);
    const detailBody = await detail.json();
    assert.equal(detailBody.session.sessionId, sessionId);
    assert.equal(detailBody.session.status, "idle");
    assert.equal(detailBody.session.messagePageUrl, `/v1/workbench/sessions/${encodeURIComponent(sessionId)}/messages`);

    const messages = await fetch(`http://127.0.0.1:${port}/v1/workbench/sessions/${encodeURIComponent(sessionId)}/messages?limit=10`);
    assert.equal(messages.status, 200);
    const messageBody = await messages.json();
    assert.equal(messageBody.sessionId, sessionId);
    assert.equal(messageBody.count, 0);
    assert.deepEqual(messageBody.messages, []);
  } finally {
    await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve()));
  }
});

test("cloud api trace resource paginates events by sinceSeq", async () => {
  const traceStore = createCodeAgentTraceStore();
  const traceId = "trc_trace_pagination";
  for (let index = 0; index < 5; index += 1) {
    traceStore.append(traceId, { type: "trace", status: "observed", label: `event:${index}` });
  }
  const server = createCloudApiServer({
    traceStore,
    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 firstPage = await fetch(`http://127.0.0.1:${port}/v1/agent/traces/${traceId}?limit=2`);
    assert.equal(firstPage.status, 200);
    const firstBody = await firstPage.json();
    assert.deepEqual(firstBody.events.map((event) => event.label), ["event:0", "event:1"]);
    assert.equal(firstBody.eventCount, 5);
    assert.equal(firstBody.hasMore, true);
    assert.equal(firstBody.truncated, true);
    assert.equal(firstBody.fullTraceLoaded, false);
    assert.equal(firstBody.range.sinceSeq, 0);
    assert.equal(firstBody.range.returned, 2);

    const secondPage = await fetch(`http://127.0.0.1:${port}/v1/agent/traces/${traceId}?sinceSeq=${firstBody.nextSinceSeq}&limit=2`);
    assert.equal(secondPage.status, 200);
    const secondBody = await secondPage.json();
    assert.deepEqual(secondBody.events.map((event) => event.label), ["event:2", "event:3"]);
    assert.equal(secondBody.range.sinceSeq, firstBody.nextSinceSeq);
    assert.equal(secondBody.hasMore, true);

    const finalPage = await fetch(`http://127.0.0.1:${port}/v1/agent/traces/${traceId}?sinceSeq=${secondBody.nextSinceSeq}&limit=2`);
    assert.equal(finalPage.status, 200);
    const finalBody = await finalPage.json();
    assert.deepEqual(finalBody.events.map((event) => event.label), ["event:4"]);
    assert.equal(finalBody.hasMore, false);
    assert.equal(finalBody.truncated, false);
    assert.equal(finalBody.fullTraceLoaded, true);
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("cloud api turn and trace endpoints reject mismatched requested project", async () => {
  const traceStore = createCodeAgentTraceStore();
  const traceId = "trc_issue1429_project_scope";
  traceStore.append(traceId, { type: "trace", status: "completed", label: "turn:completed", terminal: true });
  const server = createCloudApiServer({
    traceStore,
    accessController: {
      required: false,
      async authenticate() {
        return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION };
      },
      async getAgentSessionByTraceId(requestedTraceId) {
        assert.equal(requestedTraceId, traceId);
        return testAgentSessionRecord({ sessionId: "ses_issue1429_project_scope", projectId: "prj_v02_code_agent", traceId, status: "completed" });
      }
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const wrongTurn = await fetch(`http://127.0.0.1:${port}/v1/agent/turns/${traceId}?projectId=prj_hwpod_workbench`);
    assert.equal(wrongTurn.status, 404);
    assert.equal((await wrongTurn.json()).error.code, "trace_project_mismatch");

    const wrongTrace = await fetch(`http://127.0.0.1:${port}/v1/agent/traces/${traceId}?projectId=prj_hwpod_workbench`);
    assert.equal(wrongTrace.status, 404);
    assert.equal((await wrongTrace.json()).error.code, "trace_project_mismatch");

    const rightTrace = await fetch(`http://127.0.0.1:${port}/v1/agent/traces/${traceId}?projectId=prj_v02_code_agent`);
    assert.equal(rightTrace.status, 200);
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("AgentRun adapter filters resource tools and credentials through access capabilities", async () => {
  const calls = [];
  const agentRunServer = createHttpServer(async (request, response) => {
    const url = new URL(request.url || "/", "http://127.0.0.1");
    const chunks = [];
    for await (const chunk of request) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
    const body = chunks.length ? JSON.parse(Buffer.concat(chunks).toString("utf8")) : null;
    calls.push({ method: request.method, path: url.pathname, body });
    const send = (data) => {
      response.writeHead(200, { "content-type": "application/json" });
      response.end(`${JSON.stringify({ ok: true, data, traceId: "trc_fake_access_tools" })}\n`);
    };
    if (request.method === "POST" && url.pathname === "/api/v1/sessions") return send({ ok: true });
    if (request.method === "POST" && url.pathname === "/api/v1/runs") return send({ id: "run_access_tools", status: "pending", backendProfile: "deepseek", sessionRef: body.sessionRef, resourceBundleRef: body.resourceBundleRef });
    if (request.method === "POST" && url.pathname === "/api/v1/runs/run_access_tools/commands") return send({ id: "cmd_access_tools", runId: "run_access_tools", state: "pending", type: "turn", seq: 1 });
    if (request.method === "POST" && url.pathname === "/api/v1/runs/run_access_tools/runner-jobs") return send({
      action: "create-kubernetes-job",
      runId: "run_access_tools",
      commandId: body.commandId,
      attemptId: "attempt_access_tools",
      runnerId: "runner_access_tools",
      namespace: "agentrun-v01",
      jobName: "agentrun-v01-runner-access-tools"
    });
    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));

  try {
    const { port } = agentRunServer.address();
    const traceStore = createCodeAgentTraceStore();
    const result = await submitAgentRunChatTurn({
      traceId: "trc_access_tool_filter",
      traceStore,
      params: {
        message: "tool filter smoke",
        ownerUserId: "usr_tool_limited",
        projectId: "prj_hwpod_workbench",
        conversationId: "cnv_access_tools",
        sessionId: "ses_access_tools"
      },
      options: {
        env: {
          HWLAB_CODE_AGENT_ADAPTER: "agentrun-v01",
          AGENTRUN_MGR_URL: `http://127.0.0.1:${port}`,
          HWLAB_CODE_AGENT_AGENTRUN_ALLOW_NON_K3S_URL: "1",
          HWLAB_CODE_AGENT_AGENTRUN_PROVIDER_ID: "D601",
          HWLAB_CODE_AGENT_AGENTRUN_SOURCE_COMMIT: "0123456789abcdef0123456789abcdef01234567",
          HWLAB_CODE_AGENT_DEFAULT_PROVIDER_PROFILE: "deepseek",
          HWLAB_RUNTIME_API_URL: "http://hwlab-cloud-api.hwlab-v02.svc.cluster.local:6667",
          HWLAB_RUNTIME_WEB_URL: "http://hwlab-cloud-web.hwlab-v02.svc.cluster.local:8080",
          HWLAB_RUNTIME_NAMESPACE: "hwlab-v02",
          HWLAB_RUNTIME_LANE: "v02",
          HWLAB_RUNTIME_ENDPOINT_LOCKED: "1",
          HWLAB_CODE_AGENT_ASSEMBLED_RUNTIME: "1",
          UNIDESK_MAIN_SERVER_IP: "http://74.48.78.17:18081"
        },
        accessController: {
          async codeAgentToolCapabilitiesForOwner(ownerUserId) {
            assert.equal(ownerUserId, "usr_tool_limited");
            return {
              contractVersion: "admin-access-v1",
              tools: {
                hwpod: { allowed: false },
                unidesk_ssh: { allowed: false },
                trans_cmd: { allowed: false },
                github_pr: { allowed: false }
              }
            };
          },
          store: {
            async findActiveDefaultApiKeyForUser(userId) {
              assert.equal(userId, "usr_tool_limited");
              return { displaySecret: "hwl_live_owner_secret" };
            }
          }
        }
      }
    });

    assert.equal(result.status, "running");
    const createRun = calls.find((call) => call.method === "POST" && call.path === "/api/v1/runs");
    assert.equal(createRun.body.resourceBundleRef.kind, "gitbundle");
    assert.deepEqual(createRun.body.resourceBundleRef.bundles, [
      { name: "hwlab-tools", subpath: "tools", target_path: "tools" },
      { name: "hwlab-agent-skills", subpath: "skills", target_path: ".agents/skills" }
    ]);
    assert.equal(Object.hasOwn(createRun.body.resourceBundleRef, "toolAliases"), false);
    assert.equal(Object.hasOwn(createRun.body.resourceBundleRef, "skillRefs"), false);
    assert.equal(Object.hasOwn(createRun.body.resourceBundleRef, "workspaceFiles"), false);
    assert.deepEqual(createRun.body.executionPolicy.secretScope.toolCredentials, []);
    const runnerJob = calls.find((call) => call.method === "POST" && call.path === "/api/v1/runs/run_access_tools/runner-jobs");
    assert.equal(runnerJob.body.transientEnv.some((entry) => entry.name === "HWLAB_API_KEY"), false);
  } finally {
    await new Promise((resolve, reject) => agentRunServer.close((error) => (error ? reject(error) : resolve())));
  }
});

test("cloud api /v1/agent/chat parse and params errors use structured blocker envelope", async () => {
  const server = createCloudApiServer({
    env: {
      HWLAB_CODE_AGENT_MODEL: "gpt-test"
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const parse = await postAgentRaw(port, "{", { "x-trace-id": "trc_parse_error" });
    assert.equal(parse.status, 400);
    assert.equal(parse.body.status, "failed");
    assert.equal(parse.body.error.code, "parse_error");
    assert.equal(parse.body.error.layer, "api");
    assert.equal(parse.body.error.retryable, true);
    assert.equal(parse.body.error.traceId, "trc_parse_error");
    assert.equal(parse.body.error.route, "/v1/agent/chat");
    assert.match(parse.body.error.userMessage, /JSON/u);
    assert.equal(Object.hasOwn(parse.body, "reply"), false);
    assert.equal(JSON.stringify(parse.body).includes("sk-"), false);

    const invalid = await postAgentRaw(port, JSON.stringify([]), { "x-trace-id": "trc_invalid_params" });
    assert.equal(invalid.status, 400);
    assert.equal(invalid.body.error.code, "invalid_params");
    assert.equal(invalid.body.error.layer, "api");
    assert.equal(invalid.body.error.retryable, true);
    assert.equal(invalid.body.error.blocker.code, "invalid_params");
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("cloud api /v1/agent/chat supports short submit and result polling", async () => {
  const workspace = await mkdtemp(path.join(os.tmpdir(), "hwlab-agent-short-"));
  const codexHome = await mkdtemp(path.join(os.tmpdir(), "hwlab-agent-short-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",
      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 = {}) {
        return {
          ...codexStdioChatFixture({ workspace, codexHome, params }),
          sandbox: "danger-full-access",
          session: {
            ...codexStdioChatFixture({ workspace, codexHome, params }).session,
            sandbox: "danger-full-access"
          }
        };
      },
      cancel() {},
      reapIdle() {}
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const traceId = "trc_server-test-short-submit";
    const manualSession = await createManualAgentSession(port, {
      conversationId: "cnv_server-test-short-submit"
    });
    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: "用pwd列出你当前的工作目录"
      })
    });
    assert.equal(submit.status, 202);
    const accepted = await submit.json();
    assert.equal(accepted.accepted, true);
    assert.equal(accepted.shortConnection, true);
    assert.equal(accepted.traceId, traceId);
    assert.equal(accepted.turnId, traceId);
    assert.equal(accepted.userMessageId, "msg_server-test-short-submit_user");
    assert.equal(accepted.assistantMessageId, "msg_server-test-short-submit_agent");
    assert.equal(accepted.resultUrl, `/v1/agent/chat/result/${traceId}`);

    const acceptedTurn = await fetch(`http://127.0.0.1:${port}/v1/agent/turns/${encodeURIComponent(traceId)}`, { headers: { cookie: manualSession.cookie } });
    assert.equal(acceptedTurn.status, 200);
    const acceptedTurnPayload = await acceptedTurn.json();
    assert.equal(acceptedTurnPayload.turnId, traceId);
    assert.equal(acceptedTurnPayload.userMessageId, accepted.userMessageId);
    assert.equal(acceptedTurnPayload.assistantMessageId, accepted.assistantMessageId);

    const payload = await pollAgentResult(port, traceId);
    validateCodeAgentChatSchema(payload);
    assert.equal(payload.status, "completed");
    assert.equal(payload.traceId, traceId);
    assert.equal(payload.turnId, traceId);
    assert.equal(payload.userMessageId, accepted.userMessageId);
    assert.equal(payload.assistantMessageId, accepted.assistantMessageId);
    assert.equal(payload.sandbox, "danger-full-access");
    assert.match(payload.reply.content, new RegExp(workspace.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&")));
  } 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 delegates v0.3 turns to AgentRun v0.1 over adapter", async () => {
  const calls = [];
  const ownerSessions = new Map();
  const conversationMessages = [];
  const agentRunServer = createHttpServer(async (request, response) => {
    const url = new URL(request.url || "/", "http://127.0.0.1");
    const chunks = [];
    for await (const chunk of request) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
    const body = chunks.length ? JSON.parse(Buffer.concat(chunks).toString("utf8")) : null;
    calls.push({ method: request.method, path: url.pathname, search: url.search, body });
    const send = (data) => {
      response.writeHead(200, { "content-type": "application/json" });
      response.end(`${JSON.stringify({ ok: true, data, traceId: "trc_fake_agentrun" })}\n`);
    };
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_hwlab_adapter") {
      return send({
        id: "run_hwlab_adapter",
        status: "claimed",
        terminalStatus: null,
        claimedBy: "runner_hwlab_adapter",
        leaseExpiresAt: "2999-01-01T00:00:00.000Z",
        backendProfile: "deepseek",
        sessionRef: {
          sessionId: "ses_agentrun_deepseek_server_test_agentrun",
          conversationId: "cnv_server-test-agentrun",
          threadId: "019e8078-db67-7750-a5d9-1a99f3abd445",
          metadata: {}
        }
      });
    }
    if (request.method === "POST" && url.pathname === "/api/v1/runs") {
      assert.equal(body.tenantId, "hwlab");
      assert.equal(body.projectId, "pikasTech/HWLAB");
      assert.equal(body.backendProfile, "deepseek");
      assert.equal(body.workspaceRef.branch, "v0.3");
      assert.equal(body.workspaceRef.runtimeNamespace, "hwlab-v03");
      assert.equal(body.resourceBundleRef.repoUrl, "http://git-mirror-http.devops-infra.svc.cluster.local/pikasTech/HWLAB.git");
      assert.equal(body.resourceBundleRef.commitId, "0123456789abcdef0123456789abcdef01234567");
      assert.equal(body.resourceBundleRef.kind, "gitbundle");
      assert.deepEqual(body.resourceBundleRef.bundles, [
        { name: "hwlab-tools", subpath: "tools", target_path: "tools" },
        { name: "hwlab-agent-skills", subpath: "skills", target_path: ".agents/skills" }
      ]);
      assert.deepEqual(body.resourceBundleRef.promptRefs, [
        { name: "hwlab-v02-runtime", path: "internal/agent/prompts/hwlab-v02-runtime.md", inject: "thread-start", required: true }
      ]);
      assert.equal(Object.hasOwn(body.resourceBundleRef, "toolAliases"), false);
      assert.equal(Object.hasOwn(body.resourceBundleRef, "skillRefs"), false);
      assert.equal(Object.hasOwn(body.resourceBundleRef, "workspaceFiles"), false);
      const toolCredentials = body.executionPolicy.secretScope.toolCredentials;
      assert.equal(toolCredentials.some((item) => item.tool === "github" && item.projection.envName === "GH_TOKEN" && item.secretRef.name === "agentrun-v01-tool-github-pr"), true);
      assert.equal(toolCredentials.some((item) => item.tool === "unidesk-ssh" && item.projection.envName === "UNIDESK_SSH_CLIENT_TOKEN" && item.secretRef.name === "agentrun-v01-tool-unidesk-ssh"), true);
      assert.equal(body.sessionRef.sessionId, "ses_agentrun_deepseek_server_test_agentrun");
      assert.equal(body.sessionRef.metadata.hwlabProjectId, "prj_hwpod_workbench");
      assert.equal(body.sessionRef.metadata.hwlabSessionId, "ses_server-test-agentrun");
      assert.equal(body.sessionRef.metadata.agentRunSessionProfile, "deepseek");
      assert.equal(body.sessionRef.metadata.agentRunSessionPolicy, "backend-profile-scoped");
      assert.equal(body.sessionRef.metadata.threadContinuityPolicy, "hwlab-agentrun-v01-reuse-runner-thread");
      assert.equal(body.sessionRef.metadata.sessionPolicy, "hwlab-agentrun-v01-session-runner-reuse");
      return send({ id: "run_hwlab_adapter", status: "pending", backendProfile: "deepseek", sessionRef: body.sessionRef, resourceBundleRef: body.resourceBundleRef });
    }
    if (request.method === "POST" && url.pathname === "/api/v1/runs/run_hwlab_adapter/commands") {
      if (body.type === "steer") {
        assert.equal(body.payload.targetTraceId, "trc_server-test-agentrun-adapter");
        assert.equal(body.payload.targetCommandId, "cmd_hwlab_adapter");
        assert.equal(body.payload.traceId, "trc_steer_server_test");
        assert.match(body.payload.prompt, /STEER_MARK/u);
        assert.equal(body.payload.sessionId, "ses_agentrun_deepseek_server_test_agentrun");
        assert.equal(body.payload.hwlabSessionId, "ses_server-test-agentrun");
        assert.equal(body.payload.threadId, "019e8078-db67-7750-a5d9-1a99f3abd445");
        assert.equal(body.idempotencyKey, "trc_steer_server_test");
        return send({ id: "cmd_hwlab_adapter_steer", runId: "run_hwlab_adapter", state: "pending", type: "steer", seq: 7 });
      }
      assert.equal(body.type, "turn");
      assert.match(body.payload.prompt, /AgentRun adapter/u);
      assert.equal(body.payload.projectId, "prj_hwpod_workbench");
      assert.equal(body.payload.sessionId, "ses_agentrun_deepseek_server_test_agentrun");
      assert.equal(body.payload.hwlabSessionId, "ses_server-test-agentrun");
      assert.equal(body.payload.threadContinuityPolicy, "hwlab-agentrun-v01-reuse-runner-thread");
      assert.equal(body.payload.sessionPolicy, "hwlab-agentrun-v01-session-runner-reuse");
      const secondTurn = /第二轮/u.test(body.payload.message ?? body.payload.prompt);
      if (secondTurn) {
        assert.equal(body.payload.prompt, "AgentRun adapter smoke 第二轮：总结我们刚才的对话内容");
        assert.equal(body.payload.message, "AgentRun adapter smoke 第二轮：总结我们刚才的对话内容");
        assert.equal(Object.hasOwn(body.payload, "originalPrompt"), false);
        assert.equal(Object.hasOwn(body.payload, "conversationContext"), false);
        assert.equal(Object.hasOwn(body.payload, "messages"), false);
        assert.equal(body.payload.prompt.includes("HWLAB 同一会话的已脱敏历史上下文"), false);
        assert.equal(body.payload.prompt.includes("hwl_live_test_secret"), false);
        assert.equal(body.payload.prompt.includes("sk-test-hwpod-secret"), false);
      } else {
        assert.equal(Object.hasOwn(body.payload, "conversationContext"), false);
      }
      return send({ id: secondTurn ? "cmd_hwlab_adapter_second" : "cmd_hwlab_adapter", runId: "run_hwlab_adapter", state: "pending", type: "turn", seq: secondTurn ? 2 : 1 });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_hwlab_adapter/commands") {
      return send({ items: [
        { id: "cmd_hwlab_adapter", runId: "run_hwlab_adapter", state: "completed", type: "turn", seq: 1, idempotencyKey: "trc_server-test-agentrun-adapter", payload: { traceId: "trc_server-test-agentrun-adapter", conversationId: "cnv_server-test-agentrun", hwlabSessionId: "ses_server-test-agentrun", threadId: "019e8078-db67-7750-a5d9-1a99f3abd445", providerProfile: "deepseek" } },
        { id: "cmd_hwlab_adapter_steer", runId: "run_hwlab_adapter", state: "completed", type: "steer", seq: 7, idempotencyKey: "trc_steer_server_test", payload: { traceId: "trc_steer_server_test", targetTraceId: "trc_server-test-agentrun-adapter", targetCommandId: "cmd_hwlab_adapter", conversationId: "cnv_server-test-agentrun", hwlabSessionId: "ses_server-test-agentrun", threadId: "019e8078-db67-7750-a5d9-1a99f3abd445", providerProfile: "deepseek" } },
        { id: "cmd_hwlab_adapter_second", runId: "run_hwlab_adapter", state: "completed", type: "turn", seq: 2, idempotencyKey: "trc_server-test-agentrun-adapter-second", payload: { traceId: "trc_server-test-agentrun-adapter-second", conversationId: "cnv_server-test-agentrun", hwlabSessionId: "ses_server-test-agentrun", threadId: "019e8078-db67-7750-a5d9-1a99f3abd445", providerProfile: "deepseek" } }
      ] });
    }
    if (request.method === "POST" && url.pathname === "/api/v1/runs/run_hwlab_adapter/runner-jobs") {
      const secondRunnerJob = body.commandId === "cmd_hwlab_adapter_second";
      assert.ok(body.commandId === "cmd_hwlab_adapter" || secondRunnerJob);
      const transientEnv = Object.fromEntries(body.transientEnv.map((entry) => [entry.name, entry.value]));
      assert.equal(transientEnv.HWLAB_RUNTIME_API_URL, "http://hwlab-cloud-api.hwlab-v03.svc.cluster.local:6667");
      assert.equal(transientEnv.HWLAB_RUNTIME_WEB_URL, "http://hwlab-cloud-web.hwlab-v03.svc.cluster.local:8080");
      assert.equal(transientEnv.HWLAB_RUNTIME_NAMESPACE, "hwlab-v03");
      assert.equal(transientEnv.HWLAB_RUNTIME_LANE, "v03");
      assert.equal(transientEnv.HWLAB_RUNTIME_ENDPOINT_LOCKED, "1");
      assert.equal(transientEnv.HWLAB_CODE_AGENT_ASSEMBLED_RUNTIME, "1");
      assert.equal(transientEnv.UNIDESK_MAIN_SERVER_IP, "http://74.48.78.17:18081");
      assert.equal(transientEnv.HWLAB_CODE_AGENT_PROVIDER_PROFILE, "deepseek");
      assert.equal(transientEnv.HWLAB_CODE_AGENT_PARENT_TRACE_ID, secondRunnerJob ? "trc_server-test-agentrun-adapter-second" : "trc_server-test-agentrun-adapter");
      assert.ok(body.transientEnv.length >= 9);
      assert.equal(Object.hasOwn(transientEnv, "UNIDESK_SSH_CLIENT_TOKEN"), false);
      assert.equal(Object.hasOwn(transientEnv, "GH_TOKEN"), false);
      return send({
        action: "create-kubernetes-job",
        runId: "run_hwlab_adapter",
        commandId: body.commandId,
        attemptId: secondRunnerJob ? "attempt_hwlab_adapter_second" : "attempt_hwlab_adapter",
        runnerId: secondRunnerJob ? "runner_hwlab_adapter_second" : "runner_hwlab_adapter",
        namespace: "agentrun-v01",
        jobName: secondRunnerJob ? "agentrun-v01-runner-hwlab-adapter-second" : "agentrun-v01-runner-hwlab-adapter",
        jobIdentity: { namespace: "agentrun-v01", name: secondRunnerJob ? "agentrun-v01-runner-hwlab-adapter-second" : "agentrun-v01-runner-hwlab-adapter" },
        runner: { attemptId: secondRunnerJob ? "attempt_hwlab_adapter_second" : "attempt_hwlab_adapter", runnerId: secondRunnerJob ? "runner_hwlab_adapter_second" : "runner_hwlab_adapter" }
      });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_hwlab_adapter/events") {
      const afterSeq = Number.parseInt(url.searchParams.get("afterSeq") ?? "0", 10);
      const second = afterSeq >= 5 || url.searchParams.get("afterSeq") === "3" || calls.some((call) => call.path === "/api/v1/runs/run_hwlab_adapter/commands/cmd_hwlab_adapter_second/result");
      if (second) return send({ items: [
        { id: "evt_old_tail", runId: "run_hwlab_adapter", seq: 6, type: "assistant_message", payload: { commandId: "cmd_hwlab_adapter", text: "旧 command 尾部不应进入第二轮。" }, createdAt: "2026-06-01T00:00:02.500Z" },
        { id: "evt_7", runId: "run_hwlab_adapter", seq: 7, type: "backend_status", payload: { phase: "turn-started", commandId: "cmd_hwlab_adapter_second", attemptId: "attempt_hwlab_adapter_second", runnerId: "runner_hwlab_adapter_second", jobName: "agentrun-v01-runner-hwlab-adapter-second", namespace: "agentrun-v01" }, createdAt: "2026-06-01T00:00:03.000Z" },
        { id: "evt_7_prompt", runId: "run_hwlab_adapter", seq: 8, type: "backend_status", payload: { phase: "initial-prompt-assembly", commandId: "cmd_hwlab_adapter_second", initialPromptInjected: false, reason: "thread-resume", initialPrompt: { available: true, bytes: 512, sha256: "prompt-sha", promptRefCount: 1, skillCount: 3, valuesPrinted: false } }, createdAt: "2026-06-01T00:00:03.500Z" },
        { id: "evt_8", runId: "run_hwlab_adapter", seq: 8, type: "assistant_message", payload: { commandId: "cmd_hwlab_adapter_second", text: "AgentRun adapter 复用已有 runner 完成第二轮。" }, createdAt: "2026-06-01T00:00:04.000Z" },
        { id: "evt_9", runId: "run_hwlab_adapter", seq: 9, type: "terminal_status", payload: { commandId: "cmd_hwlab_adapter_second", terminalStatus: "completed" }, createdAt: "2026-06-01T00:00:05.000Z" }
      ] });
      return send({ items: [
        { id: "evt_1", runId: "run_hwlab_adapter", seq: 1, type: "backend_status", payload: { phase: "runner-job-created", commandId: "cmd_hwlab_adapter", attemptId: "attempt_hwlab_adapter", jobName: "agentrun-v01-runner-hwlab-adapter", namespace: "agentrun-v01" }, createdAt: "2026-06-01T00:00:00.000Z" },
          { id: "evt_bundle", runId: "run_hwlab_adapter", seq: 2, type: "backend_status", payload: { phase: "resource-bundle-materialized", commandId: "cmd_hwlab_adapter", kind: "gitbundle", commitId: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", bundles: { count: 2, names: ["hwlab-tools", "hwlab-agent-skills"], targetPaths: ["tools", ".agents/skills"], valuesPrinted: false }, tools: { count: 5, names: ["hwpod", "hwpod-ctl", "hwpod-compiler", "unidesk-ssh", "hwlab-code-agent"], valuesPrinted: false }, promptRefs: { count: 1, names: ["hwlab-v02-runtime"], valuesPrinted: false }, skillDirs: { count: 4, names: ["hwpod-cli", "hwpod-ctl", "hwlab-agent-runtime", "hwlab-code-agent"], valuesPrinted: false }, initialPrompt: { available: true, bytes: 512, sha256: "prompt-sha", promptRefCount: 1, skillCount: 4, skillNames: ["hwpod-cli", "hwpod-ctl", "hwlab-agent-runtime", "hwlab-code-agent"], valuesPrinted: false } }, createdAt: "2026-06-01T00:00:00.250Z" },
          { id: "evt_tool", runId: "run_hwlab_adapter", seq: 2, type: "tool_call", payload: { method: "item/completed", type: "commandExecution", toolName: "commandExecution", itemId: "call_agentrun_tool", command: "/bin/sh -lc 'hwpod inspect --dry-run'", status: "completed", exitCode: 0, durationMs: 708, outputSummary: '{"ok":true,"action":"hwpod-cli.plan"}', summary: { outputBytes: 42, outputTruncated: false }, commandId: "cmd_hwlab_adapter", runnerId: "runner_hwlab_adapter", attemptId: "attempt_hwlab_adapter" }, createdAt: "2026-06-01T00:00:00.500Z" },
        { id: "evt_noise", runId: "run_hwlab_adapter", seq: 3, type: "backend_status", payload: { phase: "thread/status/changed", commandId: "cmd_hwlab_adapter" }, createdAt: "2026-06-01T00:00:00.750Z" },
        { id: "evt_prompt", runId: "run_hwlab_adapter", seq: 4, type: "backend_status", payload: { phase: "initial-prompt-assembly", commandId: "cmd_hwlab_adapter", initialPromptInjected: true, reason: "thread-start", initialPrompt: { available: true, bytes: 512, sha256: "prompt-sha", promptRefCount: 1, skillCount: 4, valuesPrinted: false } }, createdAt: "2026-06-01T00:00:00.875Z" },
        { id: "evt_2", runId: "run_hwlab_adapter", seq: 4, type: "assistant_message", payload: { commandId: "cmd_hwlab_adapter", text: "AgentRun adapter 已接管 HWLAB Code Agent。" }, createdAt: "2026-06-01T00:00:01.000Z" },
        { id: "evt_3", runId: "run_hwlab_adapter", seq: 5, type: "terminal_status", payload: { commandId: "cmd_hwlab_adapter", terminalStatus: "completed" }, createdAt: "2026-06-01T00:00:02.000Z" }
      ] });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_hwlab_adapter/commands/cmd_hwlab_adapter/result") {
      return send({
        runId: "run_hwlab_adapter",
        commandId: "cmd_hwlab_adapter",
        attemptId: "attempt_hwlab_adapter",
        runnerId: "runner_hwlab_adapter",
        jobName: "agentrun-v01-runner-hwlab-adapter",
        namespace: "agentrun-v01",
        status: "completed",
        runStatus: "completed",
        commandState: "completed",
        terminalStatus: "completed",
        completed: true,
        reply: "AgentRun adapter 已接管 HWLAB Code Agent。",
        lastSeq: 5,
        eventCount: 5,
        sessionRef: { sessionId: "ses_agentrun_deepseek_server_test_agentrun", conversationId: "cnv_server-test-agentrun", threadId: "019e8078-db67-7750-a5d9-1a99f3abd445" }
      });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_hwlab_adapter/commands/cmd_hwlab_adapter_second/result") {
      return send({
        runId: "run_hwlab_adapter",
        commandId: "cmd_hwlab_adapter_second",
        attemptId: "attempt_hwlab_adapter_second",
        runnerId: "runner_hwlab_adapter_second",
        jobName: "agentrun-v01-runner-hwlab-adapter-second",
        namespace: "agentrun-v01",
        status: "completed",
        runStatus: "claimed",
        commandState: "completed",
        terminalStatus: "completed",
        completed: true,
        reply: "AgentRun adapter 复用已有 runner 完成第二轮。",
        lastSeq: 9,
        eventCount: 9,
        sessionRef: { sessionId: "ses_agentrun_deepseek_server_test_agentrun", conversationId: "cnv_server-test-agentrun", threadId: "019e8078-db67-7750-a5d9-1a99f3abd445" }
      });
    }
    response.writeHead(404, { "content-type": "application/json" });
    response.end(`${JSON.stringify({ ok: false, failureKind: "schema-invalid", message: `unexpected ${request.method} ${url.pathname}`, traceId: "trc_fake_agentrun" })}\n`);
  });
  await new Promise((resolve) => agentRunServer.listen(0, "127.0.0.1", resolve));

  const agentRunPort = agentRunServer.address().port;
  const traceStore = createCodeAgentTraceStore();
  const server = createCloudApiServer({
    traceStore,
    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_CODE_AGENT_AGENTRUN_SOURCE_COMMIT: "0123456789abcdef0123456789abcdef01234567",
      HWLAB_CODE_AGENT_DEFAULT_PROVIDER_PROFILE: "deepseek",
      HWLAB_CODE_AGENT_DEEPSEEK_MODEL: "deepseek-chat",
      HWLAB_ENVIRONMENT: "v03",
      HWLAB_GITOPS_PROFILE: "v03",
      HWLAB_BOOT_REF: "v0.3",
      UNIDESK_MAIN_SERVER_IP: "http://74.48.78.17:18081"
    },
    accessController: {
      required: false,
      async authenticate() {
        return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION };
      },
      async recordAgentSessionOwner(input) {
        const existing = ownerSessions.get(input.sessionId ?? input.id);
        const record = testAgentSessionRecord({
          ...existing,
          ...input,
          session: { ...(existing?.session ?? {}), ...(input.session ?? {}) }
        });
        ownerSessions.set(record.id, record);
        return record;
      },
      async getAgentSession(sessionId) {
        return ownerSessions.get(sessionId) ?? null;
      },
      async visibleConversationForActor(actor, conversationId, projectId) {
        assert.equal(actor.id, "usr_agent_owner");
        assert.equal(actor.role, "user");
        assert.equal(conversationId, "cnv_server-test-agentrun");
        assert.equal(projectId, "prj_hwpod_workbench");
        return { conversationId, messages: conversationMessages };
      }
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const traceId = "trc_server-test-agentrun-adapter";
    ownerSessions.set("ses_server-test-agentrun", testAgentSessionRecord({
      sessionId: "ses_server-test-agentrun",
      conversationId: "cnv_server-test-agentrun",
      projectId: "prj_hwpod_workbench",
      status: "idle",
      threadId: "019e8078-db67-7750-a5d9-1a99f3abd445"
    }));
    const submit = await fetch(`http://127.0.0.1:${port}/v1/agent/chat`, {
      method: "POST",
      headers: { "content-type": "application/json", "x-trace-id": traceId, cookie: "hwlab_session=test-stub-session" },
      body: JSON.stringify({
        conversationId: "cnv_server-test-agentrun",
        projectId: "prj_hwpod_workbench",
        sessionId: "ses_server-test-agentrun",
        ownerUserId: "usr_agent_owner",
        ownerRole: "user",
        threadId: "019e8078-db67-7750-a5d9-1a99f3abd445",
        retryOf: "trc_previous-agentrun-web",
        message: "AgentRun adapter smoke"
      })
    });
    assert.equal(submit.status, 202);
    const accepted = await submit.json();
    assert.equal(accepted.shortConnection, true);
    assert.equal(accepted.turnId, traceId);
    assert.equal(accepted.userMessageId, "msg_server-test-agentrun-adapter_user");
    assert.equal(accepted.assistantMessageId, "msg_server-test-agentrun-adapter_agent");

    for (let index = 0; index < 50 && !traceStore.snapshot(traceId).events.some((event) => event.label === "agentrun:result:completed"); index += 1) await delay(10);
    const projectedTrace = traceStore.snapshot(traceId);
    assert.equal(projectedTrace.status, "completed");
    assert.ok(projectedTrace.events.some((event) => event.label === "agentrun:assistant:message"));
    assert.ok(projectedTrace.events.some((event) => event.label === "agentrun:result:completed"));

    const acceptedTurn = await fetch(`http://127.0.0.1:${port}/v1/agent/turns/${encodeURIComponent(traceId)}`, { headers: { cookie: "hwlab_session=test-stub-session" } });
    assert.equal(acceptedTurn.status, 200);
    const acceptedTurnPayload = await acceptedTurn.json();
    assert.equal(acceptedTurnPayload.turnId, traceId);
    assert.equal(acceptedTurnPayload.userMessageId, accepted.userMessageId);
    assert.equal(acceptedTurnPayload.assistantMessageId, accepted.assistantMessageId);

    const payload = await pollAgentResult(port, traceId);
    validateCodeAgentChatSchema(payload);
    assert.equal(payload.status, "completed");
    assert.equal(payload.turnId, traceId);
    assert.equal(payload.userMessageId, accepted.userMessageId);
    assert.equal(payload.assistantMessageId, accepted.assistantMessageId);
    assert.equal(payload.provider, "deepseek");
    assert.equal(payload.backend, "agentrun-v01/deepseek");
    assert.equal(payload.infrastructureBackend, "agentrun-v01/deepseek");
    assert.equal(payload.capabilityLevel, "agentrun-v01-shared-code-agent-session");
    assert.equal(payload.sessionMode, "agentrun-v01-durable-session");
    assert.equal(payload.implementationType, "agentrun-v01-shared-execution-infra");
    assert.equal(payload.runner.kind, "agentrun-v01-shared-runner");
    assert.equal(payload.runner.provider, "deepseek");
    assert.equal(payload.runner.codexStdio, false);
    assert.equal(payload.runner.delegatedToAgentRun, true);
    assert.equal(payload.providerTrace.protocol, "agentrun-v01-jsonrpc");
    assert.equal(payload.providerTrace.command, "agentrun.v01.command.turn");
    assert.equal(payload.providerTrace.runnerKind, "agentrun-v01-shared-runner");
    assert.equal(payload.providerTrace.terminalStatus, "completed");
    assert.equal(payload.longLivedSessionGate.status, "pass");
    assert.equal(payload.longLivedSessionGate.provider, "deepseek");
    assert.equal(payload.longLivedSessionGate.codexStdio, false);
    assert.equal(payload.longLivedSessionGate.delegatedToAgentRun, true);
    assert.equal(payload.agentRun.runId, "run_hwlab_adapter");
    assert.equal(payload.agentRun.commandId, "cmd_hwlab_adapter");
    assert.equal(payload.agentRun.jobName, "agentrun-v01-runner-hwlab-adapter");
    const serializedPayload = JSON.stringify(payload);
    assert.equal(serializedPayload.includes("repo-owned-codex"), false);
    assert.equal(serializedPayload.includes("codex-app-server-stdio"), false);
    assert.equal(serializedPayload.includes("\"provider\":\"codex-stdio\""), false);
    assert.equal(serializedPayload.includes("\"codexStdio\":true"), false);
    assert.match(payload.reply.content, /AgentRun adapter/u);
    assert.ok(payload.runnerTrace.events.some((event) => event.label === "agentrun:backend:runner-job-created"));
    const bundleEvent = payload.runnerTrace.events.find((event) => event.label === "agentrun:backend:resource-bundle-materialized");
    assert.equal(bundleEvent?.details?.kind, "gitbundle");
    assert.deepEqual(bundleEvent?.details?.bundles?.names, ["hwlab-tools", "hwlab-agent-skills"]);
    assert.deepEqual(bundleEvent?.details?.tools?.names, ["hwpod", "hwpod-ctl", "hwpod-compiler", "unidesk-ssh", "hwlab-code-agent"]);
    assert.deepEqual(bundleEvent?.details?.promptRefs?.names, ["hwlab-v02-runtime"]);
    assert.deepEqual(bundleEvent?.details?.skillDirs?.names, ["hwpod-cli", "hwpod-ctl", "hwlab-agent-runtime", "hwlab-code-agent"]);
    const promptEvent = payload.runnerTrace.events.find((event) => event.label === "agentrun:backend:initial-prompt-assembly");
    assert.equal(promptEvent?.details?.initialPromptInjected, true);
    assert.equal(promptEvent?.details?.reason, "thread-start");
    assert.equal(promptEvent?.details?.initialPrompt?.promptRefCount, 1);
    assert.equal(promptEvent?.details?.initialPrompt?.skillCount, 4);
    assert.ok(calls.some((call) => call.path === "/api/v1/runs/run_hwlab_adapter/runner-jobs"));

    const inspectByTrace = await fetch(`http://127.0.0.1:${port}/v1/agent/chat/inspect?traceId=${traceId}`);
    assert.equal(inspectByTrace.status, 200);
    const inspectByTraceBody = await inspectByTrace.json();
    assert.equal(inspectByTraceBody.ok, true);
    assert.equal(inspectByTraceBody.latestTraceId, traceId);
    assert.equal(inspectByTraceBody.session.sessionId, "ses_server-test-agentrun");
    assert.equal(inspectByTraceBody.session.conversationId, "cnv_server-test-agentrun");
    assert.equal(inspectByTraceBody.session.threadId, "019e8078-db67-7750-a5d9-1a99f3abd445");
    assert.equal(inspectByTraceBody.conversationFacts.conversationId, "cnv_server-test-agentrun");
    assert.equal(inspectByTraceBody.conversationFacts.threadId, "019e8078-db67-7750-a5d9-1a99f3abd445");
    assert.equal(inspectByTraceBody.runnerTrace.traceId, traceId);
    assert.equal(inspectByTraceBody.valuesRedacted, true);
    assert.equal(JSON.stringify(inspectByTraceBody).includes("hwl_live_test_secret"), false);

    const trace = await fetch(`http://127.0.0.1:${port}/v1/agent/traces/${traceId}`);
    assert.equal(trace.status, 200);
    const traceBody = await trace.json();
    const requestTraceEvent = traceBody.events.find((event) => event.label === "agentrun:request:accepted");
    assert.equal(requestTraceEvent.eventType, "request");
    assert.equal(requestTraceEvent.backend, "agentrun-v01/deepseek");
    const runnerJobTraceEvent = traceBody.events.find((event) => event.label === "agentrun:runner-job:created");
    assert.equal(runnerJobTraceEvent.eventType, "backend");
    assert.equal(runnerJobTraceEvent.backend, "agentrun-v01/deepseek");
    assert.ok(traceBody.events.some((event) => event.runId === "run_hwlab_adapter"));
    assert.ok(traceBody.events.some((event) => event.label === "agentrun:assistant:message"));
    assert.equal(traceBody.events.some((event) => event.details?.initialPromptInjected === true), true);
    const commandTraceEvent = traceBody.events.find((event) => event.label === "item/commandExecution:completed");
    assert.equal(commandTraceEvent.eventType, "tool_call");
    assert.equal(commandTraceEvent.backend, "agentrun-v01/deepseek");
    assert.ok(Date.parse(commandTraceEvent.appendedAt) >= Date.parse(commandTraceEvent.createdAt));
    assert.equal(commandTraceEvent.toolName, "commandExecution");
    assert.equal(commandTraceEvent.createdAt, "2026-06-01T00:00:00.500Z");
    assert.match(commandTraceEvent.command, /hwpod inspect --dry-run/u);
    assert.match(commandTraceEvent.stdoutSummary, /hwpod-cli\.plan/u);
    conversationMessages.push(
      {
        id: "msg_693_user",
        role: "user",
        text: "看看 HWPOD 可用性？",
        status: "sent",
        traceId,
        conversationId: "cnv_server-test-agentrun",
        sessionId: "ses_server-test-agentrun",
        threadId: "019e8078-db67-7750-a5d9-1a99f3abd445",
        createdAt: "2026-06-02T00:00:00.000Z"
      },
      {
        id: "msg_693_agent",
        role: "agent",
        text: "v0.2 HWPOD 可用性快照：可用；apiKey=hwl_live_test_secret sk-test-hwpod-secret-000000",
        status: "completed",
        traceId,
        conversationId: "cnv_server-test-agentrun",
        sessionId: "ses_server-test-agentrun",
        threadId: "019e8078-db67-7750-a5d9-1a99f3abd445",
        createdAt: "2026-06-02T00:00:01.000Z"
      }
    );

    const steerRequest = fetch(`http://127.0.0.1:${port}/v1/agent/chat/steer`, {
      method: "POST",
      headers: { "content-type": "application/json", "x-trace-id": traceId, cookie: "hwlab_session=test-stub-session" },
      body: JSON.stringify({
        traceId,
        steerTraceId: "trc_steer_server_test",
        conversationId: "cnv_server-test-agentrun",
        projectId: "prj_hwpod_workbench",
        sessionId: "ses_server-test-agentrun",
        threadId: "019e8078-db67-7750-a5d9-1a99f3abd445",
        message: "请按 STEER_MARK 调整最终回复"
      })
    });
    const steer = await Promise.race([
      steerRequest,
      delay(100).then(() => null)
    ]);
    assert.ok(steer, "terminal steer rejection must return as a short response");
    assert.equal(steer.status, 409);
    const steerBody = await steer.json();
    assert.equal(steerBody.accepted, false);
    assert.equal(steerBody.error.code, "steer_trace_terminal");
    assert.equal(steerBody.route, "/v1/agent/chat/steer");
    assert.equal(steerBody.traceId, traceId);
    assert.equal(steerBody.agentRun.runId, "run_hwlab_adapter");
    assert.equal(calls.some((call) => call.method === "POST" && call.path === "/api/v1/runs/run_hwlab_adapter/commands" && call.body?.type === "steer"), false);

    const secondTraceId = "trc_server-test-agentrun-adapter-second";
    const second = await fetch(`http://127.0.0.1:${port}/v1/agent/chat`, {
      method: "POST",
      headers: { "content-type": "application/json", "x-trace-id": secondTraceId, cookie: "hwlab_session=test-stub-session" },
      body: JSON.stringify({
        conversationId: "cnv_server-test-agentrun",
        projectId: "prj_hwpod_workbench",
        sessionId: "ses_server-test-agentrun",
        ownerUserId: "usr_agent_owner",
        ownerRole: "user",
        threadId: "019e8078-db67-7750-a5d9-1a99f3abd445",
        message: "AgentRun adapter smoke 第二轮：总结我们刚才的对话内容"
      })
    });
    assert.equal(second.status, 202);
    const secondPayload = await pollAgentResult(port, secondTraceId);
    validateCodeAgentChatSchema(secondPayload);
    assert.equal(secondPayload.status, "completed");
    assert.equal(secondPayload.provider, "deepseek");
    assert.equal(secondPayload.backend, "agentrun-v01/deepseek");
    assert.equal(secondPayload.runner.kind, "agentrun-v01-shared-runner");
    assert.equal(secondPayload.runner.codexStdio, false);
    assert.equal(secondPayload.agentRun.runId, "run_hwlab_adapter");
    assert.equal(secondPayload.agentRun.commandId, "cmd_hwlab_adapter_second");
    assert.equal(secondPayload.providerTrace.commandId, "cmd_hwlab_adapter_second");
    assert.equal(secondPayload.providerTrace.traceId, secondTraceId);
    assert.equal(secondPayload.agentRun.providerTrace.commandId, "cmd_hwlab_adapter_second");
    assert.equal(secondPayload.agentRun.providerTrace.traceId, secondTraceId);
    assert.equal(secondPayload.agentRun.jobName, "agentrun-v01-runner-hwlab-adapter-second");
    assert.equal(secondPayload.sessionReuse.reused, true);
    assert.equal(secondPayload.agentRun.runnerJobCount, 1);
    assert.match(secondPayload.reply.content, /复用已有 runner/u);
    assert.ok(secondPayload.runnerTrace.events.some((event) => event.label === "agentrun:run:reused"));
    assert.ok(secondPayload.runnerTrace.events.some((event) => event.label === "agentrun:runner-job:ensured"));
    assert.equal(secondPayload.runnerTrace.events.some((event) => String(event.text ?? event.message ?? "").includes("旧 command 尾部")), false);
    assert.equal(calls.filter((call) => call.method === "POST" && call.path === "/api/v1/runs").length, 1);
    assert.equal(calls.filter((call) => call.method === "POST" && call.path === "/api/v1/runs/run_hwlab_adapter/runner-jobs").length, 2);
    assert.equal(calls.filter((call) => call.method === "POST" && call.path === "/api/v1/runs/run_hwlab_adapter/commands").length, 2);
  } 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 keeps admitted user message when billing preflight fails before AgentRun dispatch (#1619)", async () => {
  const traceId = "trc_issue1619_billing_after_admission";
  const sessionId = "ses_issue1619_billing_after_admission";
  const conversationId = "cnv_issue1619_billing_after_admission";
  const ownerSessions = new Map([[sessionId, testAgentSessionRecord({ sessionId, conversationId, projectId: "prj_hwpod_workbench", status: "idle" })]]);
  const ownerWrites = [];
  const billingCalls = [];
  const agentRunCalls = [];
  const agentRunServer = createHttpServer(async (request, response) => {
    agentRunCalls.push({ method: request.method, url: request.url });
    response.writeHead(500, { "content-type": "application/json" });
    response.end(`${JSON.stringify({ ok: false, message: "AgentRun must not be called when billing preflight failed" })}\n`);
  });
  await new Promise((resolve) => agentRunServer.listen(0, "127.0.0.1", resolve));
  const agentRunPort = agentRunServer.address().port;
  const traceStore = createCodeAgentTraceStore();
  const server = createCloudApiServer({
    traceStore,
    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_CODE_AGENT_AGENTRUN_SOURCE_COMMIT: "0123456789abcdef0123456789abcdef01234567",
      HWLAB_CODE_AGENT_DEFAULT_PROVIDER_PROFILE: "deepseek",
      HWLAB_ENVIRONMENT: "v03",
      HWLAB_GITOPS_PROFILE: "v03",
      HWLAB_USER_BILLING_CODE_AGENT_ENABLED: "1"
    },
    userBillingAuth: { active: true },
    userBillingClient: {
      configured: true,
      async billingPreflight(body) {
        billingCalls.push(body);
        assert.ok(ownerWrites.some((write) => write.traceId === traceId && write.status === "running"), "durable admission must be recorded before billing preflight");
        return { ok: false, status: 503, error: { code: "billing_preflight_unavailable", message: "billing preflight unavailable" } };
      }
    },
    accessController: {
      required: false,
      async authenticate() {
        return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION, userBilling: { active: true } };
      },
      async recordAgentSessionOwner(input) {
        ownerWrites.push(input);
        const existing = ownerSessions.get(input.sessionId ?? input.id);
        const record = testAgentSessionRecord({
          ...existing,
          ...input,
          session: { ...(existing?.session ?? {}), ...(input.session ?? {}) }
        });
        ownerSessions.set(record.id, record);
        return record;
      },
      async getAgentSession(requestedSessionId) {
        return ownerSessions.get(requestedSessionId) ?? null;
      }
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const submit = await fetch(`http://127.0.0.1:${port}/v1/agent/chat`, {
      method: "POST",
      headers: { "content-type": "application/json", "x-trace-id": traceId, cookie: "hwlab_session=test-stub-session" },
      body: JSON.stringify({
        conversationId,
        projectId: "prj_hwpod_workbench",
        sessionId,
        message: "测试一下和 cpython 对比的性能"
      })
    });
    assert.equal(submit.status, 202);
    const accepted = await submit.json();
    assert.equal(accepted.accepted, true);
    assert.equal(accepted.traceId, traceId);

    const payload = await pollAgentResult(port, traceId);
    validateCodeAgentChatSchema(payload);
    assert.equal(payload.status, "failed");
    assert.equal(payload.error.code, "billing_preflight_unavailable");
    assert.match(payload.finalResponse.text, /billing preflight unavailable/u);
    assert.equal(billingCalls.length, 1);
    assert.equal(agentRunCalls.length, 0);
    assert.ok(ownerWrites.some((write) => write.traceId === traceId && write.status === "running"));
    assert.ok(ownerWrites.some((write) => write.traceId === traceId && write.status === "failed"));
    const stored = ownerSessions.get(sessionId);
    const userMessage = stored?.session?.messages?.find((message) => message.role === "user");
    assert.match(userMessage?.text ?? "", /cpython/u);

    const turn = await fetch(`http://127.0.0.1:${port}/v1/agent/turns/${traceId}`, { headers: { cookie: "hwlab_session=test-stub-session" } });
    assert.equal(turn.status, 200);
    const turnBody = await turn.json();
    assert.equal(turnBody.status, "failed");
    assert.equal(turnBody.error.code, "billing_preflight_unavailable");
  } 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("AgentRun sync converts terminal command result even when run remains claimed (#1555)", async () => {
  const calls = [];
  const traceId = "trc_issue1555_terminal_command";
  const runId = "run_issue1555_claimed";
  const commandId = "cmd_issue1555_completed";
  const finalText = [
    "已新增并实际运行：",
    "",
    "- Go：`go test ./...`  保留两个空格",
    "- Rust：`cargo test --release`",
    "",
    "```sh",
    "go test ./...",
    "cargo test --release",
    "```",
    "",
    "| benchmark | Go | Rust |",
    "|---|---:|---:|",
    "| fib | 1.2ms | 1.0ms |"
  ].join("\n");
  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_issue1555" })}\n`);
    };
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/events`) {
      return send({ items: [
        { id: "evt_issue1555_assistant", runId, seq: 138, type: "assistant_message", payload: { commandId, text: finalText, final: true, replyAuthority: true }, createdAt: "2026-06-18T00:00:00.000Z" },
        { id: "evt_issue1555_terminal", runId, seq: 139, type: "terminal_status", payload: { commandId, terminalStatus: "completed" }, createdAt: "2026-06-18T00:00:00.000Z" }
      ] });
    }
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/commands`) {
      return send({ items: [
        { id: commandId, runId, state: "completed", type: "turn", seq: 1, idempotencyKey: traceId, payload: { traceId, conversationId: "cnv_issue1555", hwlabSessionId: "ses_issue1555", threadId: "thread_issue1555" } }
      ] });
    }
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/commands/${commandId}/result`) {
      return send({
        runId,
        commandId,
        attemptId: "attempt_issue1555",
        runnerId: "runner_issue1555",
        jobName: "agentrun-v01-runner-issue1555",
        namespace: "agentrun-v02",
        status: "completed",
        runStatus: "claimed",
        commandState: "completed",
        terminalStatus: "completed",
        completed: true,
        reply: finalText,
        lastSeq: 139,
        eventCount: 139,
        sessionRef: { sessionId: "ses_issue1555", conversationId: "cnv_issue1555", threadId: "thread_issue1555" }
      });
    }
    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 traceStore = createCodeAgentTraceStore();
  try {
    const currentResult = {
      ok: true,
      accepted: true,
      shortConnection: true,
      status: "running",
      traceId,
      conversationId: "cnv_issue1555",
      sessionId: "ses_issue1555",
      threadId: "thread_issue1555",
      agentRun: {
        adapter: "agentrun-v01",
        managerUrl: `http://127.0.0.1:${agentRunPort}`,
        runId,
        commandId,
        status: "pending",
        runStatus: "claimed",
        commandState: "pending",
        terminalStatus: null,
        lastSeq: 0,
        valuesPrinted: false
      },
      valuesPrinted: false
    };
    const synced = await syncAgentRunChatResult({
      traceId,
      currentResult,
      traceStore,
      options: {
        env: {
          AGENTRUN_MGR_URL: `http://127.0.0.1:${agentRunPort}`,
          HWLAB_CODE_AGENT_AGENTRUN_ALLOW_NON_K3S_URL: "1"
        }
      }
    });
    assert.equal(synced.resultSynced, true);
    assert.equal(synced.result.status, "completed");
    assert.equal(synced.result.agentRun.runStatus, "claimed");
    assert.equal(synced.result.agentRun.commandState, "completed");
    assert.equal(synced.result.agentRun.terminalStatus, "completed");
    assert.equal(synced.result.finalResponse.text, finalText);
    assert.equal(synced.result.reply.content, finalText);
    assert.ok((synced.result.finalResponse.text.match(/\n/gu) ?? []).length > 8);
    assert.ok(synced.result.finalResponse.text.includes("`go test ./...`  保留两个空格"));
    const assistantEvent = traceStore.snapshot(traceId).events.find((event) => event.label === "agentrun:assistant:message");
    assert.equal(assistantEvent?.message, finalText);
    assert.deepEqual(calls.map((call) => call.path), [
      `/api/v1/runs/${runId}/commands`,
      `/api/v1/runs/${runId}/events`,
      `/api/v1/runs/${runId}/commands/${commandId}/result`
    ]);
    assert.ok(traceStore.snapshot(traceId).events.some((event) => event.label === "agentrun:result:completed"));
  } finally {
    await new Promise((resolve, reject) => agentRunServer.close((error) => (error ? reject(error) : resolve())));
  }
});

test("AgentRun sync seals completed final response from authoritative terminal assistant trace event (#1629)", async () => {
  const calls = [];
  const traceId = "trc_issue1629_terminal_assistant_final";
  const runId = "run_issue1629_trace_final";
  const commandId = "cmd_issue1629_trace_final";
  const finalText = [
    "全部六份数据到手！下面是完整的六语言终极性能对比：",
    "",
    "| language | runtime | status |",
    "|---|---|---|",
    "| Lua | LuaJIT | pass |"
  ].join("\n");
  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_issue1629" })}\n`);
    };
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/commands`) {
      return send({ items: [
        { id: commandId, runId, state: "completed", type: "turn", seq: 1, idempotencyKey: traceId, payload: { traceId, conversationId: "cnv_issue1629", hwlabSessionId: "ses_issue1629", threadId: "thread_issue1629" } }
      ] });
    }
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/events`) {
      return send({ items: [
        { id: "evt_issue1629_progress", runId, seq: 21, type: "assistant_message", payload: { commandId, text: "正在补 Lua 基准测试。" }, createdAt: "2026-06-19T15:47:13.000Z" },
        { id: "evt_issue1629_final", runId, seq: 28, type: "assistant_message", payload: { commandId, text: finalText, final: true, replyAuthority: true }, createdAt: "2026-06-19T15:47:28.000Z" },
        { id: "evt_issue1629_terminal", runId, seq: 29, type: "terminal_status", payload: { commandId, terminalStatus: "completed" }, createdAt: "2026-06-19T15:47:29.000Z" }
      ] });
    }
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/commands/${commandId}/result`) {
      return send({
        runId,
        commandId,
        attemptId: "attempt_issue1629",
        runnerId: "runner_issue1629",
        jobName: "agentrun-v01-runner-issue1629",
        namespace: "agentrun-v01",
        status: "completed",
        runStatus: "completed",
        commandState: "completed",
        terminalStatus: "completed",
        completed: true,
        reply: null,
        finalResponse: null,
        lastSeq: 29,
        eventCount: 29,
        sessionRef: { sessionId: "ses_issue1629", conversationId: "cnv_issue1629", threadId: "thread_issue1629" }
      });
    }
    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 traceStore = createCodeAgentTraceStore();
  try {
    const currentResult = {
      ok: true,
      accepted: true,
      shortConnection: true,
      status: "running",
      traceId,
      conversationId: "cnv_issue1629",
      sessionId: "ses_issue1629",
      threadId: "thread_issue1629",
      agentRun: {
        adapter: "agentrun-v01",
        managerUrl: `http://127.0.0.1:${agentRunPort}`,
        runId,
        commandId,
        status: "running",
        runStatus: "running",
        commandState: "running",
        terminalStatus: null,
        lastSeq: 0,
        valuesPrinted: false
      },
      valuesPrinted: false
    };
    const synced = await syncAgentRunChatResult({
      traceId,
      currentResult,
      traceStore,
      options: {
        env: {
          AGENTRUN_MGR_URL: `http://127.0.0.1:${agentRunPort}`,
          HWLAB_CODE_AGENT_AGENTRUN_ALLOW_NON_K3S_URL: "1"
        }
      }
    });
    assert.equal(synced.resultSynced, true);
    assert.equal(synced.result.status, "completed");
    assert.equal(synced.result.finalResponse.text, finalText);
    assert.equal(synced.result.assistantText ?? synced.result.finalResponse.text, finalText);
    assert.equal(synced.result.reply.content, finalText);
    assert.equal(synced.result.traceSummary.finalAssistantRow.textChars, finalText.length);
    const assistantEvent = synced.result.runnerTrace.events.find((event) => event.label === "agentrun:assistant:message" && event.message === finalText);
    assert.equal(assistantEvent?.message, finalText);
    assert.deepEqual(calls.map((call) => call.path), [
      `/api/v1/runs/${runId}/commands`,
      `/api/v1/runs/${runId}/events`,
      `/api/v1/runs/${runId}/commands/${commandId}/result`
    ]);
  } finally {
    await new Promise((resolve, reject) => agentRunServer.close((error) => (error ? reject(error) : resolve())));
  }
});

test("cloud api AgentRun adapter reports persistent thread resume when a completed run needs a new runner", async () => {
  const calls = [];
  const hwlabSessionId = "ses_server-test-thread-resume";
  const agentRunSessionId = "ses_agentrun_deepseek_server_test_thread_resume";
  const conversationId = "cnv_server-test-thread-resume";
  const threadId = "019e90e0-9535-7130-a894-47ef4e127206";
  const ownerSessions = new Map([[hwlabSessionId, testAgentSessionRecord({
    sessionId: hwlabSessionId,
    conversationId,
    threadId,
    traceId: "trc_previous_thread_resume",
    status: "idle",
    session: {
      agentRun: {
        adapter: "agentrun-v01",
        backendProfile: "deepseek",
        managerUrl: "http://127.0.0.1:1",
        runId: "run_issue812_previous",
        commandId: "cmd_issue812_previous",
        jobName: "agentrun-v01-runner-issue812-previous",
        namespace: "agentrun-v01",
        sessionId: agentRunSessionId,
        conversationId,
        threadId,
        terminalStatus: "completed",
        runStatus: "completed",
        reuseEligible: true,
        reused: false
      }
    }
  })]]);

  const agentRunServer = createHttpServer(async (request, response) => {
    const url = new URL(request.url || "/", "http://127.0.0.1");
    const chunks = [];
    for await (const chunk of request) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
    const body = chunks.length ? JSON.parse(Buffer.concat(chunks).toString("utf8")) : null;
    calls.push({ method: request.method, path: url.pathname, body });
    const send = (data) => {
      response.writeHead(200, { "content-type": "application/json" });
      response.end(`${JSON.stringify({ ok: true, data, traceId: "trc_fake_issue812_resume" })}\n`);
    };
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_issue812_previous") {
      return send({
        id: "run_issue812_previous",
        status: "completed",
        terminalStatus: "completed",
        backendProfile: "deepseek",
        sessionRef: { sessionId: agentRunSessionId, conversationId, threadId, metadata: {} }
      });
    }
    if (request.method === "POST" && url.pathname === "/api/v1/sessions") {
      assert.equal(body.sessionId, agentRunSessionId);
      assert.equal(body.backendProfile, "deepseek");
      return send({ sessionId: body.sessionId, backendProfile: body.backendProfile });
    }
    if (request.method === "POST" && url.pathname === "/api/v1/runs") {
      assert.equal(body.sessionRef.sessionId, agentRunSessionId);
      assert.equal(body.sessionRef.conversationId, conversationId);
      assert.equal(body.sessionRef.metadata.hwlabSessionId, hwlabSessionId);
      assert.equal(body.sessionRef.metadata.threadContinuityPolicy, "hwlab-agentrun-v01-reuse-runner-thread");
      return send({ id: "run_issue812_resume", status: "pending", backendProfile: "deepseek", sessionRef: body.sessionRef, resourceBundleRef: body.resourceBundleRef });
    }
    if (request.method === "POST" && url.pathname === "/api/v1/runs/run_issue812_resume/commands") {
      assert.equal(body.type, "turn");
      assert.equal(body.payload.sessionId, agentRunSessionId);
      assert.equal(body.payload.hwlabSessionId, hwlabSessionId);
      assert.equal(body.payload.threadId, null);
      assert.match(body.payload.prompt, /ISSUE812_RESUME/u);
      return send({ id: "cmd_issue812_resume", runId: "run_issue812_resume", state: "pending", type: "turn", seq: 1 });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_issue812_resume/commands") {
      return send({ items: [
        { id: "cmd_issue812_resume", runId: "run_issue812_resume", state: "completed", type: "turn", seq: 1, idempotencyKey: "trc_server-test-issue812-resume", payload: { traceId: "trc_server-test-issue812-resume", conversationId, hwlabSessionId, threadId, providerProfile: "deepseek" } }
      ] });
    }
    if (request.method === "POST" && url.pathname === "/api/v1/runs/run_issue812_resume/runner-jobs") {
      assert.equal(body.commandId, "cmd_issue812_resume");
      return send({
        action: "create-kubernetes-job",
        runId: "run_issue812_resume",
        commandId: "cmd_issue812_resume",
        attemptId: "attempt_issue812_resume",
        runnerId: "runner_issue812_resume",
        namespace: "agentrun-v01",
        jobName: "agentrun-v01-runner-issue812-resume",
        jobIdentity: { namespace: "agentrun-v01", name: "agentrun-v01-runner-issue812-resume" },
        runner: { attemptId: "attempt_issue812_resume", runnerId: "runner_issue812_resume" }
      });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_issue812_resume/events") {
      return send({ items: [
        { id: "evt_issue812_1", runId: "run_issue812_resume", seq: 1, type: "backend_status", payload: { phase: "runner-job-created", commandId: "cmd_issue812_resume", attemptId: "attempt_issue812_resume", jobName: "agentrun-v01-runner-issue812-resume", namespace: "agentrun-v01" }, createdAt: "2026-06-04T00:00:00.000Z" },
        { id: "evt_issue812_2", runId: "run_issue812_resume", seq: 2, type: "backend_status", payload: { phase: "initial-prompt-assembly", commandId: "cmd_issue812_resume", initialPromptInjected: false, reason: "thread-resume" }, createdAt: "2026-06-04T00:00:00.500Z" },
        { id: "evt_issue812_3", runId: "run_issue812_resume", seq: 3, type: "assistant_message", payload: { commandId: "cmd_issue812_resume", text: "ISSUE812_RESUME_OK" }, createdAt: "2026-06-04T00:00:01.000Z" },
        { id: "evt_issue812_4", runId: "run_issue812_resume", seq: 4, type: "terminal_status", payload: { commandId: "cmd_issue812_resume", terminalStatus: "completed" }, createdAt: "2026-06-04T00:00:02.000Z" }
      ] });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_issue812_resume/commands/cmd_issue812_resume/result") {
      return send({
        runId: "run_issue812_resume",
        commandId: "cmd_issue812_resume",
        attemptId: "attempt_issue812_resume",
        runnerId: "runner_issue812_resume",
        jobName: "agentrun-v01-runner-issue812-resume",
        namespace: "agentrun-v01",
        status: "completed",
        runStatus: "completed",
        commandState: "completed",
        terminalStatus: "completed",
        completed: true,
        reply: "ISSUE812_RESUME_OK",
        lastSeq: 4,
        eventCount: 4,
        sessionRef: { sessionId: agentRunSessionId, conversationId, threadId }
      });
    }
    response.writeHead(404, { "content-type": "application/json" });
    response.end(`${JSON.stringify({ ok: false, failureKind: "schema-invalid", message: `unexpected ${request.method} ${url.pathname}`, traceId: "trc_fake_issue812_resume" })}\n`);
  });
  await new Promise((resolve) => agentRunServer.listen(0, "127.0.0.1", resolve));

  const agentRunPort = agentRunServer.address().port;
  for (const record of ownerSessions.values()) {
    record.session.agentRun.managerUrl = `http://127.0.0.1:${agentRunPort}`;
  }
  const traceStore = createCodeAgentTraceStore();
  const server = createCloudApiServer({
    traceStore,
    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_CODE_AGENT_AGENTRUN_SOURCE_COMMIT: "0123456789abcdef0123456789abcdef01234567",
      HWLAB_CODE_AGENT_DEFAULT_PROVIDER_PROFILE: "deepseek",
      HWLAB_ENVIRONMENT: "v02",
      HWLAB_GITOPS_PROFILE: "v02"
    },
    accessController: {
      required: false,
      async authenticate() {
        return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION };
      },
      async recordAgentSessionOwner(input) {
        const existing = ownerSessions.get(input.sessionId ?? input.id);
        const record = testAgentSessionRecord({
          ...existing,
          ...input,
          session: { ...(existing?.session ?? {}), ...(input.session ?? {}) }
        });
        ownerSessions.set(record.id, record);
        return record;
      },
      async getAgentSession(sessionId) {
        return ownerSessions.get(sessionId) ?? null;
      }
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const traceId = "trc_server-test-issue812-resume";
    const submit = await fetch(`http://127.0.0.1:${port}/v1/agent/chat`, {
      method: "POST",
      headers: { "content-type": "application/json", "x-trace-id": traceId, cookie: "hwlab_session=test-stub-session" },
      body: JSON.stringify({
        conversationId,
        sessionId: hwlabSessionId,
        ownerUserId: "usr_agent_owner",
        ownerRole: "user",
        threadId,
        message: "ISSUE812_RESUME after completed AgentRun run"
      })
    });
    assert.equal(submit.status, 202);

    const payload = await pollAgentResult(port, traceId);
    validateCodeAgentChatSchema(payload);
    assert.equal(payload.status, "completed");
    assert.equal(payload.sessionId, hwlabSessionId);
    assert.equal(payload.threadId, threadId);
    assert.equal(payload.agentRun.runId, "run_issue812_resume");
    assert.equal(payload.agentRun.reused, false);
    assert.equal(payload.agentRun.runnerReused, false);
    assert.equal(payload.agentRun.threadReused, false);
    assert.equal(payload.agentRun.persistentResume, false);
    assert.equal(payload.sessionReuse.threadId, threadId);
    assert.equal(payload.sessionReuse.reused, true);
    assert.equal(payload.sessionReuse.status, "thread-resumed");
    assert.equal(payload.sessionReuse.runnerReused, false);
    assert.equal(payload.sessionReuse.threadReused, true);
    assert.equal(payload.sessionReuse.persistentResume, true);
    assert.equal(payload.reply.content, "ISSUE812_RESUME_OK");
    assert.equal(calls.some((call) => call.method === "GET" && call.path === "/api/v1/runs/run_issue812_previous"), true);
    assert.equal(calls.filter((call) => call.method === "POST" && call.path === "/api/v1/runs").length, 1);
    assert.equal(calls.filter((call) => call.method === "POST" && call.path === "/api/v1/runs/run_issue812_resume/runner-jobs").length, 1);
  } 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 AgentRun adapter exposes invalid tool-call attribution in result payload", async () => {
  const agentRunServer = createHttpServer(async (request, response) => {
    const url = new URL(request.url || "/", "http://127.0.0.1");
    const chunks = [];
    for await (const chunk of request) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
    const body = chunks.length ? JSON.parse(Buffer.concat(chunks).toString("utf8")) : null;
    const send = (data) => {
      response.writeHead(200, { "content-type": "application/json" });
      response.end(`${JSON.stringify({ ok: true, data, traceId: "trc_fake_agentrun_invalid_tool" })}\n`);
    };
    if (request.method === "POST" && url.pathname === "/api/v1/runs") {
      return send({ id: "run_invalid_tool", status: "pending", backendProfile: "deepseek", sessionRef: body.sessionRef, resourceBundleRef: body.resourceBundleRef });
    }
    if (request.method === "POST" && url.pathname === "/api/v1/runs/run_invalid_tool/commands") {
      return send({ id: "cmd_invalid_tool", runId: "run_invalid_tool", state: "pending", type: "turn", seq: 1 });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_invalid_tool/commands") {
      return send({ items: [
        { id: "cmd_invalid_tool", runId: "run_invalid_tool", state: "failed", type: "turn", seq: 1, idempotencyKey: "trc_server-test-agentrun-invalid-tool", payload: { traceId: "trc_server-test-agentrun-invalid-tool", conversationId: "cnv_invalid_tool", hwlabSessionId: "ses_server-test-invalid-tool", threadId: "thread_invalid_tool", providerProfile: "deepseek" } }
      ] });
    }
    if (request.method === "POST" && url.pathname === "/api/v1/runs/run_invalid_tool/runner-jobs") {
      return send({
        action: "create-kubernetes-job",
        runId: "run_invalid_tool",
        commandId: "cmd_invalid_tool",
        attemptId: "attempt_invalid_tool",
        runnerId: "runner_invalid_tool",
        namespace: "agentrun-v01",
        jobName: "agentrun-v01-runner-invalid-tool",
        runner: { attemptId: "attempt_invalid_tool", runnerId: "runner_invalid_tool" }
      });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_invalid_tool/events") {
      return send({ items: [
        { id: "evt_invalid_tool", runId: "run_invalid_tool", seq: 1, type: "error", payload: { commandId: "cmd_invalid_tool", failureKind: "provider-invalid-tool-call", message: "invalid params, invalid function arguments json string, tool_call_id: call_function_selftest_2 (2013)" }, createdAt: "2026-06-02T00:00:00.000Z" },
        { id: "evt_invalid_tool_terminal", runId: "run_invalid_tool", seq: 2, type: "terminal_status", payload: { commandId: "cmd_invalid_tool", terminalStatus: "failed", failureKind: "provider-invalid-tool-call" }, createdAt: "2026-06-02T00:00:01.000Z" }
      ] });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_invalid_tool/commands/cmd_invalid_tool/result") {
      return send({
        runId: "run_invalid_tool",
        commandId: "cmd_invalid_tool",
        attemptId: "attempt_invalid_tool",
        runnerId: "runner_invalid_tool",
        jobName: "agentrun-v01-runner-invalid-tool",
        namespace: "agentrun-v01",
        status: "failed",
        runStatus: "failed",
        commandState: "failed",
        terminalStatus: "failed",
        failureKind: "provider-invalid-tool-call",
        failureMessage: "invalid params, invalid function arguments json string, tool_call_id: call_function_selftest_2 (2013)",
        completed: false,
        lastSeq: 2,
        eventCount: 2,
        sessionRef: { sessionId: "ses_agentrun_invalid_tool", conversationId: "cnv_invalid_tool", threadId: "thread_invalid_tool" }
      });
    }
    response.writeHead(404, { "content-type": "application/json" });
    response.end(`${JSON.stringify({ ok: false, failureKind: "schema-invalid", message: `unexpected ${request.method} ${url.pathname}`, traceId: "trc_fake_agentrun_invalid_tool" })}\n`);
  });
  await new Promise((resolve) => agentRunServer.listen(0, "127.0.0.1", resolve));
  const agentRunPort = agentRunServer.address().port;
  const ownerSessions = new Map([["ses_server-test-invalid-tool", testAgentSessionRecord({
    sessionId: "ses_server-test-invalid-tool",
    conversationId: "cnv_invalid_tool",
    status: "idle"
  })]]);
  const server = createCloudApiServer({
    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_CODE_AGENT_AGENTRUN_SOURCE_COMMIT: "0123456789abcdef0123456789abcdef01234567",
      HWLAB_CODE_AGENT_DEFAULT_PROVIDER_PROFILE: "deepseek",
      HWLAB_ENVIRONMENT: "v02",
      HWLAB_GITOPS_PROFILE: "v02"
    },
    accessController: {
      required: false,
      async authenticate() {
        return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION };
      },
      async recordAgentSessionOwner(input) {
        const record = testAgentSessionRecord(input);
        ownerSessions.set(record.id, record);
        return record;
      },
      async getAgentSession(sessionId) {
        return ownerSessions.get(sessionId) ?? null;
      }
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const traceId = "trc_server-test-agentrun-invalid-tool";
    const submit = await fetch(`http://127.0.0.1:${port}/v1/agent/chat`, {
      method: "POST",
      headers: { "content-type": "application/json", "x-trace-id": traceId, cookie: "hwlab_session=test-stub-session" },
      body: JSON.stringify({ conversationId: "cnv_invalid_tool", sessionId: "ses_server-test-invalid-tool", message: "invalid tool-call attribution" })
    });
    assert.equal(submit.status, 202);
    const payload = await pollAgentResult(port, traceId);
    validateCodeAgentChatSchema(payload);
    assert.equal(payload.status, "failed");
    assert.equal(payload.providerTrace.failureKind, "provider-invalid-tool-call");
    assert.equal(payload.error.code, "provider-invalid-tool-call");
    assert.equal(payload.error.category, "provider_invalid_tool_call");
    assert.match(payload.error.userMessage, /无效 tool-call arguments JSON/u);
    assert.match(payload.error.userMessage, /AgentRun\/provider/u);
    assert.match(payload.error.userMessage, /不是 HWPOD/u);
    assert.equal(payload.finalResponse.status, "failed");
    assert.match(payload.finalResponse.text, /invalid function arguments json string/u);
    assert.equal(payload.traceSummary.terminalStatus, "failed");
    assert.match(payload.traceSummary.finalAssistantRow.textPreview, /invalid function arguments json string/u);
    assert.equal(payload.blocker?.category ?? payload.error.category, "provider_invalid_tool_call");
    assert.match(payload.blocker?.summary ?? payload.error.userMessage, /invalid function arguments json string/u);
    assert.equal(payload.session.status, "failed");
    assert.equal(payload.session.lifecycle.requiresNewSession, false);
    assert.equal(payload.sessionReuse.threadId, "thread_invalid_tool");
    assert.equal(payload.sessionReuse.status, "failed-resumable");
    assert.equal(payload.agentRun.reuseEligible, true);
    assert.equal(payload.reuseEligible, true);
    const serializedPayload = JSON.stringify(payload);
    assert.equal(serializedPayload.includes("repo-owned-codex"), false);
    assert.equal(serializedPayload.includes("codex-app-server-stdio"), false);
    assert.equal(serializedPayload.includes("\"provider\":\"codex-stdio\""), 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 AgentRun adapter marks evicted session storage as non-reusable", async () => {
  const agentRunServer = createHttpServer(async (request, response) => {
    const url = new URL(request.url || "/", "http://127.0.0.1");
    const chunks = [];
    for await (const chunk of request) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
    const body = chunks.length ? JSON.parse(Buffer.concat(chunks).toString("utf8")) : null;
    const send = (data) => {
      response.writeHead(200, { "content-type": "application/json" });
      response.end(`${JSON.stringify({ ok: true, data, traceId: "trc_fake_agentrun_evicted" })}\n`);
    };
    if (request.method === "POST" && url.pathname === "/api/v1/runs") {
      return send({ id: "run_evicted", status: "pending", backendProfile: "deepseek", sessionRef: body.sessionRef, resourceBundleRef: body.resourceBundleRef });
    }
    if (request.method === "POST" && url.pathname === "/api/v1/runs/run_evicted/commands") {
      return send({ id: "cmd_evicted", runId: "run_evicted", state: "queued" });
    }
    if (request.method === "POST" && url.pathname === "/api/v1/runs/run_evicted/runner-jobs") {
      return send({
        action: "create-kubernetes-job",
        runId: "run_evicted",
        commandId: "cmd_evicted",
        attemptId: "attempt_evicted",
        runnerId: "runner_evicted",
        namespace: "agentrun-v01",
        jobName: "agentrun-v01-runner-evicted",
        runner: { attemptId: "attempt_evicted", runnerId: "runner_evicted" }
      });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_evicted/events") {
      return send({ items: [
        { id: "evt_evicted", runId: "run_evicted", seq: 1, type: "error", payload: { commandId: "cmd_evicted", failureKind: "session-store-evicted", message: "codex app-server thread/resume reported no rollout found for PVC-backed session; session storage was likely evicted" }, createdAt: "2026-06-02T00:00:00.000Z" },
        { id: "evt_evicted_terminal", runId: "run_evicted", seq: 2, type: "terminal_status", payload: { commandId: "cmd_evicted", terminalStatus: "failed", failureKind: "session-store-evicted" }, createdAt: "2026-06-02T00:00:01.000Z" }
      ] });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_evicted/commands") {
      return send({ items: [{ id: "cmd_evicted", runId: "run_evicted", state: "failed", terminalStatus: "failed", idempotencyKey: "trc_server-test-agentrun-evicted", payload: { traceId: "trc_server-test-agentrun-evicted" } }] });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_evicted/commands/cmd_evicted/result") {
      return send({
        runId: "run_evicted",
        commandId: "cmd_evicted",
        attemptId: "attempt_evicted",
        runnerId: "runner_evicted",
        jobName: "agentrun-v01-runner-evicted",
        namespace: "agentrun-v01",
        status: "failed",
        runStatus: "failed",
        commandState: "failed",
        terminalStatus: "failed",
        failureKind: "session-store-evicted",
        failureMessage: "codex app-server thread/resume reported no rollout found for PVC-backed session; session storage was likely evicted",
        completed: false,
        lastSeq: 2,
        eventCount: 2,
        sessionRef: { sessionId: "ses_agentrun_evicted", conversationId: "cnv_evicted", threadId: "thread_evicted" }
      });
    }
    response.writeHead(404, { "content-type": "application/json" });
    response.end(`${JSON.stringify({ ok: false, failureKind: "schema-invalid", message: `unexpected ${request.method} ${url.pathname}`, traceId: "trc_fake_agentrun_evicted" })}\n`);
  });
  await new Promise((resolve) => agentRunServer.listen(0, "127.0.0.1", resolve));
  const agentRunPort = agentRunServer.address().port;
  const ownerSessions = new Map([["ses_server-test-evicted", testAgentSessionRecord({
    sessionId: "ses_server-test-evicted",
    conversationId: "cnv_evicted",
    threadId: "thread_evicted",
    status: "idle"
  })]]);
  const server = createCloudApiServer({
    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_CODE_AGENT_AGENTRUN_SOURCE_COMMIT: "0123456789abcdef0123456789abcdef01234567",
      HWLAB_CODE_AGENT_DEFAULT_PROVIDER_PROFILE: "deepseek",
      HWLAB_ENVIRONMENT: "v02",
      HWLAB_GITOPS_PROFILE: "v02"
    },
    accessController: {
      required: false,
      async authenticate() {
        return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION };
      },
      async recordAgentSessionOwner(input) {
        const record = testAgentSessionRecord(input);
        ownerSessions.set(record.id, record);
        return record;
      },
      async getAgentSession(sessionId) {
        return ownerSessions.get(sessionId) ?? null;
      }
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const traceId = "trc_server-test-agentrun-evicted";
    const submit = await fetch(`http://127.0.0.1:${port}/v1/agent/chat`, {
      method: "POST",
      headers: { "content-type": "application/json", "x-trace-id": traceId, cookie: "hwlab_session=test-stub-session" },
      body: JSON.stringify({ conversationId: "cnv_evicted", sessionId: "ses_server-test-evicted", threadId: "thread_evicted", message: "resume evicted session" })
    });
    assert.equal(submit.status, 202);
    const payload = await pollAgentResult(port, traceId);
    validateCodeAgentChatSchema(payload);
    assert.equal(payload.status, "failed");
    assert.equal(payload.error.code, "session-store-evicted");
    assert.equal(payload.session.status, "thread-resume-failed");
    assert.equal(payload.session.lifecycle.requiresNewSession, true);
    assert.equal(payload.sessionReuse.threadId, "thread_evicted");
    assert.equal(payload.sessionReuse.status, "thread-resume-failed");
    assert.equal(payload.agentRun.reuseEligible, false);
    assert.equal(payload.reuseEligible, false);
    assert.equal(ownerSessions.get("ses_server-test-evicted")?.status, "thread-resume-failed");
  } 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 AgentRun adapter maps minimax-m3 provider profile to AgentRun backend", async () => {
  const calls = [];
  const agentRunServer = createHttpServer(async (request, response) => {
    const url = new URL(request.url || "/", "http://127.0.0.1");
    const chunks = [];
    for await (const chunk of request) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
    const body = chunks.length ? JSON.parse(Buffer.concat(chunks).toString("utf8")) : null;
    calls.push({ method: request.method, path: url.pathname, body });
    const send = (data) => {
      response.writeHead(200, { "content-type": "application/json" });
      response.end(`${JSON.stringify({ ok: true, data, traceId: "trc_fake_agentrun_minimax_m3" })}\n`);
    };
    if (request.method === "POST" && url.pathname === "/api/v1/runs") {
      assert.equal(body.backendProfile, "minimax-m3");
      assert.equal(body.sessionRef.sessionId, "ses_agentrun_minimax_m3_server_test_minimax_m3");
      assert.equal(body.sessionRef.metadata.hwlabSessionId, "ses_server-test-minimax-m3");
      assert.equal(body.sessionRef.metadata.agentRunSessionProfile, "minimax-m3");
      assert.equal(body.sessionRef.metadata.agentRunSessionPolicy, "backend-profile-scoped");
      assert.equal(body.executionPolicy.secretScope.providerCredentials[0].profile, "minimax-m3");
      assert.equal(body.executionPolicy.secretScope.providerCredentials[0].secretRef.name, "agentrun-v01-provider-minimax-m3");
      assert.equal(body.executionPolicy.secretScope.providerCredentials[0].secretRef.namespace, "agentrun-v01");
      return send({ id: "run_hwlab_minimax_m3", status: "pending", backendProfile: "minimax-m3", sessionRef: body.sessionRef, resourceBundleRef: body.resourceBundleRef });
    }
    if (request.method === "POST" && url.pathname === "/api/v1/runs/run_hwlab_minimax_m3/commands") {
      assert.equal(body.payload.providerProfile, "minimax-m3");
      assert.equal(body.payload.sessionId, "ses_agentrun_minimax_m3_server_test_minimax_m3");
      assert.equal(body.payload.hwlabSessionId, "ses_server-test-minimax-m3");
      assert.match(body.payload.prompt, /MiniMax-M3/u);
      return send({ id: "cmd_hwlab_minimax_m3", runId: "run_hwlab_minimax_m3", state: "pending", type: "turn", seq: 1 });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_hwlab_minimax_m3/commands") {
      return send({ items: [
        { id: "cmd_hwlab_minimax_m3", runId: "run_hwlab_minimax_m3", state: "completed", type: "turn", seq: 1, idempotencyKey: "trc_server-test-agentrun-minimax-m3", payload: { traceId: "trc_server-test-agentrun-minimax-m3", conversationId: "cnv_server-test-minimax-m3", hwlabSessionId: "ses_server-test-minimax-m3", threadId: null, providerProfile: "minimax-m3" } }
      ] });
    }
    if (request.method === "POST" && url.pathname === "/api/v1/runs/run_hwlab_minimax_m3/runner-jobs") {
      assert.equal(body.commandId, "cmd_hwlab_minimax_m3");
      return send({
        action: "create-kubernetes-job",
        runId: "run_hwlab_minimax_m3",
        commandId: "cmd_hwlab_minimax_m3",
        attemptId: "attempt_hwlab_minimax_m3",
        runnerId: "runner_hwlab_minimax_m3",
        namespace: "agentrun-v01",
        jobName: "agentrun-v01-runner-hwlab-minimax-m3",
        jobIdentity: { namespace: "agentrun-v01", name: "agentrun-v01-runner-hwlab-minimax-m3" },
        runner: { attemptId: "attempt_hwlab_minimax_m3", runnerId: "runner_hwlab_minimax_m3" }
      });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_hwlab_minimax_m3/events") {
      return send({ items: [
        { id: "evt_minimax_1", runId: "run_hwlab_minimax_m3", seq: 1, type: "backend_status", payload: { phase: "runner-job-created", commandId: "cmd_hwlab_minimax_m3", attemptId: "attempt_hwlab_minimax_m3", jobName: "agentrun-v01-runner-hwlab-minimax-m3", namespace: "agentrun-v01" }, createdAt: "2026-06-02T00:00:00.000Z" },
        { id: "evt_minimax_2", runId: "run_hwlab_minimax_m3", seq: 2, type: "assistant_message", payload: { commandId: "cmd_hwlab_minimax_m3", text: "AGENTRUN_MINIMAX_M3_OK" }, createdAt: "2026-06-02T00:00:01.000Z" },
        { id: "evt_minimax_3", runId: "run_hwlab_minimax_m3", seq: 3, type: "terminal_status", payload: { commandId: "cmd_hwlab_minimax_m3", terminalStatus: "completed" }, createdAt: "2026-06-02T00:00:02.000Z" }
      ] });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_hwlab_minimax_m3/commands/cmd_hwlab_minimax_m3/result") {
      return send({
        runId: "run_hwlab_minimax_m3",
        commandId: "cmd_hwlab_minimax_m3",
        attemptId: "attempt_hwlab_minimax_m3",
        runnerId: "runner_hwlab_minimax_m3",
        jobName: "agentrun-v01-runner-hwlab-minimax-m3",
        namespace: "agentrun-v01",
        status: "completed",
        runStatus: "completed",
        commandState: "completed",
        terminalStatus: "completed",
        completed: true,
        reply: "AGENTRUN_MINIMAX_M3_OK",
        lastSeq: 3,
        eventCount: 3,
        sessionRef: { sessionId: "ses_agentrun_minimax_m3_server_test_minimax_m3", conversationId: "cnv_server-test-minimax-m3", threadId: null }
      });
    }
    response.writeHead(404, { "content-type": "application/json" });
    response.end(`${JSON.stringify({ ok: false, failureKind: "schema-invalid", message: `unexpected ${request.method} ${url.pathname}`, traceId: "trc_fake_agentrun_minimax_m3" })}\n`);
  });
  await new Promise((resolve) => agentRunServer.listen(0, "127.0.0.1", resolve));

  const agentRunPort = agentRunServer.address().port;
  const minimaxOwnerSessions = new Map([["ses_server-test-minimax-m3", testAgentSessionRecord({
    sessionId: "ses_server-test-minimax-m3",
    conversationId: "cnv_server-test-minimax-m3",
    status: "idle"
  })]]);
  const server = createCloudApiServer({
    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_CODE_AGENT_AGENTRUN_SOURCE_COMMIT: "0123456789abcdef0123456789abcdef01234567",
      HWLAB_CODE_AGENT_DEFAULT_PROVIDER_PROFILE: "deepseek",
      HWLAB_ENVIRONMENT: "v02",
      HWLAB_GITOPS_PROFILE: "v02"
    },
    accessController: {
      required: false,
      async authenticate() {
        return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION };
      },
      async recordAgentSessionOwner(input) {
        const record = testAgentSessionRecord(input);
        minimaxOwnerSessions.set(record.id, record);
        return record;
      },
      async getAgentSession(sessionId) {
        return minimaxOwnerSessions.get(sessionId) ?? null;
      }
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const traceId = "trc_server-test-agentrun-minimax-m3";
    const submit = await fetch(`http://127.0.0.1:${port}/v1/agent/chat`, {
      method: "POST",
      headers: { "content-type": "application/json", "x-trace-id": traceId, cookie: "hwlab_session=test-stub-session" },
      body: JSON.stringify({
        conversationId: "cnv_server-test-minimax-m3",
        sessionId: "ses_server-test-minimax-m3",
        providerProfile: "minimax-m3",
        message: "MiniMax-M3 AgentRun adapter smoke"
      })
    });
    assert.equal(submit.status, 202);
    const accepted = await submit.json();
    assert.equal(accepted.shortConnection, true);

    const payload = await pollAgentResult(port, traceId);
    validateCodeAgentChatSchema(payload);
    assert.equal(payload.status, "completed");
    assert.equal(payload.provider, "minimax-m3");
    assert.equal(payload.backend, "agentrun-v01/minimax-m3");
    assert.equal(payload.infrastructureBackend, "agentrun-v01/minimax-m3");
    assert.equal(payload.runner.kind, "agentrun-v01-shared-runner");
    assert.equal(payload.runner.provider, "minimax-m3");
    assert.equal(payload.runner.codexStdio, false);
    assert.equal(payload.agentRun.backendProfile, "minimax-m3");
    assert.equal(payload.sessionId, "ses_server-test-minimax-m3");
    assert.equal(payload.agentRun.sessionId, "ses_agentrun_minimax_m3_server_test_minimax_m3");
    assert.equal(payload.providerTrace.backendProfile, "minimax-m3");
    assert.equal(payload.agentRun.jobName, "agentrun-v01-runner-hwlab-minimax-m3");
    assert.equal(payload.reply.content, "AGENTRUN_MINIMAX_M3_OK");
    assert.equal(calls.filter((call) => call.method === "POST" && call.path === "/api/v1/runs").length, 1);
  } 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 AgentRun adapter scopes AgentRun sessions by backend profile", async () => {
  const calls = [];
  const hwlabSessionId = "ses_server-test-profile-switch";
  const minimaxSessionId = "ses_agentrun_minimax_m3_server_test_profile_switch";
  const ownerSessions = new Map([[hwlabSessionId, testAgentSessionRecord({
    sessionId: hwlabSessionId,
    conversationId: "cnv_server-test-profile-switch",
    threadId: "019e8078-db67-7750-a5d9-1a99f3abd445",
    traceId: "trc_existing_deepseek",
    status: "active",
    session: {
      agentRun: {
        adapter: "agentrun-v01",
        backendProfile: "deepseek",
        runId: "run_existing_deepseek",
        commandId: "cmd_existing_deepseek",
        jobName: "agentrun-v01-runner-existing-deepseek",
        namespace: "agentrun-v01",
        sessionId: "ses_agentrun_deepseek_server_test_profile_switch",
        reuseEligible: true,
        managerUrl: "http://127.0.0.1:1",
        status: "runner-job-created"
      }
    }
  })]]);

  const agentRunServer = createHttpServer(async (request, response) => {
    const url = new URL(request.url || "/", "http://127.0.0.1");
    const chunks = [];
    for await (const chunk of request) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
    const body = chunks.length ? JSON.parse(Buffer.concat(chunks).toString("utf8")) : null;
    calls.push({ method: request.method, path: url.pathname, body });
    const send = (data) => {
      response.writeHead(200, { "content-type": "application/json" });
      response.end(`${JSON.stringify({ ok: true, data, traceId: "trc_fake_profile_switch" })}\n`);
    };
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_existing_deepseek") {
      response.writeHead(500, { "content-type": "application/json" });
      response.end(`${JSON.stringify({ ok: false, failureKind: "unexpected-reuse", message: "deepseek run must not be reused for minimax-m3" })}\n`);
      return;
    }
    if (request.method === "POST" && url.pathname === "/api/v1/runs") {
      assert.equal(body.backendProfile, "minimax-m3");
      assert.equal(body.sessionRef.sessionId, minimaxSessionId);
      assert.equal(body.sessionRef.metadata.hwlabSessionId, hwlabSessionId);
      assert.equal(body.sessionRef.metadata.agentRunSessionProfile, "minimax-m3");
      return send({ id: "run_hwlab_profile_switch_m3", status: "pending", backendProfile: "minimax-m3", sessionRef: body.sessionRef, resourceBundleRef: body.resourceBundleRef });
    }
    if (request.method === "POST" && url.pathname === "/api/v1/runs/run_hwlab_profile_switch_m3/commands") {
      assert.equal(body.payload.providerProfile, "minimax-m3");
      assert.equal(body.payload.sessionId, minimaxSessionId);
      assert.equal(body.payload.hwlabSessionId, hwlabSessionId);
      return send({ id: "cmd_hwlab_profile_switch_m3", runId: "run_hwlab_profile_switch_m3", state: "pending", type: "turn", seq: 1 });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_hwlab_profile_switch_m3/commands") {
      return send({ items: [
        { id: "cmd_hwlab_profile_switch_m3", runId: "run_hwlab_profile_switch_m3", state: "completed", type: "turn", seq: 1, idempotencyKey: "trc_server-test-agentrun-profile-switch", payload: { traceId: "trc_server-test-agentrun-profile-switch", conversationId: "cnv_server-test-profile-switch", hwlabSessionId, threadId: "019e8078-db67-7750-a5d9-1a99f3abd445", providerProfile: "minimax-m3" } }
      ] });
    }
    if (request.method === "POST" && url.pathname === "/api/v1/runs/run_hwlab_profile_switch_m3/runner-jobs") {
      assert.equal(body.commandId, "cmd_hwlab_profile_switch_m3");
      return send({
        action: "create-kubernetes-job",
        runId: "run_hwlab_profile_switch_m3",
        commandId: "cmd_hwlab_profile_switch_m3",
        attemptId: "attempt_hwlab_profile_switch_m3",
        runnerId: "runner_hwlab_profile_switch_m3",
        namespace: "agentrun-v01",
        jobName: "agentrun-v01-runner-profile-switch-m3",
        jobIdentity: { namespace: "agentrun-v01", name: "agentrun-v01-runner-profile-switch-m3" },
        runner: { attemptId: "attempt_hwlab_profile_switch_m3", runnerId: "runner_hwlab_profile_switch_m3" }
      });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_hwlab_profile_switch_m3/events") {
      return send({ items: [
        { id: "evt_profile_switch_1", runId: "run_hwlab_profile_switch_m3", seq: 1, type: "backend_status", payload: { phase: "runner-job-created", commandId: "cmd_hwlab_profile_switch_m3", attemptId: "attempt_hwlab_profile_switch_m3", jobName: "agentrun-v01-runner-profile-switch-m3", namespace: "agentrun-v01" }, createdAt: "2026-06-02T00:00:00.000Z" },
        { id: "evt_profile_switch_2", runId: "run_hwlab_profile_switch_m3", seq: 2, type: "assistant_message", payload: { commandId: "cmd_hwlab_profile_switch_m3", text: "AGENTRUN_HWLAB_MINIMAX_M3_OK" }, createdAt: "2026-06-02T00:00:01.000Z" },
        { id: "evt_profile_switch_3", runId: "run_hwlab_profile_switch_m3", seq: 3, type: "terminal_status", payload: { commandId: "cmd_hwlab_profile_switch_m3", terminalStatus: "completed" }, createdAt: "2026-06-02T00:00:02.000Z" }
      ] });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_hwlab_profile_switch_m3/commands/cmd_hwlab_profile_switch_m3/result") {
      return send({
        runId: "run_hwlab_profile_switch_m3",
        commandId: "cmd_hwlab_profile_switch_m3",
        attemptId: "attempt_hwlab_profile_switch_m3",
        runnerId: "runner_hwlab_profile_switch_m3",
        jobName: "agentrun-v01-runner-profile-switch-m3",
        namespace: "agentrun-v01",
        status: "completed",
        runStatus: "completed",
        commandState: "completed",
        terminalStatus: "completed",
        completed: true,
        reply: "AGENTRUN_HWLAB_MINIMAX_M3_OK",
        lastSeq: 3,
        eventCount: 3,
        sessionRef: { sessionId: minimaxSessionId, conversationId: "cnv_server-test-profile-switch", threadId: "019e8078-db67-7750-a5d9-1a99f3abd445" }
      });
    }
    response.writeHead(404, { "content-type": "application/json" });
    response.end(`${JSON.stringify({ ok: false, failureKind: "schema-invalid", message: `unexpected ${request.method} ${url.pathname}`, traceId: "trc_fake_profile_switch" })}\n`);
  });
  await new Promise((resolve) => agentRunServer.listen(0, "127.0.0.1", resolve));

  const agentRunPort = agentRunServer.address().port;
  const server = createCloudApiServer({
    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_CODE_AGENT_AGENTRUN_SOURCE_COMMIT: "0123456789abcdef0123456789abcdef01234567",
      HWLAB_CODE_AGENT_DEFAULT_PROVIDER_PROFILE: "deepseek",
      HWLAB_ENVIRONMENT: "v02",
      HWLAB_GITOPS_PROFILE: "v02"
    },
    accessController: {
      required: false,
      async authenticate() {
        return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION };
      },
      async recordAgentSessionOwner(input) {
        const record = testAgentSessionRecord(input);
        ownerSessions.set(record.id, record);
        return record;
      },
      async getAgentSession(sessionId) {
        return ownerSessions.get(sessionId) ?? null;
      }
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const traceId = "trc_server-test-agentrun-profile-switch";
    const submit = await fetch(`http://127.0.0.1:${port}/v1/agent/chat`, {
      method: "POST",
      headers: { "content-type": "application/json", "x-trace-id": traceId, cookie: "hwlab_session=test-stub-session" },
      body: JSON.stringify({
        conversationId: "cnv_server-test-profile-switch",
        sessionId: hwlabSessionId,
        ownerUserId: "usr_agent_owner",
        ownerRole: "user",
        threadId: "019e8078-db67-7750-a5d9-1a99f3abd445",
        providerProfile: "minimax-m3",
        message: "Switch this HWLAB session to MiniMax-M3 through AgentRun"
      })
    });
    assert.equal(submit.status, 202);

    const payload = await pollAgentResult(port, traceId);
    validateCodeAgentChatSchema(payload);
    assert.equal(payload.status, "completed");
    assert.equal(payload.sessionId, hwlabSessionId);
    assert.equal(payload.infrastructureBackend, "agentrun-v01/minimax-m3");
    assert.equal(payload.agentRun.backendProfile, "minimax-m3");
    assert.equal(payload.agentRun.runId, "run_hwlab_profile_switch_m3");
    assert.equal(payload.agentRun.sessionId, minimaxSessionId);
    assert.equal(payload.reply.content, "AGENTRUN_HWLAB_MINIMAX_M3_OK");
    assert.equal(calls.some((call) => call.method === "GET" && call.path === "/api/v1/runs/run_existing_deepseek"), false);
    assert.equal(calls.filter((call) => call.method === "POST" && call.path === "/api/v1/runs").length, 1);
    const stored = ownerSessions.get(hwlabSessionId);
    assert.equal(stored.session.agentRun.backendProfile, "minimax-m3");
    assert.equal(stored.session.agentRun.sessionId, minimaxSessionId);
  } 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 AgentRun adapter rejects non-internal manager URLs by default", async () => {
  const server = createCloudApiServer({
    env: {
      HWLAB_CODE_AGENT_ADAPTER: "agentrun-v01",
      HWLAB_CODE_AGENT_AGENTRUN_PROVIDER_ID: "D601",
      AGENTRUN_MGR_URL: "http://74.48.78.17:8080"
    }
  });
  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-agentrun-public-url"
    });
    const response = await fetch(`http://127.0.0.1:${port}/v1/agent/chat`, {
      method: "POST",
      headers: { "content-type": "application/json", "x-trace-id": "trc_server-test-agentrun-public-url", cookie: manualSession.cookie },
      body: JSON.stringify({ conversationId: manualSession.conversationId, sessionId: manualSession.sessionId, message: "must reject public manager url" })
    });
    assert.equal(response.status, 202);
    const body = await response.json();
    assert.equal(body.accepted, true);
    const result = await pollAgentResult(port, "trc_server-test-agentrun-public-url");
    assert.equal(result.status, "failed");
    assert.match(JSON.stringify(result), /internal k3s Service DNS/u);
  } finally {
    await new Promise((resolve, reject) => server.close((error) => (error ? reject(error) : resolve())));
  }
});

test("cloud api /v1/agent/chat records authenticated owner on agent session", async () => {
  const workspace = await mkdtemp(path.join(os.tmpdir(), "hwlab-agent-owner-"));
  const codexHome = await mkdtemp(path.join(os.tmpdir(), "hwlab-agent-owner-codex-home-"));
  const ownerRecords = [];
  const ownerSessions = new Map([["ses_server-test-owner", testAgentSessionRecord({
    sessionId: "ses_server-test-owner",
    conversationId: "cnv_server-test-owner",
    status: "idle"
  })]]);
  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",
      OPENAI_API_KEY: "test-openai-key-material",
      HWLAB_CODE_AGENT_OPENAI_BASE_URL: "http://127.0.0.1:65535/v1/responses"
    },
    accessController: {
      required: true,
      async authenticate() {
        return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION };
      },
      async recordAgentSessionOwner(input) {
        const record = testAgentSessionRecord(input);
        ownerRecords.push(input);
        ownerSessions.set(record.id, record);
        return record;
      },
      async getAgentSession(sessionId) {
        return ownerSessions.get(sessionId) ?? null;
      }
    },
    codexStdioManager: {
      describe() { return { ...codexStdioReadyFixture({ workspace, codexHome }), sandbox: "danger-full-access" }; },
      async probe() { return { ...codexStdioReadyFixture({ workspace, codexHome }), sandbox: "danger-full-access" }; },
      async chat(params = {}) {
        return {
          ...codexStdioChatFixture({ workspace, codexHome, params }),
          sandbox: "danger-full-access"
        };
      },
      cancel() {},
      reapIdle() {}
    }
  });
  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-owner",
      sessionId: "ses_server-test-owner",
      traceId: "trc_server-test-owner",
      message: "owner binding smoke"
    });
    validateCodeAgentChatSchema(payload);
    assert.equal(payload.ownerUserId, "usr_agent_owner");
    assert.equal(ownerRecords.length, 2);
    assert.equal(ownerRecords[0].status, "running");
    const terminalOwnerRecord = ownerRecords.at(-1);
    assert.equal(terminalOwnerRecord.ownerUserId, "usr_agent_owner");
    assert.equal(terminalOwnerRecord.sessionId, "ses_server_stdio_pwd");
    assert.equal(terminalOwnerRecord.conversationId, "cnv_server-test-owner");
    assert.equal(terminalOwnerRecord.traceId, "trc_server-test-owner");
    assert.equal(terminalOwnerRecord.status, "completed");
    assert.equal(terminalOwnerRecord.session.messageCount, 2);
    assert.equal(terminalOwnerRecord.session.messages.length, 2);
    assert.equal(terminalOwnerRecord.session.messages[0].role, "user");
    assert.equal(terminalOwnerRecord.session.messages[0].text, "owner binding smoke");
    assert.equal(terminalOwnerRecord.session.messages[0].status, "sent");
    assert.equal(terminalOwnerRecord.session.messages[1].role, "agent");
    assert.equal(terminalOwnerRecord.session.messages[1].status, "completed");
    assert.equal(terminalOwnerRecord.session.messages[1].traceId, "trc_server-test-owner");
    assert.equal(terminalOwnerRecord.session.firstUserMessagePreview, "owner binding smoke");
    assert.equal(terminalOwnerRecord.session.valuesRedacted, true);
    assert.equal(JSON.stringify(ownerRecords).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(codexHome, { recursive: true, force: true });
  }
});

test("cloud api /v1/agent/chat/inspect maps conversation session and thread details to trace evidence", async () => {
  const workspace = await mkdtemp(path.join(os.tmpdir(), "hwlab-agent-inspect-"));
  const codexHome = await mkdtemp(path.join(os.tmpdir(), "hwlab-agent-inspect-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",
      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",
          recentSessions: [{
            sessionId: "ses_server_stdio_pwd",
            conversationId: "cnv_server-test-inspect",
            threadId: "019e6c72-2373-75e3-9856-eff286db7163",
            status: "idle",
            currentTraceId: null,
            lastTraceId: "trc_server-test-inspect",
            workspace,
            sandbox: "danger-full-access",
            secretMaterialStored: false,
            valuesRedacted: true
          }]
        };
      },
      async probe() {
        return {
          ...codexStdioReadyFixture({ workspace, codexHome }),
          sandbox: "danger-full-access"
        };
      },
      async chat(params = {}) {
        const base = codexStdioChatFixture({ workspace, codexHome, params });
        return {
          ...base,
          sandbox: "danger-full-access",
          session: {
            ...base.session,
            threadId: "019e6c72-2373-75e3-9856-eff286db7163",
            sandbox: "danger-full-access"
          },
          sessionReuse: {
            ...base.sessionReuse,
            threadId: "019e6c72-2373-75e3-9856-eff286db7163"
          }
        };
      },
      get(sessionId) {
        if (sessionId !== "ses_server_stdio_pwd") return null;
        return {
          sessionId,
          conversationId: "cnv_server-test-inspect",
          threadId: "019e6c72-2373-75e3-9856-eff286db7163",
          status: "idle",
          lastTraceId: "trc_server-test-inspect",
          workspace,
          sandbox: "danger-full-access",
          secretMaterialStored: false,
          valuesRedacted: true
        };
      },
      cancel() {},
      reapIdle() {}
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    const { port } = server.address();
    const traceId = "trc_server-test-inspect";
    const manualSession = await createManualAgentSession(port, {
      conversationId: "cnv_server-test-inspect"
    });
    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: "inspect mapping smoke"
      })
    });
    assert.equal(submit.status, 202);
    const payload = await pollAgentResult(port, traceId);
    assert.equal(payload.status, "completed");

    const inspect = await fetch(`http://127.0.0.1:${port}/v1/agent/chat/inspect?conversationId=cnv_server-test-inspect&sessionId=${manualSession.sessionId}&threadId=019e6c72-2373-75e3-9856-eff286db7163`);
    assert.equal(inspect.status, 200);
    const body = await inspect.json();
    assert.equal(body.ok, true);
    assert.equal(body.status, "found");
    assert.equal(body.latestTraceId, traceId);
    assert.equal(body.traceUrl, `/v1/agent/traces/${traceId}`);
    assert.equal(body.resultUrl, `/v1/agent/chat/result/${traceId}`);
    assert.equal(body.query.sessionId, manualSession.sessionId);
    assert.equal(body.query.threadId, "019e6c72-2373-75e3-9856-eff286db7163");
    assert.equal(body.session.sessionId, "ses_server_stdio_pwd");
    assert.equal(body.session.threadId, "019e6c72-2373-75e3-9856-eff286db7163");
    assert.equal(body.conversationFacts.conversationId, "cnv_server-test-inspect");
    assert.equal(body.runnerTrace.traceId, traceId);
    assert.equal(body.valuesRedacted, true);
    assert.equal(body.secretMaterialStored, false);
    assert.equal(JSON.stringify(body).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(codexHome, { recursive: true, force: true });
  }
});

test("cloud api /v1/agent/chat/inspect returns not_found for empty conversation facts", async () => {
  const server = createCloudApiServer();
  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/inspect?conversationId=cnv_server-test-inspect-missing&sessionId=ses_server_test_missing&threadId=019e6c72-2373-75e3-9856-eff286db7163&traceId=trc_server_test_missing`);
    assert.equal(response.status, 404);
    const body = await response.json();
    assert.equal(body.ok, false);
    assert.equal(body.status, "not_found");
    assert.equal(body.latestTraceId, null);
    assert.deepEqual(body.traceIds, []);
    assert.equal(body.traceUrl, null);
    assert.equal(body.resultUrl, null);
    assert.equal(body.conversationFacts.turnCount, 0);
  } finally {
    await new Promise((resolve, reject) => {
      server.close((error) => (error ? reject(error) : resolve()));
    });
  }
});

test("cloud api trace reports expired projection without AgentRun read-through when live trace store has expired (#1519)", async () => {
  const ownerSessions = new Map();
  const agentRunCalls = [];
  const commandFinalText = "历史 trace 已过期，但 final response 来自 AgentRun command result。";
  ownerSessions.set("ses_issue842_expired", testAgentSessionRecord({
    sessionId: "ses_issue842_expired",
    projectId: "prj_v02_code_agent",
    conversationId: "cnv_issue842_expired",
    threadId: "thread-issue-842-expired",
    traceId: "trc_issue842_expired",
    status: "active",
    session: {
      finalResponse: {
        text: "旧 session snapshot final 不应作为历史 trace 权威。",
        textChars: 30,
        role: "assistant",
        status: "completed",
        traceId: "trc_issue842_expired",
        source: "code-agent-result",
        valuesPrinted: false
      },
      traceSummary: {
        traceId: "trc_issue842_expired",
        source: "stale-derived-session-evidence",
        sourceEventCount: 26,
        terminalStatus: "completed",
        noiseEventCount: 4,
        omittedNoiseCount: 4,
        valuesPrinted: false
      },
      agentRun: {
        adapter: "agentrun-v01",
        runId: "run_issue842_expired",
        commandId: "cmd_issue842_expired",
        runnerId: "runner_issue842_expired",
        jobName: "agentrun-v01-runner-issue842-expired",
        namespace: "agentrun-v01",
        terminalStatus: "completed",
        valuesPrinted: false
      },
      valuesRedacted: true
    }
  }));
  const agentRunServer = createHttpServer(async (request, response) => {
    const url = new URL(request.url || "/", "http://127.0.0.1");
    agentRunCalls.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_issue842_expired" })}\n`);
    };
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_issue842_expired/commands") {
      return send({ items: [
        { id: "cmd_issue842_expired", runId: "run_issue842_expired", state: "completed", type: "turn", seq: 1, idempotencyKey: "trc_issue842_expired", payload: { traceId: "trc_issue842_expired", conversationId: "cnv_issue842_expired", hwlabSessionId: "ses_issue842_expired", threadId: "thread-issue-842-expired", providerProfile: "deepseek" } }
      ] });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_issue842_expired/events") {
      return send({ items: [] });
    }
    if (request.method === "GET" && url.pathname === "/api/v1/runs/run_issue842_expired/commands/cmd_issue842_expired/result") {
      return send({
        runId: "run_issue842_expired",
        commandId: "cmd_issue842_expired",
        attemptId: "attempt_issue842_expired",
        runnerId: "runner_issue842_expired",
        jobName: "agentrun-v01-runner-issue842-expired",
        namespace: "agentrun-v01",
        status: "completed",
        runStatus: "completed",
        commandState: "completed",
        terminalStatus: "completed",
        completed: true,
        reply: commandFinalText,
        lastSeq: 26,
        eventCount: 26,
        sessionRef: { sessionId: "ses_agentrun_issue842_expired", conversationId: "cnv_issue842_expired", threadId: "thread-issue-842-expired" }
      });
    }
    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 traceStore = createCodeAgentTraceStore();
  const server = createCloudApiServer({
    traceStore,
    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) ?? null;
      }
    }
  });
  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/trc_issue842_expired`, {
      headers: { cookie: "hwlab_session=test-stub-session" }
    });
    assert.equal(response.status, 200);
    const body = await response.json();
    assert.equal(body.ok, false);
    assert.equal(body.status, "missing");
    assert.equal(body.traceStatus, "missing");
    assert.equal(body.eventCount, 0);
    assert.equal(body.projectionStatus, "unknown");
    assert.equal(body.retention.liveTraceStore, "missing");
    assert.equal(JSON.stringify(body).includes("旧 session snapshot final"), false);
    assert.deepEqual(agentRunCalls, []);
    assert.equal(JSON.stringify(body).includes("password"), 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 trace does not replay an earlier AgentRun command from GET after same-run lastSeq advances (#1519)", async () => {
  const calls = [];
  const firstTraceId = "trc_issue955_first_trace";
  const codeAgentChatResults = new Map();
  const runId = "run_issue955_replay";
  const firstCommandId = "cmd_issue955_first";
  const secondCommandId = "cmd_issue955_second";
  const firstFinalText = "目前只有一个 HWPOD 可用：\n\n- d601-f103-v2 (board: D601-F103-V2 / STM32F103)\n\nAPI 返回 count=1, availableCount=1。";
  const firstEvents = [
    { id: "evt_issue955_first_setup", runId, seq: 1, type: "backend_status", payload: { phase: "runner-job-created", commandId: firstCommandId, jobName: "agentrun-v01-runner-issue955-first", namespace: "agentrun-v01" }, createdAt: "2026-06-06T01:43:25.000Z" },
    { id: "evt_issue955_first_tool", runId, seq: 18, 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,"ids":["d601-f103-v2"]}', commandId: firstCommandId }, createdAt: "2026-06-06T01:43:42.000Z" },
    { id: "evt_issue955_first_assistant", runId, seq: 27, type: "assistant_message", payload: { commandId: firstCommandId, itemId: "msg_item_0", text: firstFinalText }, createdAt: "2026-06-06T01:43:55.000Z" },
    { id: "evt_issue955_first_terminal", runId, seq: 35, type: "terminal_status", payload: { commandId: firstCommandId, terminalStatus: "completed" }, createdAt: "2026-06-06T01:43:56.000Z" }
  ];
  const secondEvents = [
    { id: "evt_issue955_second_setup", runId, seq: 47, type: "backend_status", payload: { phase: "runner-claim-waiting-for-stale-lease" }, createdAt: "2026-06-06T01:45:56.000Z" },
    { id: "evt_issue955_second_assistant", runId, seq: 58, type: "assistant_message", payload: { commandId: secondCommandId, itemId: "msg_item_0", text: "编译成功！来总结一下结果。" }, createdAt: "2026-06-06T01:46:24.000Z" },
    { id: "evt_issue955_second_terminal", runId, seq: 66, 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, afterSeq: url.searchParams.get("afterSeq") });
    const send = (data) => {
      response.writeHead(200, { "content-type": "application/json" });
      response.end(`${JSON.stringify({ ok: true, data, traceId: "trc_fake_issue955_replay" })}\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:56.000Z", payload: { traceId: firstTraceId, conversationId: "cnv_issue955_replay", hwlabSessionId: "ses_issue955_replay", threadId: "thread-issue955-replay", providerProfile: "deepseek" } },
        { id: secondCommandId, runId, state: "completed", idempotencyKey: "trc_issue955_second_trace", createdAt: "2026-06-06T01:46:11.000Z", updatedAt: "2026-06-06T01:46:28.000Z", payload: { traceId: "trc_issue955_second_trace", conversationId: "cnv_issue955_replay", hwlabSessionId: "ses_issue955_replay", threadId: "thread-issue955-replay", 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_replay", conversationId: "cnv_issue955_replay", threadId: "thread-issue955-replay" } });
    }
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/events`) {
      return send({ items: [...firstEvents, ...secondEvents] });
    }
    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;
  codeAgentChatResults.set(firstTraceId, {
    accepted: true,
    status: "completed",
    shortConnection: true,
    traceId: firstTraceId,
    conversationId: "cnv_issue955_replay",
    sessionId: "ses_issue955_replay",
    threadId: "thread-issue955-replay",
    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: firstTraceId, valuesPrinted: false },
    traceSummary: { traceId: firstTraceId, source: "code-agent-derived-session-evidence", sourceEventCount: 41, 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, lastSeq: 66, terminalStatus: "completed", valuesPrinted: false },
    valuesPrinted: false
  });
  const traceStore = createCodeAgentTraceStore();
  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/${firstTraceId}`, {
      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, firstTraceId);
    assert.equal(body.status, "expired");
    assert.equal(body.projectionStatus, "projecting");
    assert.deepEqual(calls, []);
    assert.equal(body.eventCount, 0);
    assert.deepEqual(body.events, []);
    assert.equal(body.finalResponse.text, firstFinalText);
    assert.match(text, /d601-f103-v2/u);
    assert.doesNotMatch(text, /编译成功/u);
  } 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 running trace reports current projection without AgentRun event refresh (#1519)", async () => {
  const calls = [];
  const traceId = "trc_issue1000_running_trace";
  const runId = "run_issue1000_running_trace";
  const commandId = "cmd_issue1000_running_trace";
  const codeAgentChatResults = new Map();
  const events = [
    { id: "evt_issue1000_created", runId, seq: 1, type: "backend_status", payload: { phase: "runner-job-created", commandId, jobName: "agentrun-v01-runner-issue1000", namespace: "agentrun-v01" }, createdAt: "2026-06-06T08:34:30.000Z" },
    { id: "evt_issue1000_turn", runId, seq: 2, type: "backend_status", payload: { phase: "turn/started", commandId }, createdAt: "2026-06-06T08:34:31.000Z" },
    { id: "evt_issue1000_tool", runId, seq: 3, type: "tool_call", payload: { method: "item/completed", type: "commandExecution", toolName: "commandExecution", itemId: "call_issue1000_hwpod", command: "hwpod list --available", status: "completed", exitCode: 0, outputSummary: "available=1", commandId }, createdAt: "2026-06-06T08:34:32.000Z" },
    { id: "evt_issue1000_output", runId, seq: 4, type: "assistant_message", payload: { commandId, itemId: "msg_issue1000_running", text: "正在查看 HWPOD。" }, createdAt: "2026-06-06T08:34:33.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_issue1000_running" })}\n`);
    };
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/events`) return send({ items: events });
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/commands/${commandId}/result`) {
      return send({ runId, commandId, status: "running", runStatus: "running", commandState: "running", terminalStatus: null, completed: false, reply: null, lastSeq: 3, eventCount: 3 });
    }
    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;
  codeAgentChatResults.set(traceId, {
    accepted: true,
    status: "running",
    shortConnection: true,
    traceId,
    conversationId: "cnv_issue1000_running_trace",
    sessionId: "ses_issue1000_running_trace",
    threadId: "thread-issue1000-running-trace",
    ownerUserId: TEST_AGENT_ACTOR.id,
    ownerRole: TEST_AGENT_ACTOR.role,
    agentRun: { adapter: "agentrun-v01", managerUrl: `http://127.0.0.1:${agentRunPort}`, runId, commandId, traceId, providerTrace: { traceId }, lastSeq: 0, status: "running", commandState: "running", 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/traces/${traceId}`, {
      headers: { cookie: "hwlab_session=test-stub-session" }
    });
    assert.equal(response.status, 200);
    const body = await response.json();
    assert.equal(body.status, "missing");
    assert.equal(body.projectionStatus, "projecting");
    assert.equal(body.eventCount, 0);
    assert.deepEqual(body.events, []);
    assert.deepEqual(calls, []);
    assert.equal(calls.some((call) => call.path === `/api/v1/runs/${runId}/commands/${commandId}/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 turn status does not backfill terminal AgentRun projection on GET (#1585)", async () => {
  const calls = [];
  const traceId = "trc_issue1422_turn_status_fast_path";
  const runId = "run_issue1422_turn_status_fast_path";
  const commandId = "cmd_issue1422_turn_status_fast_path";
  const events = [
    { id: "evt_issue1422_created", runId, seq: 1, type: "backend_status", payload: { phase: "runner-job-created", commandId }, createdAt: "2026-06-18T04:30:00.000Z" },
    { id: "evt_issue1422_terminal", runId, seq: 2, type: "terminal_status", payload: { commandId, terminalStatus: "completed" }, createdAt: "2026-06-18T04:30:01.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_issue1422_turn" })}\n`);
    };
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/events`) return send({ items: events });
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/commands/${commandId}/result`) return send({
      runId,
      commandId,
      status: "completed",
      runStatus: "claimed",
      commandState: "completed",
      terminalStatus: "completed",
      completed: true,
      reply: { content: "issue 1555 read-side backfill completed" },
      lastSeq: 2,
      eventCount: 2
    });
    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([[traceId, {
    accepted: true,
    status: "running",
    shortConnection: true,
    traceId,
    conversationId: "cnv_issue1422_turn_status",
    sessionId: "ses_issue1422_turn_status",
    threadId: "thread-issue1422-turn-status",
    ownerUserId: TEST_AGENT_ACTOR.id,
    ownerRole: TEST_AGENT_ACTOR.role,
    agentRun: { adapter: "agentrun-v01", managerUrl: `http://127.0.0.1:${agentRunPort}`, runId, commandId, traceId, providerTrace: { traceId }, lastSeq: 0, status: "running", commandState: "running", 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, "running");
    assert.equal(body.terminal, false);
    assert.equal(body.projectionStatus, "projecting");
    assert.equal(body.agentRun.commandState, "running");
    assert.equal(body.agentRun.terminalStatus ?? null, null);
    assert.equal(body.finalResponse, null);
    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 reuses request session lookup without loading persisted AgentRun result (#1519)", async () => {
  const calls = [];
  const traceId = "trc_issue1422_turn_status_session_cache";
  const runId = "run_issue1422_turn_status_session_cache";
  const commandId = "cmd_issue1422_turn_status_session_cache";
  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_issue1422_session_cache" })}\n`);
    };
    if (request.method === "GET" && url.pathname === `/api/v1/runs/${runId}/events`) {
      return send({ items: [
        { id: "evt_issue1422_session_cache_running", runId, seq: 1, type: "backend_status", payload: { phase: "runner-job-created", commandId }, createdAt: "2026-06-18T05:20:00.000Z" }
      ] });
    }
    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;
  let sessionLookupCount = 0;
  const session = testAgentSessionRecord({
    sessionId: "ses_issue1422_turn_status_session_cache",
    projectId: "prj_hwpod_workbench",
    conversationId: "cnv_issue1422_turn_status_session_cache",
    threadId: "thread-issue1422-turn-status-session-cache",
    lastTraceId: traceId,
    status: "running",
    session: {
      agentRun: {
        adapter: "agentrun-v01",
        managerUrl: `http://127.0.0.1:${agentRunPort}`,
        runId,
        commandId,
        traceId,
        providerTrace: { traceId, valuesPrinted: false },
        lastSeq: 0,
        status: "running",
        commandState: "running",
        backendProfile: "deepseek",
        valuesPrinted: false
      },
      valuesRedacted: true
    }
  });
  const server = createCloudApiServer({
    traceStore: createCodeAgentTraceStore(),
    codeAgentChatResults: new Map(),
    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(requestTraceId) {
        sessionLookupCount += 1;
        return requestTraceId === traceId ? session : null;
      }
    }
  });
  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}?projectId=prj_hwpod_workbench`, {
      headers: { cookie: "hwlab_session=test-stub-session" }
    });
    assert.equal(response.status, 404);
    const body = await response.json();
    assert.equal(body.status, "unknown");
    assert.equal(body.projectionStatus, "unknown");
    assert.equal(sessionLookupCount, 1);
    assert.equal(calls.filter((call) => call.path === `/api/v1/runs/${runId}/events`).length, 0);
  } 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 resumes AgentRun projection from durable state after restart", async () => {
  const calls = [];
  const durableEvents = [];
  const projectionStates = new Map();
  const ownerWrites = [];
  const traceId = "trc_projection_resume_restart";
  const runId = "run_projection_resume_restart";
  const commandId = "cmd_projection_resume_restart";
  const sessionId = "ses_projection_resume_restart";
  const conversationId = "cnv_projection_resume_restart";
  const finalText = "OK from resumed AgentRun projection.";

  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, afterSeq: url.searchParams.get("afterSeq") });
    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`) {
      assert.equal(url.searchParams.get("afterSeq"), "21");
      return send({ items: [
        { id: "evt_projection_resume_22", runId, seq: 22, type: "assistant_message", payload: { commandId, text: finalText }, createdAt: "2026-06-18T16:31:11.000Z" },
        { id: "evt_projection_resume_23", runId, seq: 23, type: "terminal_status", payload: { commandId, terminalStatus: "completed" }, createdAt: "2026-06-18T16:31:12.000Z" }
      ] });
    }
    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: 23,
        eventCount: 23,
        sessionRef: { sessionId, conversationId, threadId: "thread-projection-resume-restart" }
      });
    }
    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 session = testAgentSessionRecord({
    sessionId,
    conversationId,
    projectId: "prj_hwpod_workbench",
    status: "running",
    traceId,
    updatedAt: "2026-06-18T16:31:04.000Z",
    session: {
      traceResults: {
        [traceId]: {
          traceId,
          status: "running",
          sessionId,
          conversationId,
          updatedAt: "2026-06-18T16:31:04.000Z",
          agentRun: {
            adapter: "agentrun-v01",
            managerUrl: `http://127.0.0.1:${agentRunPort}`,
            runId,
            commandId,
            traceId,
            lastSeq: 0,
            status: "running",
            commandState: "running",
            backendProfile: "codex",
            valuesPrinted: false
          },
          valuesRedacted: true
        }
      }
    }
  });

  durableEvents.push({
    traceId,
    seq: 27,
    source: "agentrun",
    sourceSeq: 21,
    type: "backend",
    status: "running",
    label: "agentrun:backend:mcpServer/startupStatus/updated",
    commandId,
    runId,
    createdAt: "2026-06-18T16:31:04.200Z",
    valuesPrinted: false
  });
  projectionStates.set(traceId, {
    traceId,
    sessionId,
    conversationId,
    threadId: "thread-projection-resume-restart",
    ownerUserId: TEST_AGENT_ACTOR.id,
    ownerRole: TEST_AGENT_ACTOR.role,
    runId,
    commandId,
    sourceRunId: runId,
    sourceCommandId: commandId,
    managerUrl: `http://127.0.0.1:${agentRunPort}`,
    backendProfile: "codex",
    lastSourceSeq: 21,
    lastAgentRunSeq: 21,
    lastProjectedSeq: 27,
    sourceLatestSeq: 21,
    upstreamLatestSeq: 21,
    projectionStatus: "projecting",
    projectionHealth: "healthy",
    resultSyncState: "not_started",
    createdAt: "2026-06-18T16:31:04.000Z",
    updatedAt: "2026-06-18T16:31:04.000Z",
    valuesPrinted: false
  });

  const runtimeStore = {
    async queryAgentTraceEvents(params = {}) {
      return { events: durableEvents.filter((event) => event.traceId === params.traceId), count: durableEvents.length };
    },
    async writeAgentTraceEvent(params = {}) {
      const event = params.event ?? params.traceEvent ?? params;
      durableEvents.push(event);
      return { written: true, traceEvent: event };
    },
    async getWorkbenchProjectionState(params = {}) {
      const projectionState = projectionStates.get(params.traceId) ?? null;
      return { projectionState, found: Boolean(projectionState) };
    },
    async queryWorkbenchProjectionStates() {
      return { states: [...projectionStates.values()], count: projectionStates.size };
    },
    async writeWorkbenchProjectionState(params = {}) {
      const projectionState = params.projectionState ?? params.state ?? params;
      projectionStates.set(projectionState.traceId, projectionState);
      return { written: true, projectionState };
    }
  };
  const accessController = {
    required: false,
    store: {
      async listAgentSessionsForUser() { return [session]; },
      async getAgentSessionByTraceId(requestTraceId) { return requestTraceId === traceId ? session : null; }
    },
    async authenticate() { return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION }; },
    async recordAgentSessionOwner(input = {}) {
      ownerWrites.push(input);
      return { ...session, status: input.status ?? session.status, session: input.session ?? session.session };
    }
  };

  const server = createCloudApiServer({
    accessController,
    runtimeStore,
    codeAgentChatResults: new Map(),
    env: {
      HWLAB_CODE_AGENT_ADAPTER: "agentrun-v01",
      HWLAB_CODE_AGENT_AGENTRUN_ALLOW_NON_K3S_URL: "1",
      HWLAB_CODE_AGENT_AGENTRUN_PROJECTION_RESUME_ENABLED: "1",
      HWLAB_CODE_AGENT_AGENTRUN_PROJECTION_RESUME_INITIAL_DELAY_MS: "1",
      HWLAB_CODE_AGENT_AGENTRUN_PROJECTION_RESUME_INTERVAL_MS: "0",
      HWLAB_CODE_AGENT_AGENTRUN_PROJECTION_RESUME_MIN_AGE_MS: "0",
      HWLAB_CODE_AGENT_AGENTRUN_PROJECTION_RESUME_BATCH_SIZE: "10"
    }
  });
  await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));

  try {
    for (let index = 0; index < 80 && projectionStates.get(traceId)?.resultSyncState !== "synced"; index += 1) await delay(10);
    assert.ok(calls.some((call) => call.path === `/api/v1/runs/${runId}/events` && call.afterSeq === "21"));
    assert.equal(calls.some((call) => call.path === `/api/v1/runs/${runId}/commands/${commandId}/result`), true);
    assert.equal(projectionStates.get(traceId)?.lastSourceSeq, 23);
    assert.equal(projectionStates.get(traceId)?.resultSyncState, "synced");
    assert.equal(ownerWrites.some((write) => write.status === "completed"), true);
    assert.ok(durableEvents.some((event) => event.sourceSeq === 22));
  } 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 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, "projecting");
    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, "projecting");
    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, "projecting");
    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()));
    });
  }
});
