import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { spawnSync } from "node:child_process";
import { describe, expect, test } from "bun:test";
import {
  parseAgentRunClientConfigYaml,
  parseResourceOptions,
  renderMutationSummary,
  resolveAgentRunAuth,
  runAgentRunCommand,
  stripAgentRunResourceWrapperArgs,
} from "./agentrun";
import { resolveAgentRunLaneTarget } from "./agentrun-lanes";
import { agentRunToolCredentialRefs } from "./agentrun/config";
import { autoDispatchTargetTask, targetTaskDispatchDryRunPlan } from "./agentrun/rest-bridge";
import {
  AgentRunTargetTaskPreflightError,
  preflightTargetTask,
  preflightTargetTaskFromObservedWorkspace,
  resolveTargetTaskIdempotency,
  targetTaskIdempotencyKey,
  targetTaskOperationEvidence,
  targetTaskRequestFromArgs,
  type AgentRunTargetTaskPreflight,
} from "./agentrun/target-task";
import { placeholderAgentRunImage, renderAgentRunGitopsFiles } from "./agentrun-manifests";
import { collectLaneSecretSources, secretSyncScript } from "./agentrun/secrets";

function renderedTextOf(value: unknown): string {
  if (typeof value !== "object" || value === null) throw new Error("expected rendered CLI result");
  const text = (value as { renderedText?: unknown }).renderedText;
  if (typeof text !== "string") throw new Error("expected renderedText string");
  return text;
}

function renderedContentTypeOf(value: unknown): string {
  if (typeof value !== "object" || value === null) throw new Error("expected rendered CLI result");
  const contentType = (value as { contentType?: unknown }).contentType;
  if (typeof contentType !== "string") throw new Error("expected contentType string");
  return contentType;
}

function gitFixture(cwd: string, args: string[]): string {
  const result = spawnSync("git", args, { cwd, encoding: "utf8" });
  if (result.status !== 0) throw new Error(String(result.stderr || result.stdout));
  return String(result.stdout).trim();
}

const agentRunClientYaml = [
  "version: 1",
  "kind: AgentRunConfig",
  "metadata:",
  "  name: agentrun",
  "manager:",
  "  baseUrl: https://agentrun.127-0-0-1.nip.io/",
  "  timeoutMs: 15000",
  "publicExposure:",
  "  enabled: true",
  "  proxyName: agentrun-v01-frpc",
  "  remotePort: 22880",
  "  publicBaseUrl: https://agentrun.127-0-0-1.nip.io/",
  "  masterBaseUrl: http://127.0.0.1:22880",
  "  masterFrps:",
  "    configPath: /opt/hwlab-frp/frps.dev.toml",
  "    containerName: hwlab-frps-dev",
  "  masterCaddy:",
  "    enabled: true",
  "    domain: agentrun.127-0-0-1.nip.io",
  "    configPath: /etc/caddy/Caddyfile",
  "    serviceName: caddy",
  "    upstreamBaseUrl: http://127.0.0.1:22880",
  "    responseHeaderTimeoutSeconds: 60",
  "auth:",
  "  env: HWLAB_API_KEY",
  "  file: /tmp/hwlab-api-key.env",
  "  header: Authorization",
  "  scheme: Bearer",
  "client:",
  "  role: render-only",
  "  transport: direct-http",
  "  sessionPolicy:",
  "    tenantId: unidesk",
  "    projectId: test",
  "    providerId: NC01",
  "    backendProfile: codex",
  "    workspaceRef:",
  "      kind: opaque",
  "    executionPolicy:",
  "      sandbox: workspace-write",
  "      approval: never",
  "      timeoutMs: 600000",
  "      network: enabled",
  "      secretScope:",
  "        allowCredentialEcho: false",
].join("\n");

const agentRunMinimalClientYaml = [
  "version: 1",
  "kind: AgentRunConfig",
  "metadata:",
  "  name: agentrun",
  "manager:",
  "  baseUrl: http://agentrun.example.local:8080",
  "  timeoutMs: 15000",
  "auth:",
  "  env: HWLAB_API_KEY",
  "  file: /tmp/hwlab-api-key.env",
  "  header: Authorization",
  "  scheme: Bearer",
  "client:",
  "  role: render-only",
  "  transport: direct-http",
  "  sessionPolicy:",
  "    tenantId: unidesk",
  "    projectId: test",
  "    providerId: NC01",
  "    backendProfile: codex",
  "    workspaceRef:",
  "      kind: opaque",
  "    executionPolicy:",
  "      sandbox: workspace-write",
  "      approval: never",
  "      timeoutMs: 600000",
  "      network: enabled",
  "      secretScope:",
  "        allowCredentialEcho: false",
].join("\n");

describe("AgentRun resource bridge argv", () => {
  test("does not forward UniDesk output flags to create task prompt argv", () => {
    expect(stripAgentRunResourceWrapperArgs([
      "--aipod",
      "Artificer",
      "--prompt-stdin",
      "-o",
      "json",
      "--idempotency-key",
      "case-262",
      "--dry-run",
    ])).toEqual([
      "--aipod",
      "Artificer",
      "--prompt-stdin",
      "--idempotency-key",
      "case-262",
      "--dry-run",
    ]);
  });

  test("strips wrapper display flags while preserving official apply arguments", () => {
    expect(stripAgentRunResourceWrapperArgs([
      "-f",
      "-",
      "--output=yaml",
      "--raw",
      "--full",
      "--input",
      "--full-text",
      "--dry-run",
    ])).toEqual([
      "-f",
      "-",
      "--dry-run",
    ]);
  });
});

describe("AgentRun render-only REST client config", () => {
  test("parses explicit YAML config for direct REST render-only client", () => {
    const config = parseAgentRunClientConfigYaml(agentRunClientYaml, "config/agentrun.yaml");
    expect(config.manager.baseUrl).toBe("https://agentrun.127-0-0-1.nip.io/");
    expect(config.publicExposure?.publicBaseUrl).toBe("https://agentrun.127-0-0-1.nip.io/");
    expect(config.publicExposure?.masterCaddy.domain).toBe("agentrun.127-0-0-1.nip.io");
    expect(config.auth.env).toBe("HWLAB_API_KEY");
    expect(config.auth.header).toBe("Authorization");
    expect(config.auth.scheme).toBe("Bearer");
    expect(config.client.role).toBe("render-only");
    expect(config.client.transport).toBe("direct-http");
  });

  test("uses the owning YAML ten-minute session idle-timeout", () => {
    const config = parseAgentRunClientConfigYaml(readFileSync("config/agentrun.yaml", "utf8"), "config/agentrun.yaml");
    expect(config.client.sessionPolicy.executionPolicy.timeoutMs).toBe(600_000);
  });

  test("rejects a non-positive session idle-timeout", () => {
    const invalid = agentRunClientYaml.replace("      timeoutMs: 600000", "      timeoutMs: 0");
    expect(() => parseAgentRunClientConfigYaml(invalid, "config/agentrun.yaml")).toThrow(
      "client.sessionPolicy.executionPolicy.timeoutMs must be a positive integer",
    );
  });

  test("uses env auth before configured file auth without exposing the key", () => {
    const config = parseAgentRunClientConfigYaml(agentRunClientYaml, "config/agentrun.yaml");
    const auth = resolveAgentRunAuth(config, { HWLAB_API_KEY: "secret-value" });
    expect(auth.source).toBe("env");
    expect(auth.value).toBe("secret-value");
  });

  test("requires explicit render-only direct-http client contract", () => {
    expect(() => parseAgentRunClientConfigYaml(agentRunClientYaml.replace("  transport: direct-http", "  transport: ssh-bridge"), "config/agentrun.yaml")).toThrow("client.transport must be direct-http");
    expect(() => parseAgentRunClientConfigYaml(agentRunClientYaml.replace("  role: render-only", "  role: proxy"), "config/agentrun.yaml")).toThrow("client.role must be render-only");
  });

  test("parses YAML-first target-trans without a remote CLI worktree contract", () => {
    const targetYaml = agentRunClientYaml.replace(
      "  transport: direct-http",
      "  transport: target-trans",
    );
    const config = parseAgentRunClientConfigYaml(targetYaml, "config/agentrun.yaml");
    expect(config.client.transport).toBe("target-trans");
    expect(config.client).not.toHaveProperty("targetExecution");
  });
});

describe("Artificer Target one-command dispatch", () => {
  test("keeps only explicit absolute path and directory existence admission", () => {
    expect(() => targetTaskRequestFromArgs([
      "--title", "检查 AgentRun 工作区路径",
      "--target", "NC01",
      "--target-workspace", "relative/workspace",
      "--repo", "pikasTech/unidesk",
      "--ref", "fix/path-check",
      "--mdtodo-id", "tt_example-tasktree-id",
    ])).toThrow("--target-workspace 必须是 Target 上的绝对路径");

    const request = targetTaskRequestFromArgs([
      "--title", "检查 AgentRun 工作区路径",
      "--target", "NC01",
      "--target-workspace", "/definitely/missing/agentrun-workspace",
      "--repo", "pikasTech/unidesk",
      "--ref", "fix/path-check",
      "--mdtodo-id", "tt_example-tasktree-id",
    ]);
    if (request === null) throw new Error("expected Target request");
    expect(() => preflightTargetTask(request)).toThrow("Target 工作区不存在或不是目录");
  });

  test("admits dirty, ahead, behind, and mismatched Git state", () => {
    const workspace = mkdtempSync(join(tmpdir(), "unidesk-agentrun-target-"));
    const request = targetTaskRequestFromArgs([
      "--title", "修复 SelfMedia 的 OCR 规划器",
      "--target", "NC01",
      "--target-workspace", workspace,
      "--repo", "pikainc/selfmedia",
      "--ref", "declared/ref",
      "--mdtodo-id", "R6.3",
    ]);
    expect(request).not.toBeNull();
    if (request === null) throw new Error("expected Target request");
    try {
      gitFixture(workspace, ["init", "-b", "actual/ref"]);
      gitFixture(workspace, ["config", "user.email", "test@example.com"]);
      gitFixture(workspace, ["config", "user.name", "AgentRun Test"]);
      writeFileSync(join(workspace, "tracked.txt"), "base\n", "utf8");
      gitFixture(workspace, ["add", "tracked.txt"]);
      gitFixture(workspace, ["commit", "-m", "base"]);
      const baseCommit = gitFixture(workspace, ["rev-parse", "HEAD"]);
      const baseTree = gitFixture(workspace, ["rev-parse", "HEAD^{tree}"]);
      writeFileSync(join(workspace, "tracked.txt"), "local\n", "utf8");
      gitFixture(workspace, ["commit", "-am", "local ahead"]);
      const remoteCommit = gitFixture(workspace, ["commit-tree", baseTree, "-p", baseCommit, "-m", "remote behind"]);
      gitFixture(workspace, ["update-ref", "refs/remotes/origin/declared/ref", remoteCommit]);
      gitFixture(workspace, ["remote", "add", "origin", "https://example.invalid/wrong/repository.git"]);
      writeFileSync(join(workspace, "tracked.txt"), "dirty diff\n", "utf8");
      expect(gitFixture(workspace, ["rev-list", "--left-right", "--count", "HEAD...refs/remotes/origin/declared/ref"]))
        .toMatch(/^1\s+1$/u);
      expect(gitFixture(workspace, ["status", "--porcelain"])).not.toBe("");

      const preflight = preflightTargetTask(request);
      expect(preflight).toMatchObject({
        targetWorkspace: workspace,
        workspaceRoot: workspace,
        repository: "pikainc/selfmedia",
        ref: "declared/ref",
        sourceAuthority: {
          kind: "explicit-target-context",
          gitStateInspected: false,
          valuesPrinted: false,
        },
      });
      expect(preflight).not.toHaveProperty("verifiedCommit");
      expect(preflight).not.toHaveProperty("clean");
    } finally {
      rmSync(workspace, { recursive: true, force: true });
    }
    const preflight = {
      ...request,
      targetRoute: `${request.target}:${request.targetWorkspace}`,
      projectId: request.repository,
      workspaceRoot: request.targetWorkspace,
      sourceAuthority: {
        kind: "explicit-target-context",
        gitStateInspected: false,
        valuesPrinted: false,
      },
    } satisfies AgentRunTargetTaskPreflight;
    const operation = {
      aipod: "Artificer",
      tenantId: "default",
      projectId: request.repository,
      prompt: "完成 MDTODO R6.3",
    };
    expect(targetTaskIdempotencyKey(preflight, operation)).toMatch(/^artificer-target:[0-9a-f]{64}$/u);
    expect(targetTaskIdempotencyKey(preflight, operation)).toBe(targetTaskIdempotencyKey(preflight, operation));
    expect(targetTaskIdempotencyKey(preflight, { ...operation, prompt: "不同 payload" })).not.toBe(targetTaskIdempotencyKey(preflight, operation));
  });

  test("accepts a Target-observed absolute directory without inspecting Git or a remote CLI checkout", () => {
    const request = targetTaskRequestFromArgs([
      "--title", "验证 AgentRun 脏工作区派单",
      "--target", "NC01",
      "--target-workspace", "/root/.worktrees/unidesk/dirty-canary",
      "--repo", "pikasTech/unidesk",
      "--ref", "fix/dirty-canary",
      "--mdtodo-id", "R13",
    ]);
    if (request === null) throw new Error("expected Target request");
    expect(preflightTargetTaskFromObservedWorkspace(request, "/root/.worktrees/unidesk/dirty-canary")).toMatchObject({
      target: "NC01",
      workspaceRoot: "/root/.worktrees/unidesk/dirty-canary",
      sourceAuthority: {
        kind: "explicit-target-context",
        gitStateInspected: false,
      },
    });

    const source = readFileSync(new URL("./agentrun/target-execution.ts", import.meta.url), "utf8");
    expect(source).toContain('["argv", "pwd", "-P"]');
    expect(source).not.toContain("cliPath");
    expect(source).not.toMatch(/git\s/u);
  });

  test("scopes post-task create replay to one complete logical operation", () => {
    const base = {
      title: "修复 UniDesk 的 Artificer 派单",
      target: "NC01",
      targetRoute: "NC01:/root/unidesk/.worktree/base",
      projectId: "pikasTech/unidesk",
      workspaceRoot: "/root/unidesk/.worktree/base",
      sourceAuthority: {
        kind: "explicit-target-context",
        gitStateInspected: false,
        valuesPrinted: false,
      },
    } as const;
    const fixtures = [
      { mdtodoId: "R8", targetWorkspace: "/root/unidesk/.worktree/2165", repository: "pikasTech/unidesk", ref: "fix/2165", prompt: "Issue #2165" },
      { mdtodoId: "R7.1", targetWorkspace: "/root/unidesk/.worktree/2163", repository: "pikasTech/unidesk", ref: "fix/2163", prompt: "Issue #2163" },
      { mdtodoId: "R7.2", targetWorkspace: "/root/unidesk/.worktree/2010", repository: "pikasTech/unidesk", ref: "feat/2010", prompt: "Issue #2010" },
      { mdtodoId: "R3", targetWorkspace: "/root/unidesk/.worktree/1888", repository: "pikasTech/unidesk", ref: "fix/1888", prompt: "Issue #1888" },
    ];
    const keys = fixtures.map((fixture) => targetTaskIdempotencyKey(
      {
        ...base,
        ...fixture,
        targetRoute: `NC01:${fixture.targetWorkspace}`,
        workspaceRoot: fixture.targetWorkspace,
      },
      { aipod: "Artificer", tenantId: "default", projectId: fixture.repository, prompt: fixture.prompt },
    ));
    expect(new Set(keys).size).toBe(fixtures.length);

    const replay = {
      ...base,
      ...fixtures[0],
      targetRoute: `NC01:${fixtures[0].targetWorkspace}`,
      workspaceRoot: fixtures[0].targetWorkspace,
    } satisfies AgentRunTargetTaskPreflight;
    const operation = { aipod: "Artificer", tenantId: "default", projectId: replay.repository, prompt: fixtures[0].prompt };
    const evidence = targetTaskOperationEvidence(replay, operation);
    expect(evidence.payloadHash).toMatch(/^sha256:[0-9a-f]{64}$/u);
    expect(resolveTargetTaskIdempotency(replay, operation, targetTaskIdempotencyKey(replay, operation)).idempotencyKey).toBe(keys[0]);
    expect(() => resolveTargetTaskIdempotency(replay, { ...operation, prompt: "changed payload" }, keys[0])).toThrow(
      "不同 payload 不得复用同一 key",
    );
    try {
      resolveTargetTaskIdempotency(replay, { ...operation, prompt: "changed payload" }, keys[0]);
      throw new Error("expected idempotency conflict");
    } catch (error) {
      expect(error).toBeInstanceOf(Error);
      expect((error as AgentRunTargetTaskPreflightError).stage).toBe("idempotency-key-conflict");
      expect((error as AgentRunTargetTaskPreflightError).details).toMatchObject({
        code: "target-task-idempotency-key-conflict",
        reason: "provided-key-does-not-match-canonical-logical-operation",
        mutation: false,
        valuesPrinted: false,
      });
      expect((error as AgentRunTargetTaskPreflightError).details).not.toHaveProperty("providedKey");
    }
  });

  test("auto-dispatches pending submit exactly once and reuses existing attempt identity on retry", async () => {
    let dispatchRequests = 0;
    const server = Bun.serve({
      port: 0,
      async fetch(request) {
        const url = new URL(request.url);
        expect(request.headers.get("authorization")).toBe("Bearer secret-value");
        if (request.method === "POST" && url.pathname === "/api/v1/queue/tasks/qt_target/dispatch") {
          dispatchRequests += 1;
          return Response.json({
            ok: true,
            data: {
              task: { id: "qt_target", state: "running" },
              run: { id: "run_target", sessionRef: { sessionId: "ses_target" } },
              command: { id: "cmd_target" },
              latestAttempt: {
                attemptId: "qat_target",
                runId: "run_target",
                commandId: "cmd_target",
                runnerJobId: "rjob_target",
                sessionId: "ses_target",
              },
            },
          });
        }
        return new Response("not found", { status: 404 });
      },
    });
    const previousConfig = process.env.AGENTRUN_CLIENT_CONFIG;
    const previousKey = process.env.HWLAB_API_KEY;
    const tempConfigPath = `/tmp/unidesk-agentrun-target-dispatch-test-${process.pid}-${Date.now()}.yaml`;
    try {
      process.env.AGENTRUN_CLIENT_CONFIG = tempConfigPath;
      process.env.HWLAB_API_KEY = "secret-value";
      await Bun.write(tempConfigPath, agentRunMinimalClientYaml.replace("http://agentrun.example.local:8080", server.url.href.replace(/\/$/u, "")));
      const first = await autoDispatchTargetTask(
        { ok: true, data: { id: "qt_target", state: "pending" } },
        { mdtodoId: "R6.3" },
        { aipod: "Artificer" },
      );
      expect(dispatchRequests).toBe(1);
      expect((first.data as Record<string, unknown>).runId).toBe("run_target");
      expect((first.data as Record<string, unknown>).sessionId).toBe("ses_target");
      expect(((first.autoDispatch as Record<string, unknown>).decision)).toBe("dispatched");

      const replay = await autoDispatchTargetTask(
        {
          ok: true,
          data: {
            id: "qt_target",
            state: "running",
            latestAttempt: {
              attemptId: "qat_target",
              runId: "run_target",
              commandId: "cmd_target",
              runnerJobId: "rjob_target",
              sessionId: "ses_target",
            },
          },
        },
        { mdtodoId: "R6.3" },
        { aipod: "Artificer" },
      );
      expect(dispatchRequests).toBe(1);
      expect(((replay.autoDispatch as Record<string, unknown>).decision)).toBe("idempotent-replay");
      expect(((replay.autoDispatch as Record<string, unknown>).duplicateDispatchPrevented)).toBe(true);

      const plan = targetTaskDispatchDryRunPlan("artificer-target:test");
      expect(plan.sequence).toEqual(["queue-submit", "queue-dispatch"]);
      expect((plan.request as Record<string, unknown>).pathTemplate).toBe("/api/v1/queue/tasks/<submitted-task-id>/dispatch");
      expect(plan.mutation).toBe(false);
    } finally {
      server.stop(true);
      if (previousConfig === undefined) delete process.env.AGENTRUN_CLIENT_CONFIG;
      else process.env.AGENTRUN_CLIENT_CONFIG = previousConfig;
      if (previousKey === undefined) delete process.env.HWLAB_API_KEY;
      else process.env.HWLAB_API_KEY = previousKey;
      rmSync(tempConfigPath, { force: true });
    }
  });

  test("keeps Target live human, JSON, and YAML output bounded while retaining dispatch identities", () => {
    const outputConfig = Bun.YAML.parse(
      readFileSync(new URL("../../config/unidesk-cli.yaml", import.meta.url), "utf8"),
    ) as { output?: { maxStdoutBytes?: number } };
    const maxStdoutBytes = outputConfig.output?.maxStdoutBytes;
    if (typeof maxStdoutBytes !== "number") throw new Error("expected YAML-first output.maxStdoutBytes");
    const hugePrompt = "PROMPT_SHOULD_NOT_BE_RENDERED_".repeat(500);
    expect(Buffer.byteLength(hugePrompt, "utf8")).toBeGreaterThan(maxStdoutBytes);

    const identity = {
      taskId: "qt_compact_target",
      taskState: "running",
      attemptId: "qat_compact_target",
      runId: "run_compact_target",
      commandId: "cmd_compact_target",
      runnerJobId: "rjob_compact_target",
      sessionId: "sess_compact_target",
      valuesPrinted: false,
    };
    const autoDispatch = {
      enabled: true,
      decision: "dispatched",
      mutation: true,
      duplicateDispatchPrevented: false,
      identity,
      valuesPrinted: false,
    };
    const raw = {
      ok: true,
      action: "queue-submit-auto-dispatch",
      data: {
        ...identity,
        attemptState: "running",
        runState: "running",
        commandState: "running",
        runnerState: "claimed",
        sessionState: "active",
        mutation: true,
        autoDispatch,
        task: {
          id: identity.taskId,
          state: identity.taskState,
          prompt: hugePrompt,
          payload: { prompt: hugePrompt },
          latestAttempt: {
            attemptId: identity.attemptId,
            state: "running",
            runnerJobId: identity.runnerJobId,
            runnerState: "claimed",
            sessionId: identity.sessionId,
          },
        },
        run: {
          id: identity.runId,
          state: "running",
          sessionRef: { sessionId: identity.sessionId, state: "active" },
        },
        command: { id: identity.commandId, state: "running", payload: { prompt: hugePrompt } },
        latestAttempt: {
          attemptId: identity.attemptId,
          state: "running",
          runId: identity.runId,
          commandId: identity.commandId,
          runnerJobId: identity.runnerJobId,
          runnerState: "claimed",
          sessionId: identity.sessionId,
        },
        session: { id: identity.sessionId, state: "active", prompt: hugePrompt },
        valuesPrinted: false,
      },
      targetTask: {
        mdtodoId: "R6.4",
        target: "NC01",
        targetWorkspace: "/root/.worktrees/unidesk/artificer-compact-output",
        targetRoute: "NC01:/root/.worktrees/unidesk/artificer-compact-output",
        projectId: "pikasTech/unidesk",
        repository: "pikasTech/unidesk",
        ref: "fix/artificer-compact-output",
        workspace: {
          root: "/root/.worktrees/unidesk/artificer-compact-output",
          gitStateInspected: false,
        },
        prompt: hugePrompt,
      },
      aipodBinding: {
        aipod: "Artificer",
        node: "NC01",
        lane: "nc01-v02",
        namespace: "agentrun-v01",
        projectId: "pikasTech/unidesk",
        providerId: "NC01",
        backendProfile: "sub2api",
        workspaceRef: { kind: "opaque", path: ".", valid: true },
        resourceBundleRef: {
          kind: "gitbundle",
          repoUrl: "https://credential-must-be-redacted@github.com/pikasTech/unidesk.git",
          ref: "fix/artificer-compact-output",
          inheritedFromAipod: true,
          credentialRefPresent: true,
        },
        session: { sessionId: identity.sessionId, identitySource: "task" },
        providerCredentials: [{
          profile: "sub2api",
          secretRef: { namespace: "agentrun-v01", name: "agentrun-provider", keys: ["auth.json"] },
          bindingPresent: true,
          value: hugePrompt,
        }],
        toolCredentials: [{
          tool: "github",
          purpose: "pull-request",
          secretRef: { namespace: "agentrun-v01", name: "agentrun-github", keys: ["GH_TOKEN"] },
          bindingPresent: true,
          value: hugePrompt,
        }],
        prompt: hugePrompt,
      },
      autoDispatch,
      valuesPrinted: false,
    };
    expect(Buffer.byteLength(JSON.stringify(raw), "utf8")).toBeGreaterThan(maxStdoutBytes);

    const variants = [
      { name: "human", args: [] },
      { name: "json", args: ["-o", "json"] },
      { name: "yaml", args: ["-o", "yaml"] },
    ];
    for (const variant of variants) {
      const rendered = renderMutationSummary(
        "agentrun queue submit",
        raw,
        parseResourceOptions(variant.args),
        "Queue task submitted",
      );
      const text = renderedTextOf(rendered);
      expect(Buffer.byteLength(text, "utf8"), variant.name).toBeLessThan(maxStdoutBytes);
      expect(text).not.toContain("PROMPT_SHOULD_NOT_BE_RENDERED_");
      expect(text).not.toContain("credential-must-be-redacted");
      for (const value of Object.values(identity).filter((item): item is string => typeof item === "string")) {
        expect(text, `${variant.name}:${value}`).toContain(value);
      }
      expect(text).toContain("R6.4");
      expect(text).toContain("dispatched");
      expect(text).toContain("gitStateInspected");
      expect(text).not.toContain("verifiedCommit");
      expect(text).not.toContain("refRelation");
    }

    const jsonText = renderedTextOf(renderMutationSummary(
      "agentrun queue submit",
      raw,
      parseResourceOptions(["-o", "json"]),
      "Queue task submitted",
    ));
    const json = JSON.parse(jsonText) as Record<string, unknown>;
    const jsonData = json.data as Record<string, unknown>;
    const jsonNext = json.next as Record<string, unknown>;
    const jsonCredentials = (json.aipodBinding as Record<string, unknown>).credentialRefs as Record<string, unknown>;
    expect(jsonData).toMatchObject({
      taskId: identity.taskId,
      taskState: "running",
      attemptId: identity.attemptId,
      attemptState: "running",
      runId: identity.runId,
      runState: "running",
      commandId: identity.commandId,
      commandState: "running",
      runnerJobId: identity.runnerJobId,
      runnerState: "claimed",
      sessionId: identity.sessionId,
      sessionState: "active",
    });
    expect((json.autoDispatch as Record<string, unknown>).decision).toBe("dispatched");
    expect((json.targetTask as Record<string, unknown>).mdtodoId).toBe("R6.4");
    expect((json.targetTask as Record<string, unknown>).workspace).toEqual({
      root: "/root/.worktrees/unidesk/artificer-compact-output",
      gitStateInspected: false,
      valuesPrinted: false,
    });
    expect(jsonCredentials).toMatchObject({ totalCount: 2, allPresent: true });
    expect((jsonCredentials.provider as Record<string, unknown>).presentCount).toBe(1);
    expect((jsonCredentials.tool as Record<string, unknown>).presentCount).toBe(1);
    expect(jsonNext.result).toBe(
      `bun scripts/cli.ts agentrun result run/${identity.runId} --command ${identity.commandId} --target NC01 --lane nc01-v02`,
    );
    expect(jsonNext.logs).toBe(
      `bun scripts/cli.ts agentrun logs session/${identity.sessionId} --tail 120 --target NC01 --lane nc01-v02`,
    );

    const yamlText = renderedTextOf(renderMutationSummary(
      "agentrun queue submit",
      raw,
      parseResourceOptions(["-o", "yaml"]),
      "Queue task submitted",
    ));
    const yaml = Bun.YAML.parse(yamlText) as Record<string, unknown>;
    expect(yaml.data).toMatchObject(json.data as object);
    expect(yaml.next).toMatchObject(json.next as object);
  });
});

describe("AgentRun default transport contract", () => {
  test("server-facing compatibility groups use REST dispatcher, not official SSH CLI wrapper", () => {
    const source = readFileSync(new URL("./agentrun/entry.ts", import.meta.url), "utf8");
    const commandRouter = source.slice(source.indexOf("export async function runAgentRunCommand"), source.indexOf("function isAgentRunRestCompatGroup"));
    expect(commandRouter).toContain("runAgentRunRestCompatCommand");
    expect(commandRouter).not.toContain("runOfficialAgentRunCli");
    expect(commandRouter).not.toContain("runPreparedOfficialAgentRunCli");
  });

  test("resource verbs can use direct REST without UniDesk SSH config", async () => {
    const server = Bun.serve({
      port: 0,
      fetch(request) {
        const url = new URL(request.url);
        expect(request.headers.get("authorization")).toBe("Bearer secret-value");
        expect(url.pathname).toBe("/api/v1/queue/tasks");
        expect(url.searchParams.get("queue")).toBe("commander");
        expect(url.searchParams.get("state")).toBe("running");
        return Response.json({
          ok: true,
          data: {
            items: [
              { id: "qt_1", state: "queued", queue: "commander" },
            ],
          },
        });
      },
    });
    const previousConfig = process.env.AGENTRUN_CLIENT_CONFIG;
    const previousKey = process.env.HWLAB_API_KEY;
    process.env.HWLAB_API_KEY = "secret-value";
    const tempConfigPath = `/tmp/unidesk-agentrun-test-${process.pid}-${Date.now()}.yaml`;
    try {
      process.env.AGENTRUN_CLIENT_CONFIG = tempConfigPath;
      await Bun.write(process.env.AGENTRUN_CLIENT_CONFIG, agentRunMinimalClientYaml.replace("http://agentrun.example.local:8080", server.url.href.replace(/\/$/u, "")));
      const result = await runAgentRunCommand(null, ["get", "tasks", "--queue", "commander", "-o", "json"]);
      expect(result.ok).toBe(true);
      expect("renderedText" in result).toBe(true);
      if ("renderedText" in result) {
        expect(result.renderedText).toContain("\"kind\": \"TaskList\"");
        expect(result.renderedText).toContain("\"name\": \"qt_1\"");
      }
    } finally {
      server.stop(true);
      if (previousConfig === undefined) delete process.env.AGENTRUN_CLIENT_CONFIG;
      else process.env.AGENTRUN_CLIENT_CONFIG = previousConfig;
      if (previousKey === undefined) delete process.env.HWLAB_API_KEY;
      else process.env.HWLAB_API_KEY = previousKey;
      rmSync(tempConfigPath, { force: true });
    }
  });

  test("task input drill-down is bounded, reconstructable, and SecretRef-only", async () => {
    const taskId = "qt_artificer_input";
    const hiddenCredential = "HIDDEN_CREDENTIAL_VALUE_MUST_NOT_BE_PRINTED";
    const task = {
      id: taskId,
      tenantId: "unidesk",
      projectId: "pikasTech/unidesk",
      queue: "commander",
      lane: "v0.1",
      title: "Artificer input fixture",
      priority: 50,
      state: "completed",
      version: 7,
      backendProfile: "sub2api",
      providerId: "G14",
      workspaceRef: { kind: "opaque", path: ".", repo: "pikasTech/unidesk", branch: "master" },
      sessionRef: { sessionId: "ses_fixture", conversationId: "conv_fixture", metadata: { credential: hiddenCredential } },
      executionPolicy: {
        sandbox: "workspace-write",
        approval: "never",
        timeoutMs: 1_800_000,
        network: "enabled",
        secretScope: {
          allowCredentialEcho: false,
          providerCredentials: [{
            profile: "sub2api",
            secretRef: { name: "agentrun-provider", keys: ["auth.json"], value: hiddenCredential },
            value: hiddenCredential,
          }],
          toolCredentials: [{
            tool: "github",
            purpose: "github-pr",
            secretRef: { name: "agentrun-github", keys: ["GH_TOKEN"], token: hiddenCredential },
            projection: { kind: "env", envName: "GH_TOKEN", secretKey: "GH_TOKEN", value: hiddenCredential },
          }],
        },
      },
      resourceBundleRef: {
        kind: "gitbundle",
        repoUrl: `https://fixture:${hiddenCredential}@github.com/pikasTech/unidesk.git`,
        ref: "master",
        bundles: [{ name: "unidesk-skills", subpath: ".agents/skills", targetPath: ".agents/skills" }],
        requiredSkills: [{ name: "unidesk-gh" }],
        credentialRef: { name: "agentrun-resource-git", keys: ["username", "password"], value: hiddenCredential },
        submodules: false,
        lfs: false,
      },
      payload: { prompt: "Inspect the existing sentinel configuration.", model: "gpt-5.5" },
      payloadHash: "sha256:fixture",
      references: [{ kind: "github-issue", url: "https://github.com/pikasTech/unidesk/issues/1819" }],
      metadata: {
        aipod: "Artificer",
        source: "config/aipods/artificer.yaml",
        aipodSpecHash: "sha256:aipod-fixture",
        aipodImageRef: {
          kind: "env-image-dockerfile",
          repoUrl: `https://fixture:${hiddenCredential}@github.com/pikasTech/agentrun.git`,
          commitId: "a".repeat(40),
          dockerfilePath: "deploy/container/Containerfile",
        },
        credential: hiddenCredential,
      },
      idempotencyKey: "artificer-input-fixture",
      latestAttempt: { attemptId: "qat_fixture", state: "completed", runId: "run_fixture", commandId: "cmd_fixture", runnerJobId: "rjob_fixture", sessionId: "ses_fixture" },
      supervisor: { verboseDiagnostic: "x".repeat(20_000), credential: hiddenCredential },
      valuesPrinted: false,
    };
    let requests = 0;
    const server = Bun.serve({
      port: 0,
      fetch(request) {
        const url = new URL(request.url);
        expect(request.headers.get("authorization")).toBe("Bearer secret-value");
        expect(url.pathname).toBe(`/api/v1/queue/tasks/${taskId}`);
        requests += 1;
        return Response.json({ ok: true, data: task });
      },
    });
    const previousConfig = process.env.AGENTRUN_CLIENT_CONFIG;
    const previousKey = process.env.HWLAB_API_KEY;
    process.env.HWLAB_API_KEY = "secret-value";
    const tempConfigPath = `/tmp/unidesk-agentrun-input-test-${process.pid}-${Date.now()}.yaml`;
    try {
      process.env.AGENTRUN_CLIENT_CONFIG = tempConfigPath;
      await Bun.write(tempConfigPath, agentRunMinimalClientYaml.replace("http://agentrun.example.local:8080", server.url.href.replace(/\/$/u, "")));

      const invalidCombinations = [
        { args: ["--input", "--full"], contentType: "text/plain" },
        { args: ["--full", "--input", "-o", "json"], contentType: "application/json" },
        { args: ["--input", "--full", "-o", "yaml"], contentType: "application/yaml" },
        { args: ["--input", "--raw"], contentType: "application/json" },
      ];
      for (const invalid of invalidCombinations) {
        const rejected = await runAgentRunCommand(null, ["describe", `task/${taskId}`, ...invalid.args]);
        const rejectedText = renderedTextOf(rejected);
        expect(rejected.ok).toBe(false);
        expect(renderedContentTypeOf(rejected)).toBe(invalid.contentType);
        expect(rejectedText).toContain("validation-failed");
        expect(rejectedText).toContain("cannot be combined with complete resource disclosure");
        expect(rejectedText).not.toContain(hiddenCredential);
        expect(rejectedText).not.toContain("supervisor");
        expect(Buffer.byteLength(rejectedText, "utf8")).toBeLessThan(2400);
      }
      expect(requests).toBe(0);

      const summaryText = renderedTextOf(await runAgentRunCommand(null, ["describe", `task/${taskId}`]));
      expect(summaryText).toContain(`agentrun describe task/${taskId} --input -o json`);
      expect(summaryText).not.toContain(hiddenCredential);

      const compact = JSON.parse(renderedTextOf(await runAgentRunCommand(null, ["describe", `task/${taskId}`, "-o", "json"]))) as { next?: { input?: string } };
      expect(compact.next?.input).toContain("--input -o json");

      const inputText = renderedTextOf(await runAgentRunCommand(null, ["describe", `task/${taskId}`, "--input"]));
      const input = JSON.parse(inputText) as {
        kind?: string;
        spec?: Record<string, any>;
        aipodSpec?: Record<string, any>;
        provenance?: Record<string, any>;
        redaction?: Record<string, any>;
        valuesPrinted?: boolean;
      };
      expect(input.kind).toBe("TaskInput");
      expect(input.spec?.payload?.prompt).toBe(task.payload.prompt);
      expect(input.spec?.idempotencyKey).toBe(task.idempotencyKey);
      expect(input.spec?.metadata?.aipod).toBe("Artificer");
      expect(input.aipodSpec?.specHash).toBe("sha256:aipod-fixture");
      expect(input.provenance?.sourceTaskId).toBe(taskId);
      expect(input.spec?.executionPolicy?.secretScope?.providerCredentials?.[0]?.secretRef).toEqual({
        name: "agentrun-provider",
        keys: ["auth.json"],
        valuesPrinted: false,
      });
      expect(input.spec?.resourceBundleRef?.credentialRef).toEqual({
        name: "agentrun-resource-git",
        keys: ["username", "password"],
        valuesPrinted: false,
      });
      expect(input.spec?.resourceBundleRef?.repoUrl).toBe("https://github.com/pikasTech/unidesk.git");
      expect(input.aipodSpec?.imageRef?.repoUrl).toBe("https://github.com/pikasTech/agentrun.git");
      expect(input.redaction?.credentialValues).toBe("omitted");
      expect(input.valuesPrinted).toBe(false);
      expect(inputText).not.toContain(hiddenCredential);
      expect(Buffer.byteLength(inputText, "utf8")).toBeLessThan(10_240);

      const full = JSON.parse(renderedTextOf(await runAgentRunCommand(null, ["describe", `task/${taskId}`, "--full", "-o", "json"]))) as { resource?: typeof task };
      expect(full.resource?.executionPolicy.secretScope.providerCredentials[0]?.secretRef.value).toBe(hiddenCredential);
      const raw = JSON.parse(renderedTextOf(await runAgentRunCommand(null, ["describe", `task/${taskId}`, "--raw"]))) as { data?: typeof task };
      expect(raw.data?.resourceBundleRef.credentialRef.value).toBe(hiddenCredential);
      expect(requests).toBe(5);
    } finally {
      server.stop(true);
      if (previousConfig === undefined) delete process.env.AGENTRUN_CLIENT_CONFIG;
      else process.env.AGENTRUN_CLIENT_CONFIG = previousConfig;
      if (previousKey === undefined) delete process.env.HWLAB_API_KEY;
      else process.env.HWLAB_API_KEY = previousKey;
      rmSync(tempConfigPath, { force: true });
    }
  });

  test("aipodspec describe is bounded and homologous while full and raw stay complete", async () => {
    const aipodName = "Artificer";
    const hiddenCredential = "HIDDEN_AIPOD_CREDENTIAL_VALUE_MUST_NOT_BE_PRINTED";
    const providerCredential = {
      profile: "sub2api",
      name: "agentrun-provider",
      namespace: null,
      keys: ["auth.json", "config.toml"],
      value: hiddenCredential,
      valuesPrinted: false,
    };
    const toolCredentials = [
      {
        tool: "github",
        purpose: "github-pr",
        name: "agentrun-github",
        namespace: null,
        keys: ["GH_TOKEN"],
        projection: { kind: "env", envName: "GH_TOKEN", secretKey: "GH_TOKEN", value: hiddenCredential },
        token: hiddenCredential,
        valuesPrinted: false,
      },
      {
        tool: "ssh",
        purpose: "remote-workspace",
        name: "agentrun-ssh",
        namespace: null,
        keys: ["config", "key"],
        projection: { kind: "mount", mountPath: "/run/secrets/ssh", value: hiddenCredential },
        valuesPrinted: false,
      },
      {
        tool: "provider",
        purpose: "model-auth",
        name: "agentrun-provider",
        namespace: null,
        keys: ["auth.json"],
        projection: { kind: "mount", mountPath: "/run/secrets/provider", value: hiddenCredential },
        valuesPrinted: false,
      },
    ];
    const data = {
      action: "show",
      item: {
        name: aipodName,
        displayName: "Artificer",
        description: "x".repeat(20_000),
        specHash: "sha256:aipod-fixture",
        source: "config/aipods/artificer.yaml",
        backendProfile: "sub2api",
        model: { model: "gpt-5.5", reasoningEffort: "high" },
        imageRef: {
          kind: "env-image-dockerfile",
          repoUrl: "https://github.com/pikasTech/agentrun.git",
          commitId: "a".repeat(40),
          dockerfilePath: "deploy/container/Containerfile",
          sourceIdentity: "agentrun@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
          valuesPrinted: false,
        },
        queue: "commander",
        lane: "v0.1",
        providerId: "NC01",
        providerCredentials: { count: 1, profiles: ["sub2api"], items: [providerCredential], valuesPrinted: false },
        toolCredentials: { count: 3, tools: ["github", "ssh", "provider"], items: toolCredentials, valuesPrinted: false },
        resourceBundleRef: {
          kind: "gitbundle",
          repoUrl: `https://fixture:${hiddenCredential}@github.com/pikasTech/unidesk.git`,
          ref: "master",
          commitId: null,
          bundles: { count: 6, items: [{ name: "unidesk-skills", targetPath: ".agents/skills" }], valuesPrinted: false },
          requiredSkills: { count: 11, names: ["unidesk-gh"], valuesPrinted: false },
          promptRefs: { count: 0, names: [], valuesPrinted: false },
          valuesPrinted: false,
        },
        createdAt: "2026-07-12T00:00:00.000Z",
        updatedAt: "2026-07-12T01:00:00.000Z",
        valuesPrinted: false,
      },
      spec: {
        apiVersion: "agentrun.pikastech.local/v1alpha1",
        kind: "AipodSpec",
        metadata: { name: aipodName, displayName: "Artificer", description: "x".repeat(20_000) },
        spec: {
          queue: "commander",
          lane: "v0.1",
          providerId: "NC01",
          backendProfile: "sub2api",
          model: { model: "gpt-5.5", reasoningEffort: "high" },
          workspaceRef: { kind: "opaque", path: "." },
          executionPolicy: {
            secretScope: {
              allowCredentialEcho: false,
              providerCredentials: [{ profile: "sub2api", secretRef: { name: "agentrun-provider", keys: ["auth.json"], value: hiddenCredential } }],
              toolCredentials: [{ tool: "github", secretRef: { name: "agentrun-github", keys: ["GH_TOKEN"], token: hiddenCredential } }],
            },
          },
          resourceBundleRef: {
            kind: "gitbundle",
            repoUrl: `https://fixture:${hiddenCredential}@github.com/pikasTech/unidesk.git`,
            ref: "master",
            bundles: [{ name: "unidesk-skills", subpath: ".agents/skills", targetPath: ".agents/skills" }],
            requiredSkills: [{ name: "unidesk-gh" }],
          },
          metadata: { aipod: aipodName, source: "config/aipods/artificer.yaml" },
        },
      },
      valuesPrinted: false,
    };
    let requests = 0;
    const server = Bun.serve({
      port: 0,
      fetch(request) {
        const url = new URL(request.url);
        expect(request.headers.get("authorization")).toBe("Bearer secret-value");
        expect(url.pathname).toBe(`/api/v1/aipod-specs/${aipodName}`);
        requests += 1;
        return Response.json({ ok: true, data });
      },
    });
    const previousConfig = process.env.AGENTRUN_CLIENT_CONFIG;
    const previousKey = process.env.HWLAB_API_KEY;
    process.env.HWLAB_API_KEY = "secret-value";
    const tempConfigPath = `/tmp/unidesk-agentrun-aipodspec-test-${process.pid}-${Date.now()}.yaml`;
    try {
      process.env.AGENTRUN_CLIENT_CONFIG = tempConfigPath;
      await Bun.write(tempConfigPath, agentRunMinimalClientYaml.replace("http://agentrun.example.local:8080", server.url.href.replace(/\/$/u, "")));

      const text = renderedTextOf(await runAgentRunCommand(null, ["describe", `aipodspec/${aipodName}`]));
      expect(text).toContain(`Name:  aipodspec/${aipodName}`);
      expect(text).toContain("Hash:     sha256:aipod-fixture");
      expect(text).toContain("Kind: opaque path=. branch=-");
      expect(text).toContain("References: bundles=6 requiredSkills=11 promptRefs=0");
      expect(text).toContain("Required skills: unidesk-gh (+10 omitted)");
      expect(text).toContain("Credentials: provider=1 tool=3 total=4");
      expect(text).toContain("secret=agentrun-provider keys=auth.json,config.toml");
      expect(text).toContain(`agentrun describe aipodspec/${aipodName} --full -o json`);
      expect(Buffer.byteLength(text, "utf8")).toBeLessThan(10_240);
      expect(text).not.toContain(hiddenCredential);

      const jsonText = renderedTextOf(await runAgentRunCommand(null, ["describe", `aipodspec/${aipodName}`, "-o", "json"]));
      const json = JSON.parse(jsonText) as Record<string, any>;
      const yamlText = renderedTextOf(await runAgentRunCommand(null, ["describe", `aipodspec/${aipodName}`, "-o", "yaml"]));
      const yaml = Bun.YAML.parse(yamlText) as Record<string, any>;
      expect(yaml).toEqual(json);
      expect(json.kind).toBe("AipodSpec");
      expect(json.identity.specHash).toBe("sha256:aipod-fixture");
      expect(json.runtime).toMatchObject({ lane: "v0.1", backendProfile: "sub2api", providerId: "NC01" });
      expect(json.workspaceRef).toMatchObject({ kind: "opaque", path: ".", valuesPrinted: false });
      expect(json.resourceBundleRef.sourceIdentity.repoUrl).toBe("https://github.com/pikasTech/unidesk.git");
      expect(json.resourceBundleRef).toMatchObject({ bundleCount: 6, requiredSkillCount: 11, promptRefCount: 0 });
      expect(json.resourceBundleRef.requiredSkills).toEqual({ count: 11, names: ["unidesk-gh"], omittedCount: 10, valuesPrinted: false });
      expect(json.credentialRefs).toMatchObject({ totalCount: 4, valuesPrinted: false });
      expect(json.credentialRefs.provider.items[0].secretRef).toEqual({
        namespace: null,
        name: "agentrun-provider",
        keys: ["auth.json", "config.toml"],
        valuesPrinted: false,
      });
      expect(json.redaction).toEqual({ credentialValues: "omitted", secretRefsOnly: true, valuesPrinted: false });
      expect(json.valuesPrinted).toBe(false);
      for (const bounded of [jsonText, yamlText]) {
        expect(Buffer.byteLength(bounded, "utf8")).toBeLessThan(10_240);
        expect(bounded).not.toContain(hiddenCredential);
        expect(bounded).not.toContain("x".repeat(200));
      }

      const full = JSON.parse(renderedTextOf(await runAgentRunCommand(null, ["describe", `aipodspec/${aipodName}`, "--full", "-o", "json"]))) as { resource?: typeof data };
      expect(full.resource?.item.description).toBe("x".repeat(20_000));
      expect(full.resource?.spec.kind).toBe("AipodSpec");
      const raw = JSON.parse(renderedTextOf(await runAgentRunCommand(null, ["describe", `aipodspec/${aipodName}`, "--raw"]))) as { data?: typeof data };
      expect(raw.data?.item.description).toBe("x".repeat(20_000));
      expect(raw.data?.spec.kind).toBe("AipodSpec");
      expect(requests).toBe(5);
    } finally {
      server.stop(true);
      if (previousConfig === undefined) delete process.env.AGENTRUN_CLIENT_CONFIG;
      else process.env.AGENTRUN_CLIENT_CONFIG = previousConfig;
      if (previousKey === undefined) delete process.env.HWLAB_API_KEY;
      else process.env.HWLAB_API_KEY = previousKey;
      rmSync(tempConfigPath, { force: true });
    }
  });

  test("retry dry-run is server-validated and attempts use the formal resource API", async () => {
    const taskId = "qt_failed_1";
    const attempt = {
      attemptId: "qat_retry_1",
      taskId,
      retryIndex: 1,
      state: "reserved",
      idempotencyKey: "retry-key-1",
      reason: "dependency repaired",
      payloadHash: "sha256:payload",
      previousAttemptId: "qat_initial_0",
      runId: "run_retry_1",
      commandId: "cmd_retry_1",
      runnerJobId: "rjob_retry_1",
      sessionId: "ses_retry_1",
      sessionPath: "/api/v1/sessions/ses_retry_1",
      failureKind: "infra-failed",
      failureMessage: "kubectl create runner job failed before materialization",
      createdAt: "2026-07-12T00:00:00.000Z",
      updatedAt: "2026-07-12T00:00:01.000Z",
      activatedAt: "2026-07-12T00:00:01.000Z",
      terminalAt: null,
    };
    let retryRequests = 0;
    let attemptRequests = 0;
    const server = Bun.serve({
      port: 0,
      async fetch(request) {
        const url = new URL(request.url);
        expect(request.headers.get("authorization")).toBe("Bearer secret-value");
        if (url.pathname === `/api/v1/queue/tasks/${taskId}/retry`) {
          retryRequests += 1;
          expect(request.method).toBe("POST");
          expect(await request.json()).toEqual({
            idempotencyKey: "retry-key-1",
            reason: "dependency repaired",
            dryRun: true,
          });
          return Response.json({
            ok: true,
            data: {
              action: "queue-retry",
              mutation: false,
              idempotentReplay: false,
              task: { id: taskId, state: "failed", queue: "commander", payloadHash: "sha256:payload" },
              attempt: null,
              previousAttempt: { ...attempt, attemptId: "qat_initial_0", retryIndex: 0, state: "failed", previousAttemptId: null },
              run: null,
              command: null,
              runnerJob: null,
              allowedTransition: { from: "failed", to: "running", retryIndex: 1, previousAttemptId: "qat_initial_0", payloadHash: "sha256:payload", valuesPrinted: false },
              pollActions: [],
            },
          });
        }
        if (url.pathname === `/api/v1/queue/tasks/${taskId}/attempts`) {
          attemptRequests += 1;
          expect(request.method).toBe("GET");
          expect(url.searchParams.get("cursor")).toBe("1");
          expect(url.searchParams.get("limit")).toBe("10");
          return Response.json({ ok: true, data: { taskId, items: [attempt], count: 1, cursor: null } });
        }
        return new Response("not found", { status: 404 });
      },
    });
    const previousConfig = process.env.AGENTRUN_CLIENT_CONFIG;
    const previousKey = process.env.HWLAB_API_KEY;
    process.env.HWLAB_API_KEY = "secret-value";
    const tempConfigPath = `/tmp/unidesk-agentrun-retry-test-${process.pid}-${Date.now()}.yaml`;
    try {
      process.env.AGENTRUN_CLIENT_CONFIG = tempConfigPath;
      await Bun.write(tempConfigPath, agentRunMinimalClientYaml.replace("http://agentrun.example.local:8080", server.url.href.replace(/\/$/u, "")));
      const retryResult = await runAgentRunCommand(null, ["retry", `task/${taskId}`, "--idempotency-key", "retry-key-1", "--reason", "dependency repaired", "--dry-run"]);
      expect(retryResult.ok).toBe(true);
      expect("renderedText" in retryResult).toBe(true);
      if ("renderedText" in retryResult) {
        expect(retryResult.renderedText).toContain(`Task retry validated: task/${taskId}`);
        expect(retryResult.renderedText).toContain("Transition: failed -> running retryIndex=1");
        expect(retryResult.renderedText).toContain("Attempt: planned");
      }

      const attemptsResult = await runAgentRunCommand(null, ["get", "attempts", "--task", taskId, "--cursor", "1", "--limit", "10", "-o", "json"]);
      expect(attemptsResult.ok).toBe(true);
      expect("renderedText" in attemptsResult).toBe(true);
      if ("renderedText" in attemptsResult && typeof attemptsResult.renderedText === "string") {
        const payload = JSON.parse(attemptsResult.renderedText) as { kind?: string; taskId?: string; count?: number; items?: Array<Record<string, unknown>> };
        expect(payload.kind).toBe("AttemptList");
        expect(payload.taskId).toBe(taskId);
        expect(payload.count).toBe(1);
        expect(payload.items?.[0]?.name).toBe(attempt.attemptId);
        expect(payload.items?.[0]?.retryIndex).toBe(1);
        expect(payload.items?.[0]?.failureMessage).toBe(attempt.failureMessage);
      }

      const attemptsHumanResult = await runAgentRunCommand(null, ["get", "attempts", "--task", taskId, "--cursor", "1", "--limit", "10"]);
      expect("renderedText" in attemptsHumanResult ? attemptsHumanResult.renderedText : "").toContain("infra-failed: kubectl create runner job failed before materialization");
      expect(retryRequests).toBe(1);
      expect(attemptRequests).toBe(2);
    } finally {
      server.stop(true);
      if (previousConfig === undefined) delete process.env.AGENTRUN_CLIENT_CONFIG;
      else process.env.AGENTRUN_CLIENT_CONFIG = previousConfig;
      if (previousKey === undefined) delete process.env.HWLAB_API_KEY;
      else process.env.HWLAB_API_KEY = previousKey;
      rmSync(tempConfigPath, { force: true });
    }
  });

  test("retry and attempt resource help stays scoped to the controlled commands", async () => {
    const retryHelp = await runAgentRunCommand(null, ["retry", "--help"]);
    const attemptHelp = await runAgentRunCommand(null, ["get", "attempts", "--help"]);
    const describeHelp = await runAgentRunCommand(null, ["describe", "--help"]);
    expect("renderedText" in retryHelp ? retryHelp.renderedText : "").toContain("agentrun retry task/<taskId> --idempotency-key <key> --reason <text>");
    expect("renderedText" in attemptHelp ? attemptHelp.renderedText : "").toContain("agentrun get attempts --task <taskId>");
    expect("renderedText" in describeHelp ? describeHelp.renderedText : "").toContain("agentrun describe task/qt_... --input -o json");

    const rootHelp = Bun.spawnSync(["bun", "scripts/cli.ts", "agentrun", "--help"], {
      cwd: new URL("../..", import.meta.url).pathname,
      stdout: "pipe",
      stderr: "pipe",
    });
    const rootHelpText = rootHelp.stdout.toString();
    expect(rootHelp.exitCode).toBe(0);
    expect(rootHelpText).toContain("Verbs: get, describe, events, logs, result, ack, cancel, retry,");
    expect(rootHelpText).toContain("Resources: task/qt, attempt, run,");
    expect(rootHelpText).toContain("agentrun retry task/<taskId> --idempotency-key <key> --reason <text> --dry-run");
    expect(rootHelpText).toContain("agentrun get attempts --task <taskId> --limit 20");
    expect(rootHelpText.split("\n").length).toBeLessThan(40);
  });

  test("local resource validation preserves bounded human and machine errors", async () => {
    const cases = [
      {
        args: ["retry", "task/qt_failed_1", "--reason", "dependency repaired"],
        message: "retry requires --idempotency-key <key>",
      },
      {
        args: ["retry", "task/qt_failed_1", "--idempotency-key", "retry-key-1"],
        message: "retry requires --reason <text>",
      },
      {
        args: ["get", "attempts"],
        message: "get attempts requires --task <taskId>",
      },
      {
        args: ["retry", "run/run_invalid", "--idempotency-key", "retry-key-1", "--reason", "dependency repaired"],
        message: "retry supports task/<taskId>",
      },
      {
        args: ["retry"],
        message: "retry requires task/<taskId>",
      },
    ];
    for (const item of cases) {
      const human = await runAgentRunCommand(null, item.args);
      const humanText = renderedTextOf(human);
      expect(human.ok).toBe(false);
      expect(humanText).toContain("Error: validation-failed");
      expect(humanText).toContain(item.message);
      expect(humanText.length).toBeLessThan(1600);

      for (const outputArgs of [["-o", "json"], ["--raw"]]) {
        const machine = await runAgentRunCommand(null, [...item.args, ...outputArgs]);
        const machineText = renderedTextOf(machine);
        const payload = JSON.parse(machineText) as { ok?: boolean; failureKind?: string; message?: string };
        expect(machine.ok).toBe(false);
        expect(renderedContentTypeOf(machine)).toBe("application/json");
        expect(payload.ok).toBe(false);
        expect(payload.failureKind).toBe("validation-failed");
        expect(payload.message).toBe(item.message);
        expect(machineText.length).toBeLessThan(2400);
      }
    }

    for (const cliArgs of [
      ["retry", "run/run_invalid", "--idempotency-key", "retry-key-1", "--reason", "dependency repaired", "-o", "json"],
      ["get", "attempts", "--raw"],
      ["describe", "task/qt_sensitive", "--input", "--full", "-o", "json"],
      ["describe", "task/qt_sensitive", "--input", "--raw"],
    ]) {
      const cli = Bun.spawnSync(["bun", "scripts/cli.ts", "agentrun", ...cliArgs], {
        cwd: new URL("../..", import.meta.url).pathname,
        stdout: "pipe",
        stderr: "pipe",
      });
      const payload = JSON.parse(cli.stdout.toString()) as { ok?: boolean; failureKind?: string };
      expect(cli.exitCode).toBe(1);
      expect(payload.ok).toBe(false);
      expect(payload.failureKind).toBe("validation-failed");
      expect(cli.stdout.toString().length).toBeLessThan(2400);
      expect(cli.stdout.toString()).not.toContain('"resource":');
      expect(cli.stdout.toString()).not.toContain('"data":');
    }
  });

  test("server retry validation errors stay bounded in human and JSON output", async () => {
    const taskId = "qt_completed_1";
    const longMessage = `queue task ${taskId} cannot be retried from state completed: ${"x".repeat(6000)}`;
    const longDiagnostic = `server diagnostic: ${"y".repeat(9000)}`;
    let requests = 0;
    const server = Bun.serve({
      port: 0,
      async fetch(request) {
        const url = new URL(request.url);
        expect(url.pathname).toBe(`/api/v1/queue/tasks/${taskId}/retry`);
        expect(request.method).toBe("POST");
        expect(await request.json()).toEqual({ idempotencyKey: "retry-key-terminal", reason: "operator requested retry", dryRun: true });
        requests += 1;
        return Response.json({
          ok: false,
          failureKind: "schema-invalid",
          message: longMessage,
          details: { allowedStates: ["failed", "blocked"], diagnostic: longDiagnostic, valuesPrinted: false },
          valuesPrinted: false,
        }, { status: 409 });
      },
    });
    const previousConfig = process.env.AGENTRUN_CLIENT_CONFIG;
    const previousKey = process.env.HWLAB_API_KEY;
    process.env.HWLAB_API_KEY = "secret-value";
    const tempConfigPath = `/tmp/unidesk-agentrun-retry-error-test-${process.pid}-${Date.now()}.yaml`;
    try {
      process.env.AGENTRUN_CLIENT_CONFIG = tempConfigPath;
      await Bun.write(tempConfigPath, agentRunMinimalClientYaml.replace("http://agentrun.example.local:8080", server.url.href.replace(/\/$/u, "")));
      const baseArgs = ["retry", `task/${taskId}`, "--idempotency-key", "retry-key-terminal", "--reason", "operator requested retry", "--dry-run"];
      const human = await runAgentRunCommand(null, baseArgs);
      const humanText = renderedTextOf(human);
      expect(human.ok).toBe(false);
      expect(humanText).toContain(`queue task ${taskId} cannot be retried from state completed`);
      expect(humanText).not.toContain("x".repeat(500));
      expect(humanText.length).toBeLessThan(1800);

      const json = await runAgentRunCommand(null, [...baseArgs, "-o", "json"]);
      const jsonText = renderedTextOf(json);
      const payload = JSON.parse(jsonText) as { ok?: boolean; failureKind?: string; message?: string; agentrun?: { details?: { diagnostic?: string } } };
      expect(json.ok).toBe(false);
      expect(renderedContentTypeOf(json)).toBe("application/json");
      expect(payload.failureKind).toBe("validation-failed");
      expect(payload.message?.length).toBeLessThanOrEqual(400);
      expect(payload.agentrun?.details?.diagnostic?.length).toBeLessThanOrEqual(400);
      expect(jsonText.length).toBeLessThan(5000);
      expect(requests).toBe(2);
    } finally {
      server.stop(true);
      if (previousConfig === undefined) delete process.env.AGENTRUN_CLIENT_CONFIG;
      else process.env.AGENTRUN_CLIENT_CONFIG = previousConfig;
      if (previousKey === undefined) delete process.env.HWLAB_API_KEY;
      else process.env.HWLAB_API_KEY = previousKey;
      rmSync(tempConfigPath, { force: true });
    }
  });

  test("session send plan and typed partial-write errors stay homologous and bounded", async () => {
    const sessionId = "sess_artificer_fixture";
    const runId = "run_partial_fixture";
    const commandId = "cmd_partial_fixture";
    const hiddenKubernetesPayload = "HIDDEN_KUBERNETES_PAYLOAD_MUST_NOT_BE_PRINTED";
    let postRequests = 0;
    const server = Bun.serve({
      port: 0,
      async fetch(request) {
        const url = new URL(request.url);
        expect(request.headers.get("authorization")).toBe("Bearer secret-value");
        if (request.method === "GET" && url.pathname === `/api/v1/sessions/${sessionId}`) {
          return Response.json({
            ok: true,
            data: {
              sessionId,
              tenantId: "unidesk",
              projectId: "test",
              providerId: "NC01",
              backendProfile: "codex",
              conversationId: sessionId,
              metadata: { title: "Artificer fixture" },
            },
          });
        }
        if (request.method === "POST" && url.pathname === `/api/v1/sessions/${sessionId}/send`) {
          postRequests += 1;
          const body = await request.json() as Record<string, any>;
          if (body.payload?.prompt === "plan fixture") {
            expect(body.dryRun).toBe(true);
            return Response.json({
              ok: true,
              data: {
                action: "session-send-plan",
                dryRun: true,
                mutation: false,
                sessionId,
                decision: "turn",
                internalCommandType: "turn",
                activeBefore: null,
                reusedIdleRun: null,
                request: { method: "POST", path: `/api/v1/sessions/${sessionId}/send`, commandType: "turn", createRunnerJob: true, valuesPrinted: false },
                next: {
                  confirm: { action: "send-session", operation: "send", resourceKind: "session", resourceName: sessionId, sessionId, inputKind: "prompt", valuesPrinted: false },
                  note: "Remove --dry-run to perform the mutation.",
                },
                valuesPrinted: false,
              },
            });
          }
          return Response.json({
            ok: false,
            failureKind: "infra-failed",
            message: "kubectl get jobs failed with code 1",
            traceId: "trc_session_send_fixture",
            error: {
              name: "AgentRunError",
              failureKind: "infra-failed",
              message: "kubectl get jobs failed with code 1",
              details: {
                code: "runner-admission-failed",
                reason: "runner-retention-observation-failed",
                phase: "runner-admission",
                sessionId,
                runId,
                commandId,
                mutation: true,
                partialWrite: true,
                durable: true,
                resources: {
                  session: { id: sessionId, state: "running" },
                  run: { id: runId, status: "queued" },
                  command: { id: commandId, state: "pending", type: "turn" },
                },
                recoveryActions: [
                  { operation: "describe", resourceKind: "session", resourceName: sessionId },
                  { operation: "events", resourceKind: "run", resourceName: runId, runId, afterSeq: 0, limit: 100 },
                ],
                stderr: hiddenKubernetesPayload,
                rawKubernetesObject: { secret: hiddenKubernetesPayload },
                valuesPrinted: false,
              },
            },
          }, { status: 502 });
        }
        return new Response("not found", { status: 404 });
      },
    });
    const previousConfig = process.env.AGENTRUN_CLIENT_CONFIG;
    const previousKey = process.env.HWLAB_API_KEY;
    process.env.HWLAB_API_KEY = "secret-value";
    const tempConfigPath = `/tmp/unidesk-agentrun-session-send-test-${process.pid}-${Date.now()}.yaml`;
    try {
      process.env.AGENTRUN_CLIENT_CONFIG = tempConfigPath;
      await Bun.write(tempConfigPath, agentRunMinimalClientYaml.replace("http://agentrun.example.local:8080", server.url.href.replace(/\/$/u, "")));

      const planArgs = ["send", `session/${sessionId}`, "--prompt", "plan fixture", "--dry-run"];
      const planHuman = renderedTextOf(await runAgentRunCommand(null, planArgs));
      expect(planHuman).toContain("Session send plan");
      expect(planHuman).toContain("Decision: turn");
      expect(planHuman).toContain("ReuseRun: false");
      expect(planHuman).toContain("CreateRunner: true");
      expect(planHuman).toContain("Mutation: false");
      expect(planHuman).not.toContain("[object Object]");
      const planJsonText = renderedTextOf(await runAgentRunCommand(null, [...planArgs, "-o", "json"]));
      const planYamlText = renderedTextOf(await runAgentRunCommand(null, [...planArgs, "-o", "yaml"]));
      const planJson = JSON.parse(planJsonText) as Record<string, any>;
      const planYaml = Bun.YAML.parse(planYamlText) as Record<string, any>;
      expect(planYaml).toEqual(planJson);
      expect(planJson).toMatchObject({ kind: "SessionSendPlan", decision: "turn", dryRun: true, mutation: false, partialWrite: false, reuseRun: false, createRunner: true });
      expect(planJson.resources.session).toEqual({ kind: "session", id: sessionId });
      expect(planJson.next.actions[0]).toMatchObject({ mutation: true });
      expect(planJson.next.actions[0].command).not.toContain("--dry-run");

      const failureArgs = ["send", `session/${sessionId}`, "--prompt", "failure fixture"];
      const failureHumanResult = await runAgentRunCommand(null, failureArgs);
      const failureHuman = renderedTextOf(failureHumanResult);
      expect(failureHumanResult.ok).toBe(false);
      expect(failureHuman).toContain("Session send failed");
      expect(failureHuman).toContain("Error: validation-failed");
      expect(failureHuman).toContain("TypedFailure: infra-failed");
      expect(failureHuman).toContain("Code: runner-admission-failed");
      expect(failureHuman).toContain("Reason: runner-retention-observation-failed");
      expect(failureHuman).toContain("Mutation: true");
      expect(failureHuman).toContain("PartialWrite: true");
      expect(failureHuman).toContain(`session/${sessionId} state=running`);
      expect(failureHuman).toContain(`run/${runId} status=queued`);
      expect(failureHuman).toContain(`command/${commandId} state=pending type=turn`);
      expect(failureHuman).not.toContain(hiddenKubernetesPayload);
      expect(failureHuman).not.toContain("agentrun send");

      const failureJsonResult = await runAgentRunCommand(null, [...failureArgs, "-o", "json"]);
      const failureYamlResult = await runAgentRunCommand(null, [...failureArgs, "-o", "yaml"]);
      const failureJsonText = renderedTextOf(failureJsonResult);
      const failureYamlText = renderedTextOf(failureYamlResult);
      const failureJson = JSON.parse(failureJsonText) as Record<string, any>;
      const failureYaml = Bun.YAML.parse(failureYamlText) as Record<string, any>;
      expect(failureJsonResult.ok).toBe(false);
      expect(failureYamlResult.ok).toBe(false);
      expect(failureYaml).toEqual(failureJson);
      expect(failureJson).toMatchObject({
        kind: "SessionSendError",
        mutation: true,
        partialWrite: true,
        error: {
          failureKind: "validation-failed",
          typedFailureKind: "infra-failed",
          code: "runner-admission-failed",
          reason: "runner-retention-observation-failed",
          traceId: "trc_session_send_fixture",
        },
      });
      for (const bounded of [planHuman, planJsonText, planYamlText, failureHuman, failureJsonText, failureYamlText]) {
        expect(Buffer.byteLength(bounded, "utf8")).toBeLessThan(7000);
        expect(bounded).not.toContain(hiddenKubernetesPayload);
        expect(bounded).not.toContain("rawKubernetesObject");
      }
      expect(postRequests).toBe(6);
    } finally {
      server.stop(true);
      if (previousConfig === undefined) delete process.env.AGENTRUN_CLIENT_CONFIG;
      else process.env.AGENTRUN_CLIENT_CONFIG = previousConfig;
      if (previousKey === undefined) delete process.env.HWLAB_API_KEY;
      else process.env.HWLAB_API_KEY = previousKey;
      rmSync(tempConfigPath, { force: true });
    }
  });

  test("Aipod follow-up inherits cancelled durable session identity and keeps boundary conflicts fail-closed", async () => {
    const sessionId = "sess_artificer_cancelled_selfmedia";
    const durableSession = {
      sessionId,
      tenantId: "unidesk",
      projectId: "pikainc/selfmedia",
      providerId: "NC01",
      backendProfile: "codex",
      conversationId: "conv_selfmedia",
      threadId: "thread_selfmedia",
      metadata: { lastTurnId: "turn_cancelled", durable: true },
      executionState: "terminal",
      terminalStatus: "cancelled",
      failureKind: "cancelled",
    };
    const renderBodies: Record<string, any>[] = [];
    const sendBodies: Record<string, any>[] = [];
    let sessionReads = 0;
    const server = Bun.serve({
      port: 0,
      async fetch(request) {
        const url = new URL(request.url);
        expect(request.headers.get("authorization")).toBe("Bearer secret-value");
        if (request.method === "GET" && url.pathname === `/api/v1/sessions/${sessionId}`) {
          sessionReads += 1;
          return Response.json({ ok: true, data: durableSession });
        }
        if (request.method === "POST" && url.pathname === "/api/v1/aipod-specs/Artificer/render") {
          const body = await request.json() as Record<string, any>;
          renderBodies.push(body);
          return Response.json({
            ok: true,
            data: {
              queueTask: {
                tenantId: body.tenantId ?? "unidesk",
                projectId: body.projectId ?? "default",
                queue: "commander",
                lane: "v0.2",
                title: "Artificer cancelled continuation",
                backendProfile: "codex",
                providerId: "NC01",
                workspaceRef: { kind: "opaque", path: "." },
                sessionRef: body.sessionRef ?? { sessionId },
                executionPolicy: {
                  sandbox: "workspace-write",
                  approval: "never",
                  timeoutMs: 1_800_000,
                  network: "enabled",
                  secretScope: {
                    allowCredentialEcho: false,
                    providerCredentials: [{
                      profile: "codex",
                      secretRef: { name: "agentrun-v01-provider-codex", keys: ["auth.json", "config.toml"] },
                    }],
                  },
                },
                resourceBundleRef: null,
                payload: { prompt: body.prompt },
              },
              dispatchDefaults: { runnerJob: {} },
            },
          });
        }
        if (request.method === "POST" && url.pathname === `/api/v1/sessions/${sessionId}/send`) {
          const body = await request.json() as Record<string, any>;
          sendBodies.push(body);
          if (body.run?.tenantId !== durableSession.tenantId || body.run?.projectId !== durableSession.projectId) {
            return Response.json({
              ok: false,
              failureKind: "tenant-policy-denied",
              message: "sessionRef cannot be reused across tenant or project boundary",
              details: { sessionId, valuesPrinted: false },
            }, { status: 403 });
          }
          return Response.json({
            ok: true,
            data: {
              action: "session-send-plan",
              dryRun: true,
              mutation: false,
              sessionId,
              decision: "turn",
              internalCommandType: "turn",
              activeBefore: null,
              request: { method: "POST", path: `/api/v1/sessions/${sessionId}/send`, commandType: "turn", createRunnerJob: true, valuesPrinted: false },
              next: { confirm: { action: "send-session", operation: "send", resourceKind: "session", resourceName: sessionId } },
              valuesPrinted: false,
            },
          });
        }
        return new Response("not found", { status: 404 });
      },
    });
    const previousConfig = process.env.AGENTRUN_CLIENT_CONFIG;
    const previousKey = process.env.HWLAB_API_KEY;
    process.env.HWLAB_API_KEY = "secret-value";
    const tempConfigPath = `/tmp/unidesk-agentrun-cancelled-session-test-${process.pid}-${Date.now()}.yaml`;
    try {
      process.env.AGENTRUN_CLIENT_CONFIG = tempConfigPath;
      await Bun.write(tempConfigPath, agentRunMinimalClientYaml.replace("http://agentrun.example.local:8080", server.url.href.replace(/\/$/u, "")));

      const continued = await runAgentRunCommand(null, [
        "send",
        `session/${sessionId}`,
        "--aipod",
        "Artificer",
        "--prompt",
        "continue cancelled selfmedia task",
        "--dry-run",
        "-o",
        "json",
      ]);
      expect(continued.ok).toBe(true);
      expect(JSON.parse(renderedTextOf(continued))).toMatchObject({
        kind: "SessionSendPlan",
        decision: "turn",
        dryRun: true,
        mutation: false,
      });
      expect(sessionReads).toBe(1);
      expect(renderBodies).toHaveLength(1);
      expect(renderBodies[0]).toMatchObject({
        tenantId: durableSession.tenantId,
        projectId: durableSession.projectId,
        sessionId,
        sessionRef: {
          sessionId,
          conversationId: durableSession.conversationId,
          threadId: durableSession.threadId,
          metadata: durableSession.metadata,
        },
      });
      expect(sendBodies).toHaveLength(1);
      expect(sendBodies[0]?.run).toMatchObject({
        tenantId: durableSession.tenantId,
        projectId: durableSession.projectId,
        sessionRef: {
          sessionId,
          conversationId: durableSession.conversationId,
          threadId: durableSession.threadId,
          metadata: durableSession.metadata,
        },
      });

      const conflict = await runAgentRunCommand(null, [
        "send",
        `session/${sessionId}`,
        "--aipod",
        "Artificer",
        "--project-id",
        "pikasTech/unidesk",
        "--prompt",
        "must stay fail closed",
        "--dry-run",
        "-o",
        "json",
      ]);
      expect(conflict.ok).toBe(false);
      expect(renderedTextOf(conflict)).toContain("tenant-policy-denied");
      expect(sessionReads).toBe(2);
      expect(renderBodies).toHaveLength(1);
      expect(sendBodies).toHaveLength(1);
    } finally {
      server.stop(true);
      if (previousConfig === undefined) delete process.env.AGENTRUN_CLIENT_CONFIG;
      else process.env.AGENTRUN_CLIENT_CONFIG = previousConfig;
      if (previousKey === undefined) delete process.env.HWLAB_API_KEY;
      else process.env.HWLAB_API_KEY = previousKey;
      rmSync(tempConfigPath, { force: true });
    }
  });
});

describe("AgentRun YAML tool credential binding", () => {
  test("aggregates managed GitHub SSH source keys into one volume credential and one sync target", () => {
    const { spec } = resolveAgentRunLaneTarget({ node: "NC01", lane: "nc01-v02" });
    const githubSsh = agentRunToolCredentialRefs(spec).filter((credential) => credential.tool === "github" && credential.purpose === "github-ssh");
    expect(githubSsh).toEqual([{
      sourceId: "github-ssh",
      tool: "github",
      purpose: "github-ssh",
      secretRef: {
        namespace: "agentrun-v02",
        name: "agentrun-v01-tool-github-ssh",
        keys: ["id_ed25519", "known_hosts"],
      },
      projection: { kind: "volume", mountPath: "/home/agentrun/.ssh" },
      valuesPrinted: false,
    }]);

    const sources = collectLaneSecretSources(spec).filter((source) => source.targetRef.name === "agentrun-v01-tool-github-ssh");
    expect(sources.map((source) => ({ id: source.id, sourceMode: source.sourceMode, sourceRef: source.sourceRef, targetRef: source.targetRef }))).toEqual([
      {
        id: "tool-github-ssh-private-key",
        sourceMode: "file",
        sourceRef: "deploy-ssh/github.com/id_ed25519",
        targetRef: { namespace: "agentrun-v02", name: "agentrun-v01-tool-github-ssh", key: "id_ed25519" },
      },
      {
        id: "tool-github-ssh-known-hosts",
        sourceMode: "file",
        sourceRef: "deploy-ssh/github.com/known_hosts",
        targetRef: { namespace: "agentrun-v02", name: "agentrun-v01-tool-github-ssh", key: "known_hosts" },
      },
    ]);
    const syncScript = secretSyncScript(spec, sources.map((source, index) => ({ targetRef: source.targetRef, value: `fixture-${index}` })));
    const payloadMatch = syncScript.match(/^payload_b64='([^']+)'$/mu);
    expect(payloadMatch).not.toBeNull();
    const syncManifest = JSON.parse(Buffer.from(payloadMatch?.[1] ?? "", "base64").toString("utf8")) as Array<{ targetRef: { namespace: string; name: string; key: string } }>;
    expect(syncManifest.map((item) => item.targetRef)).toEqual(sources.map((source) => source.targetRef));
    expect(new Set(syncManifest.map((item) => `${item.targetRef.namespace}/${item.targetRef.name}`))).toEqual(new Set(["agentrun-v02/agentrun-v01-tool-github-ssh"]));
    expect(syncScript).toContain("groups.setdefault(key");
    expect(JSON.stringify({ githubSsh, sources })).not.toContain("/root/.ssh");
  });

  test("preserves explicit credential subsets across Aipod admission and rejects unknown identities or conflicts", async () => {
    const renderBodies: Record<string, any>[] = [];
    const submittedBodies: Record<string, any>[] = [];
    const taskTitle = "验证 Artificer 工具凭据";
    let credentialMode: "all" | "subset" | "conflict" | "unknown" = "all";
    const renderedToolCredentials = (): Record<string, unknown>[] => {
      const credentials = [
        {
          tool: "github",
          purpose: "github-pr",
          secretRef: { name: "agentrun-release-tool-github-pr", keys: ["GH_TOKEN"] },
          projection: { kind: "env", envName: "GH_TOKEN", secretKey: "GH_TOKEN" },
        },
        {
          tool: "unidesk-ssh",
          purpose: "ssh-passthrough",
          secretRef: { name: "agentrun-release-tool-unidesk-ssh", keys: ["UNIDESK_SSH_CLIENT_TOKEN"] },
          projection: { kind: "env", envName: "UNIDESK_SSH_CLIENT_TOKEN", secretKey: "UNIDESK_SSH_CLIENT_TOKEN" },
        },
        {
          tool: "github",
          purpose: "github-ssh",
          secretRef: {
            name: "agentrun-release-tool-github-ssh",
            keys: credentialMode === "conflict" ? ["id_ed25519", "known_hosts", "config"] : ["id_ed25519", "known_hosts"],
          },
          projection: { kind: "volume", mountPath: "/home/agentrun/.ssh" },
        },
      ];
      if (credentialMode === "subset") return credentials.slice(0, 1);
      if (credentialMode === "unknown") {
        return [{
          tool: "artifact-store",
          purpose: "publish",
          secretRef: { name: "agentrun-artifact-store", keys: ["TOKEN"] },
          projection: { kind: "env", envName: "ARTIFACT_TOKEN", secretKey: "TOKEN" },
        }];
      }
      return credentials;
    };
    const renderedTask = () => ({
      title: taskTitle,
      metadata: { title: taskTitle },
      sessionRef: { metadata: { title: taskTitle } },
      tenantId: "unidesk",
      projectId: "pikasTech/unidesk",
      queue: "commander",
      lane: "v0.1",
      backendProfile: "codex",
      providerId: "NC01",
      workspaceRef: { kind: "opaque", path: "." },
      executionPolicy: {
        sandbox: "workspace-write",
        approval: "never",
        timeoutMs: 1_800_000,
        network: "enabled",
        secretScope: {
          allowCredentialEcho: false,
          providerCredentials: [{
            profile: "codex",
            secretRef: { name: "agentrun-release-provider-codex", keys: ["auth.json", "config.toml"] },
          }],
          toolCredentials: renderedToolCredentials(),
        },
      },
      payload: { prompt: "fixture" },
    });
    const server = Bun.serve({
      port: 0,
      async fetch(request) {
        const url = new URL(request.url);
        expect(request.headers.get("authorization")).toBe("Bearer secret-value");
        if (url.pathname === "/api/v1/aipod-specs/Artificer/render") {
          renderBodies.push(await request.json() as Record<string, any>);
          return Response.json({ ok: true, data: { queueTask: renderedTask() } });
        }
        if (url.pathname === "/api/v1/queue/tasks") {
          submittedBodies.push(await request.json() as Record<string, any>);
          return Response.json({ ok: true, data: { id: "qt_fixture", state: "queued" } });
        }
        return new Response("not found", { status: 404 });
      },
    });
    const previousConfig = process.env.AGENTRUN_CLIENT_CONFIG;
    const previousKey = process.env.HWLAB_API_KEY;
    process.env.HWLAB_API_KEY = "secret-value";
    const tempConfigPath = `/tmp/unidesk-agentrun-tool-credential-test-${process.pid}-${Date.now()}.yaml`;
    try {
      process.env.AGENTRUN_CLIENT_CONFIG = tempConfigPath;
      await Bun.write(tempConfigPath, agentRunMinimalClientYaml.replace("http://agentrun.example.local:8080", server.url.href.replace(/\/$/u, "")));

      const accepted = await runAgentRunCommand(null, ["create", "task", "--aipod", "Artificer", "--title", taskTitle, "--prompt", "fixture", "--model", "gpt-explicit", "--reasoning-effort", "high", "-o", "json"]);
      expect(accepted.ok).toBe(true);
      expect(renderBodies).toHaveLength(1);
      expect(submittedBodies).toHaveLength(1);
      expect(renderBodies[0]?.backendProfile).toBeUndefined();
      expect(renderBodies[0]?.executionPolicy).toBeUndefined();
      expect(renderBodies[0]?.model).toBe("gpt-explicit");
      expect(renderBodies[0]?.reasoningEffort).toBe("high");
      expect(submittedBodies[0]).toEqual(renderedTask());

      credentialMode = "subset";
      const subsetAccepted = await runAgentRunCommand(null, ["create", "task", "--aipod", "Artificer", "--title", taskTitle, "--prompt", "fixture", "-o", "json"]);
      expect(subsetAccepted.ok).toBe(true);
      expect(renderBodies).toHaveLength(2);
      expect(submittedBodies).toHaveLength(2);
      expect(submittedBodies[1]).toEqual(renderedTask());

      credentialMode = "conflict";
      const rejected = await runAgentRunCommand(null, ["create", "task", "--aipod", "Artificer", "--title", taskTitle, "--prompt", "fixture", "-o", "json"]);
      expect(rejected.ok).toBe(false);
      expect(submittedBodies).toHaveLength(2);
      expect(renderedTextOf(rejected)).toContain("github/github-ssh keys conflict");

      credentialMode = "unknown";
      const unknownRejected = await runAgentRunCommand(null, ["create", "task", "--aipod", "Artificer", "--title", taskTitle, "--prompt", "fixture", "-o", "json"]);
      expect(unknownRejected.ok).toBe(false);
      expect(submittedBodies).toHaveLength(2);
      expect(renderedTextOf(unknownRejected)).toContain("artifact-store/publish is not declared by YAML lane");
    } finally {
      server.stop(true);
      if (previousConfig === undefined) delete process.env.AGENTRUN_CLIENT_CONFIG;
      else process.env.AGENTRUN_CLIENT_CONFIG = previousConfig;
      if (previousKey === undefined) delete process.env.HWLAB_API_KEY;
      else process.env.HWLAB_API_KEY = previousKey;
      rmSync(tempConfigPath, { force: true });
    }
  });
});

describe("AgentRun runner API key SecretRef", () => {
  test("renders manager runtime authority from the YAML runner SecretRef", () => {
    const { spec } = resolveAgentRunLaneTarget({ node: "NC01", lane: "nc01-v02" });
    const files = renderAgentRunGitopsFiles(spec, { sourceCommit: "a".repeat(40), image: placeholderAgentRunImage(spec, "a".repeat(40)) });
    const managerFile = files.find((file) => file.path.endsWith("/mgr.yaml"));
    expect(managerFile).toBeDefined();
    const resources = (managerFile?.content ?? "").split(/\n---\n/u).map((document) => Bun.YAML.parse(document) as Record<string, unknown>);
    const deployment = resources.find((resource) => resource.kind === "Deployment") as { spec?: { template?: { spec?: { containers?: Array<{ env?: Array<{ name?: string; value?: string }> }> } } } } | undefined;
    const env = deployment?.spec?.template?.spec?.containers?.[0]?.env ?? [];
    const values = new Map(env.map((item) => [item.name, item.value]));
    expect(values.get("AGENTRUN_RUNNER_API_KEY_SECRET_NAME")).toBe(spec.deployment.runner.apiKeySecretRef.name);
    expect(values.get("AGENTRUN_RUNNER_API_KEY_SECRET_KEY")).toBe(spec.deployment.runner.apiKeySecretRef.key);
    expect(values.get("AGENTRUN_RUNNER_STARTUP_RETRY_JITTER_RATIO")).toBe("0.2");
    expect(env.filter((item) => item.value !== undefined).every((item) => typeof item.value === "string")).toBe(true);
    expect(spec.secrets.some((secret) => secret.targetRef.name === "agentrun-v01-api-key")).toBe(false);
  });
});
