// Ci Node Test Plan tests cover ci node test plan script behavior.
import { existsSync, globSync, readdirSync } from "node:fs";
import { isAbsolute, join, relative, resolve } from "node:path";
import { describe, expect, it } from "vitest";
import {
  assignVitestFsCacheWriter,
  createNodeTestShardBundles,
  createNodeTestShards,
  createVitestCacheWarmGroups,
  resolvePolicyTestTargets,
  type NodeTestShard,
} from "../../scripts/lib/ci-node-test-plan.mts";
import { expectNoNodeFsScans } from "../../src/test-utils/fs-scan-assertions.js";
import { listGitTrackedFiles, sortRepoPaths, toRepoPath } from "../../src/test-utils/repo-files.js";
import {
  agentVitestProjectOwners,
  embeddedAgentVitestProjectOwners,
} from "../vitest/vitest.agents-paths.mjs";
import { commandsLightTestFiles } from "../vitest/vitest.commands-light-paths.mjs";
import { isGatewayServerTestFile } from "../vitest/vitest.gateway-server-paths.mjs";
import { createGatewayServerVitestConfig } from "../vitest/vitest.gateway-server.config.ts";
import { createPluginsVitestConfig } from "../vitest/vitest.plugins.config.ts";
import { createToolingVitestConfig } from "../vitest/vitest.tooling.config.ts";

type VitestTestConfig = {
  dir?: string;
  exclude?: string[];
  include?: string[];
};

type VitestConfig = {
  test?: VitestTestConfig;
};

const PLUGIN_PRERELEASE_NPM_SPEC_TEST = "src/plugins/install.npm-spec.test.ts";
const PLUGIN_NPM_INSTALL_SECURITY_SCAN_TEST =
  "src/plugins/npm-install-security-scan.release.test.ts";
const DEFAULT_NODE_TEST_RUNNER = "blacksmith-8vcpu-ubuntu-2404";
const BUNDLED_NODE_TEST_RUNNER = "blacksmith-4vcpu-ubuntu-2404";
function listTestFiles(rootDir: string): string[] {
  const gitFiles = listGitTrackedFiles({ pathspecs: rootDir });
  expect(gitFiles).not.toBeNull();
  if (gitFiles) {
    return gitFiles.filter((line) => line.endsWith(".test.ts"));
  }

  if (!existsSync(rootDir)) {
    return [];
  }

  const files: string[] = [];
  const visit = (dir: string) => {
    for (const entry of readdirSync(dir, { withFileTypes: true })) {
      const path = join(dir, entry.name);
      if (entry.isDirectory()) {
        visit(path);
      } else if (entry.isFile() && entry.name.endsWith(".test.ts")) {
        files.push(toRepoPath(path));
      }
    }
  };

  visit(rootDir);
  return sortRepoPaths(files);
}

function listMatchedTestFiles(config: VitestConfig): string[] {
  const testConfig = config.test ?? {};
  const cwd = testConfig.dir ? resolve(testConfig.dir) : process.cwd();
  const exclude = (testConfig.exclude ?? []).map((pattern) =>
    isAbsolute(pattern) ? toRepoPath(relative(cwd, pattern)) : toRepoPath(pattern),
  );
  return globSync(testConfig.include ?? [], {
    cwd,
    exclude,
  })
    .map((file) => toRepoPath(relative(process.cwd(), resolve(cwd, file))))
    .toSorted((a, b) => a.localeCompare(b));
}

function listAllToolingTestFiles(): string[] {
  const originalArgv = process.argv;
  try {
    process.argv = originalArgv.slice(0, 2);
    return listMatchedTestFiles(
      createToolingVitestConfig({
        ...process.env,
        OPENCLAW_VITEST_INCLUDE_FILE: undefined,
      }),
    );
  } finally {
    process.argv = originalArgv;
  }
}

describe("scripts/lib/ci-node-test-plan.mts", () => {
  it("inventories source-scanning Control UI policy tests", () => {
    expect(resolvePolicyTestTargets(["ui/src/pages/chat/view.ts"])).toEqual([
      "ui/src/components/web-awesome-migration.node.test.ts",
      "ui/src/styles/base-theme-tokens.node.test.ts",
      "ui/src/styles/cursor-policy.node.test.ts",
    ]);
    expect(resolvePolicyTestTargets(["docs/web/control-ui.md"])).toEqual([]);
  });

  it("assigns one semantic Vitest cache writer without changing shard order", () => {
    const full = createNodeTestShardBundles({ includeReleaseOnlyPluginShards: false });
    const compact = createNodeTestShardBundles({
      includeReleaseOnlyPluginShards: false,
      compact: true,
    });

    const expectWriter = (plan: Array<Pick<NodeTestShard, "groups" | "shardName">>) => {
      const marked = assignVitestFsCacheWriter(plan);
      expect(marked.map((shard) => shard.shardName)).toEqual(plan.map((shard) => shard.shardName));
      expect(marked.filter((shard) => shard.saveVitestFsCache)).toHaveLength(1);
      expect(
        marked.find((shard) => shard.saveVitestFsCache)?.shardName.startsWith("core-unit-fast") ||
          marked
            .find((shard) => shard.saveVitestFsCache)
            ?.groups?.some((group) => group.shard_name.startsWith("core-unit-fast")),
      ).toBe(true);
    };
    expectWriter(full);
    expectWriter(compact);

    expect(assignVitestFsCacheWriter([])).toEqual([]);
    const changedOnly = {
      checkName: "checks-node-changed-only",
      configs: ["test/vitest/vitest.unit.config.ts"],
      requiresDist: false,
      runner: DEFAULT_NODE_TEST_RUNNER,
      shardName: "changed-only",
    };
    expect(assignVitestFsCacheWriter([changedOnly])).toEqual([
      { ...changedOnly, saveVitestFsCache: true },
    ]);
  });

  it("projects cache-warm groups from the owned node test plan", () => {
    const groups = createVitestCacheWarmGroups();
    expect(groups).toHaveLength(10);
    expect(groups.every((group) => group.configs.length === 1)).toBe(true);
    expect(new Set(groups.flatMap((group) => group.configs))).toHaveProperty("size", 9);
    expect(new Set(groups.map((group) => group.shard_name))).toHaveProperty("size", groups.length);

    const coreStripeGroups = groups.filter(
      (group) => group.configs[0] === "test/vitest/vitest.unit-fast.config.ts",
    );
    expect(coreStripeGroups).toHaveLength(2);
    expect(coreStripeGroups.every((group) => (group.includePatterns?.length ?? 0) > 0)).toBe(true);
    const coreStripePatterns = coreStripeGroups.flatMap((group) => group.includePatterns ?? []);
    expect(new Set(coreStripePatterns).size).toBe(coreStripePatterns.length);

    const isolatedGroups = groups.filter((group) =>
      group.shard_name.startsWith("cache-warm:core-unit-fast-isolated:"),
    );
    expect(isolatedGroups).toHaveLength(2);
    expect(isolatedGroups.every((group) => group.includePatterns === undefined)).toBe(true);
    expect(isolatedGroups.every((group) => group.env === undefined)).toBe(true);

    const embeddedGroups = groups.filter((group) =>
      group.shard_name.startsWith("cache-warm:agentic-agents-embedded:"),
    );
    expect(embeddedGroups).toHaveLength(4);
    expect(
      embeddedGroups.every((group) => group.env?.OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS === "660000"),
    ).toBe(true);

    const gatewayGroups = groups.filter((group) =>
      group.shard_name.startsWith("cache-warm:agentic-gateway-methods:"),
    );
    expect(gatewayGroups).toHaveLength(1);
    expect(gatewayGroups[0]?.includePatterns).toBeUndefined();
    expect(gatewayGroups[0]?.env).toBeUndefined();

    const autoReplyGroups = groups.filter((group) =>
      group.shard_name.startsWith("cache-warm:auto-reply-reply-commands-3:"),
    );
    expect(autoReplyGroups).toHaveLength(1);
    expect(autoReplyGroups[0]?.includePatterns).toHaveLength(18);
    expect(autoReplyGroups[0]?.env).toBeUndefined();
  });

  it("creates split shards without walking test roots", () => {
    const payload = expectNoNodeFsScans<{
      includePatterns: number;
      shards: number;
    }>(`
      const { createNodeTestShards } = await import("./scripts/lib/ci-node-test-plan.mts");
      const shards = createNodeTestShards();
      return {
        includePatterns: shards.reduce(
          (total, shard) => total + (shard.includePatterns?.length ?? 0),
          0,
        ),
        shards: shards.length,
      };
    `);
    expect(payload.shards).toBeGreaterThan(0);
    expect(payload.includePatterns).toBeGreaterThan(0);
  });

  it("bundles split shards deterministically without changing coverage", () => {
    const base = createNodeTestShards({ includeReleaseOnlyPluginShards: false });
    const bundled = createNodeTestShardBundles({ includeReleaseOnlyPluginShards: false });
    const basePatterns = base
      .flatMap((shard) => shard.includePatterns ?? [])
      .toSorted((a, b) => a.localeCompare(b));
    const bundledPatterns = bundled
      .flatMap((shard) => shard.includePatterns ?? [])
      .toSorted((a, b) => a.localeCompare(b));

    expect(bundled.length).toBeLessThan(base.length);
    expect(bundledPatterns).toEqual(basePatterns);
    expect(
      bundled
        .filter((shard) => shard.shardName.startsWith("bundle-"))
        .every((shard) => (shard.includePatterns?.length ?? 0) <= 64),
    ).toBe(true);
    expect(bundled.every((shard) => shard.runner?.startsWith("blacksmith-"))).toBe(true);
    expect(bundled).toEqual(createNodeTestShardBundles({ includeReleaseOnlyPluginShards: false }));
    expect(bundled.slice(0, 6).map((shard) => shard.shardName)).toEqual([
      "core-unit-fast-1",
      "core-unit-fast-2",
      "core-tooling-1",
      "core-tooling-2",
      "core-tooling-3",
      "core-tooling-4",
    ]);
    expect(bundled.find((shard) => shard.shardName === "core-unit-fast-1")?.runner).toBe(
      DEFAULT_NODE_TEST_RUNNER,
    );
    expect(bundled.find((shard) => shard.shardName === "core-unit-fast-2")?.runner).toBe(
      DEFAULT_NODE_TEST_RUNNER,
    );
    expect(
      bundled.find((shard) => shard.shardName === "agentic-control-plane-startup-health-runtime")
        ?.env,
    ).toEqual({ OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS: "60000" });
    expect(
      bundled.find((shard) => shard.shardName === "agentic-control-plane-startup-core")?.runner,
    ).toBe(DEFAULT_NODE_TEST_RUNNER);
    expect(bundled.find((shard) => shard.shardName === "bundle-infra-small-1")?.runner).toBe(
      "blacksmith-4vcpu-ubuntu-2404",
    );
    expect(
      new Set(
        bundled
          .filter((shard) => shard.shardName.startsWith("bundle-"))
          .flatMap((shard) => shard.configs),
      ),
    ).toEqual(new Set(["test/vitest/vitest.infra.config.ts"]));
    expect(bundled.some((shard) => shard.shardName.startsWith("bundle-commands-"))).toBe(false);
    expect(bundled.some((shard) => shard.shardName.startsWith("bundle-cron-"))).toBe(false);
    expect(bundled.some((shard) => shard.shardName.startsWith("bundle-agents-core-"))).toBe(false);
    expect(bundled.some((shard) => shard.shardName.startsWith("bundle-gateway-server-"))).toBe(
      false,
    );
  });

  it("compacts pull-request shards into isolated groups inside fewer jobs", () => {
    const base = createNodeTestShards({ includeReleaseOnlyPluginShards: false });
    const compact = createNodeTestShardBundles({
      includeReleaseOnlyPluginShards: false,
      compact: true,
    });

    // Rebalancing may change ownership but must not add CI workers.
    expect(compact).toHaveLength(23);
    expect(compact.every((shard) => Array.isArray(shard.groups))).toBe(true);
    expect(compact.every((shard) => shard.groups.length <= 10)).toBe(true);
    expect(compact.some((shard) => shard.requiresDist)).toBe(true);
    expect(
      compact.every((shard) =>
        shard.groups.every(
          (group) => group.requiresDist === shard.requiresDist && group.runner === shard.runner,
        ),
      ),
    ).toBe(true);
    // Runtime-balanced packing must keep the two heaviest measured groups in
    // different jobs; regressing to per-file weights recombines them.
    const jobOf = (name: string) =>
      compact.findIndex((shard) => shard.groups.some((group) => group.shard_name === name));
    expect(jobOf("agentic-agents-core-runner-embedded")).toBeGreaterThanOrEqual(0);
    // The complete Control UI and model catalog both cold-load broad graphs;
    // pairing them starves model visibility and repeatedly hits its timeout.
    expect(jobOf("agentic-agents-core-models")).not.toBe(jobOf("core-runtime-media-ui"));
    expect(jobOf("core-runtime-media-ui")).not.toBe(jobOf("core-unit-src-security"));
    // Means expose recurrent 8-vCPU tails hidden by the median-only plan. Keep
    // the observed pairing that dominated replayed job walls separated.
    expect(jobOf("agentic-agents-core-tools")).not.toBe(jobOf("agentic-agents-embedded-base"));
    expect(
      compact[jobOf("core-unit-src-security")]?.groups.map((group) => group.shard_name),
    ).toEqual(["core-unit-src-security"]);
    // Cheap stripes may legally co-locate in one bin; only existence matters.
    expect(jobOf("core-unit-fast-1")).toBeGreaterThanOrEqual(0);
    expect(jobOf("core-unit-fast-2")).toBeGreaterThanOrEqual(0);
    // Spawn/signal-timing suites never mix with regular groups, and every
    // compact bin runs serially: overlapping Vitest runs flake timing-
    // sensitive tests on both runner classes.
    const exclusiveGroupRe = /^core-tooling(?:-\d+|-isolated)$|^core-runtime-tui-pty$/u;
    for (const shard of compact) {
      const exclusiveCount = shard.groups.filter((group) =>
        exclusiveGroupRe.test(group.shard_name),
      ).length;
      if (exclusiveCount > 0) {
        expect(exclusiveCount).toBe(shard.groups.length);
      }
      expect(shard.planConcurrency).toBe(1);
    }
    expect(
      compact.filter((shard) =>
        shard.groups.some((group) => exclusiveGroupRe.test(group.shard_name)),
      ).length,
    ).toBeGreaterThan(0);
    const expectedEmbeddedAgentGroupNames = [
      "agentic-agents-embedded-base",
      "agentic-agents-embedded-incomplete-turn",
      "agentic-agents-embedded-overflow-compaction",
      "agentic-agents-embedded-run",
    ];
    const compactGroups = compact.flatMap((shard) => shard.groups);
    const expectedGroupNames = base.flatMap((shard) =>
      shard.shardName === "agentic-agents-embedded"
        ? expectedEmbeddedAgentGroupNames
        : [shard.shardName],
    );
    expect(compactGroups.map((group) => group.shard_name).toSorted()).toEqual(
      expectedGroupNames.toSorted(),
    );
    // Both plans carry the same split stripes now; compact bundling must also
    // preserve include-pattern coverage exactly.
    expect(
      compactGroups
        .flatMap((group) => group.includePatterns ?? [])
        .toSorted((a, b) => a.localeCompare(b)),
    ).toEqual(
      base.flatMap((shard) => shard.includePatterns ?? []).toSorted((a, b) => a.localeCompare(b)),
    );
    expect(compact.every((shard) => shard.groups.every((group) => group.configs.length > 0))).toBe(
      true,
    );
    expect(
      compact
        .flatMap((shard) => shard.groups)
        .find((group) => group.shard_name === "core-runtime-tui-pty")?.env,
    ).toEqual({
      OPENCLAW_TUI_PTY_INCLUDE_LOCAL: "1",
      OPENCLAW_TUI_PTY_USE_BUILT_CLI: "1",
      // Timing-sensitive groups pin the worker budget while the job-level
      // default scales with the runner class.
      OPENCLAW_VITEST_MAX_WORKERS: "2",
    });
    expect(
      compact.flatMap((shard) => shard.groups).find((group) => group.shard_name === "agentic-cli")
        ?.env,
    ).toEqual({
      OPENCLAW_VITEST_MAX_WORKERS: "2",
    });
    const startupCoreJob = compact.find((shard) =>
      shard.groups.some((group) => group.shard_name === "agentic-control-plane-startup-core"),
    );
    expect(startupCoreJob?.runner).toBe(DEFAULT_NODE_TEST_RUNNER);
    expect(
      startupCoreJob?.groups.find(
        (group) => group.shard_name === "agentic-control-plane-startup-core",
      )?.runner,
    ).toBe(DEFAULT_NODE_TEST_RUNNER);
    expect(
      compact
        .flatMap((shard) => shard.groups)
        .find((group) => group.shard_name === "agentic-control-plane-startup-health-runtime")?.env,
    ).toEqual({ OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS: "60000" });
    const largeJobs = compact.filter(
      (shard) => !shard.requiresDist && shard.checkName.startsWith("checks-node-compact-large-"),
    );
    const smallJobs = compact.filter(
      (shard) => !shard.requiresDist && shard.checkName.startsWith("checks-node-compact-small-"),
    );
    const distJobs = compact.filter((shard) => shard.requiresDist);
    expect(largeJobs).toHaveLength(7);
    expect(smallJobs).toHaveLength(14);
    expect(distJobs).toHaveLength(2);
    const regularSmallJobs = smallJobs.filter((shard) =>
      shard.groups.every((group) => !exclusiveGroupRe.test(group.shard_name)),
    );
    expect(regularSmallJobs).toHaveLength(10);
    const routed8VcpuCheckNames = [
      "checks-node-compact-small-2",
      "checks-node-compact-small-5",
      "checks-node-compact-small-8",
    ];
    expect(
      regularSmallJobs
        .filter((shard) => shard.runner === DEFAULT_NODE_TEST_RUNNER)
        .map((shard) => shard.checkName),
    ).toEqual(routed8VcpuCheckNames);
    expect(
      smallJobs
        .filter((shard) => !routed8VcpuCheckNames.includes(shard.checkName))
        .every((shard) => shard.runner === BUNDLED_NODE_TEST_RUNNER),
    ).toBe(true);
    // The refreshed hosted estimates give every regular bin one known tail
    // anchor. Stale hints paired two slow groups in each runner class.
    const largeTailAnchors = [
      "core-unit-src-security",
      "agentic-gateway-core",
      "core-runtime-media-ui",
      "agentic-agents-support",
      "agentic-gateway-methods",
      "agentic-agents-core-runtime",
      "agentic-agents-embedded-base",
    ];
    const smallTailAnchors = [
      "agentic-control-plane-auth-node",
      "agentic-control-plane-agent-chat",
      "core-runtime-infra-process",
      "agentic-cli",
      "core-runtime-cron-isolated-agent",
      "core-runtime-infra-storage-state",
      "agentic-agents-tools",
      "agentic-commands-agent-channel",
      "agentic-commands-doctor-config-state",
      "auto-reply-reply-agent-runner",
    ];
    expect(
      largeJobs.map(
        (shard) =>
          shard.groups.filter((group) => largeTailAnchors.includes(group.shard_name)).length,
      ),
    ).toEqual(Array.from({ length: largeTailAnchors.length }, () => 1));
    expect(
      regularSmallJobs.map(
        (shard) =>
          shard.groups.filter((group) => smallTailAnchors.includes(group.shard_name)).length,
      ),
    ).toEqual(Array.from({ length: smallTailAnchors.length }, () => 1));
    expect(compact).toEqual(
      createNodeTestShardBundles({
        includeReleaseOnlyPluginShards: false,
        compact: true,
      }),
    );
    const embeddedAgentGroups = compact
      .flatMap((shard) => shard.groups)
      .filter((group) => group.shard_name.startsWith("agentic-agents-embedded-"));
    expect(embeddedAgentGroups.map((group) => group.shard_name).toSorted()).toEqual(
      expectedEmbeddedAgentGroupNames,
    );
    expect(
      compact.some((shard) =>
        shard.groups.some((group) => group.shard_name === "agentic-agents-embedded"),
      ),
    ).toBe(false);
    expect(embeddedAgentGroups.flatMap((group) => group.configs).toSorted()).toEqual(
      embeddedAgentVitestProjectOwners.map((owner) => owner.config).toSorted(),
    );
    expect(
      embeddedAgentGroups.every(
        (group) => group.env?.OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS === "660000",
      ),
    ).toBe(true);
    expect(
      compact
        .filter((shard) => shard.groups.some((group) => !group.includePatterns))
        .every((shard) => shard.timeoutMinutes === 120),
    ).toBe(true);
    // Whole-config groups now pack into the same runtime-balanced bins as
    // include-pattern groups; the separate "-whole-" job class is gone.
    expect(compact.some((shard) => shard.checkName.includes("-whole-"))).toBe(false);
    expect(
      compact.some((shard) => shard.groups.some((group) => group.shard_name === "core-tooling")),
    ).toBe(false);
    expect(
      compact
        .flatMap((shard) => shard.groups)
        .find((group) => group.shard_name === "core-tooling-isolated"),
    ).toEqual(
      expect.objectContaining({
        configs: [
          "test/vitest/vitest.tooling-docker.config.ts",
          "test/vitest/vitest.tooling-isolated.config.ts",
        ],
      }),
    );
    // The docker helper config rides with the isolated shard on both plans;
    // no standalone core-tooling-docker group remains.
    expect(
      compact
        .flatMap((shard) => shard.groups)
        .some((group) => group.shard_name === "core-tooling-docker"),
    ).toBe(false);
    const toolingGroups = compact
      .flatMap((shard) => shard.groups)
      .filter((group) => /^core-tooling-\d+$/u.test(group.shard_name));
    const toolingFiles = toolingGroups.flatMap((group) => group.includePatterns ?? []);
    expect(toolingGroups).toHaveLength(4);
    expect(
      toolingGroups.every((group) => group.configs[0] === "test/vitest/vitest.tooling.config.ts"),
    ).toBe(true);
    expect(new Set(toolingFiles).size).toBe(toolingFiles.length);
    expect(toolingFiles.toSorted((a, b) => a.localeCompare(b))).toEqual(listAllToolingTestFiles());
  });

  it("splits the slow core unit shards while keeping paired source/security coverage", () => {
    const coreUnitShards = createNodeTestShards()
      .filter((shard) => shard.shardName.startsWith("core-unit-"))
      .map((shard) => ({
        configs: shard.configs,
        requiresDist: shard.requiresDist,
        shardName: shard.shardName,
      }));

    expect(coreUnitShards).toEqual([
      {
        configs: ["test/vitest/vitest.unit-fast.config.ts"],
        requiresDist: false,
        shardName: "core-unit-fast-1",
      },
      {
        configs: ["test/vitest/vitest.unit-fast.config.ts"],
        requiresDist: false,
        shardName: "core-unit-fast-2",
      },
      {
        configs: [
          "test/vitest/vitest.unit-fast-isolated.config.ts",
          "test/vitest/vitest.unit-fast-fake-timers.config.ts",
        ],
        requiresDist: false,
        shardName: "core-unit-fast-isolated",
      },
      {
        configs: [
          "test/vitest/vitest.unit-src.config.ts",
          "test/vitest/vitest.unit-security.config.ts",
        ],
        requiresDist: false,
        shardName: "core-unit-src-security",
      },
      {
        configs: ["test/vitest/vitest.unit-support.config.ts"],
        requiresDist: false,
        shardName: "core-unit-support",
      },
    ]);
  });

  it("names the node shard checks as core test lanes", () => {
    const shards = createNodeTestShards();

    expect(shards).not.toHaveLength(0);
    expect(shards.map((shard) => shard.checkName)).toEqual(
      shards.map((shard) =>
        shard.shardName.startsWith("core-unit-")
          ? `checks-node-core-${shard.shardName.slice("core-unit-".length)}`
          : `checks-node-${shard.shardName}`,
      ),
    );
  });

  it("keeps extension, bundled, contracts, and channels configs out of the core node lane", () => {
    const configs = createNodeTestShards().flatMap((shard) => shard.configs);

    expect(configs).not.toContain("test/vitest/vitest.channels.config.ts");
    expect(configs).not.toContain("test/vitest/vitest.contracts.config.ts");
    expect(configs).not.toContain("test/vitest/vitest.bundled.config.ts");
    expect(configs).not.toContain("test/vitest/vitest.full-extensions.config.ts");
    expect(configs).not.toContain("test/vitest/vitest.extension-telegram.config.ts");
  });

  it("marks only dist-dependent shards for built artifact restore", () => {
    const requiresDistShardNames = createNodeTestShards()
      .filter((shard) => shard.requiresDist)
      .map((shard) => shard.shardName);

    expect(requiresDistShardNames).toEqual(["core-support-boundary", "core-runtime-tui-pty"]);
  });

  it("splits tooling checks independently from built artifacts", () => {
    const toolingShards = createNodeTestShards().filter((shard) =>
      shard.shardName.startsWith("core-tooling"),
    );

    const stripes = toolingShards.filter((shard) => /^core-tooling-\d+$/u.test(shard.shardName));
    expect(stripes).toHaveLength(4);
    for (const stripe of stripes) {
      expect(stripe.configs).toEqual(["test/vitest/vitest.tooling.config.ts"]);
      expect(stripe.requiresDist).toBe(false);
      expect(stripe.includePatterns?.length ?? 0).toBeGreaterThan(0);
    }
    // Stripes partition the tooling files: no overlap, nothing dropped.
    const stripeFiles = stripes.flatMap((stripe) => stripe.includePatterns ?? []);
    expect(new Set(stripeFiles).size).toBe(stripeFiles.length);
    expect(
      toolingShards.find((shard) => shard.shardName === "core-tooling-isolated"),
    ).toMatchObject({
      configs: [
        "test/vitest/vitest.tooling-docker.config.ts",
        "test/vitest/vitest.tooling-isolated.config.ts",
      ],
      requiresDist: false,
    });
  });

  it("assigns Blacksmith runners to every core node shard", () => {
    const shards = createNodeTestShards();

    expect(shards).not.toHaveLength(0);
    expect(shards.every((shard) => shard.runner?.startsWith("blacksmith-"))).toBe(true);
  });

  it("splits core runtime configs into smaller source-only shards", () => {
    const runtimeShards = createNodeTestShards()
      .filter((shard) => shard.shardName.startsWith("core-runtime-"))
      .map((shard) => ({
        configs: shard.configs,
        requiresDist: shard.requiresDist,
        runner: shard.runner,
        shardName: shard.shardName,
      }));

    expect(runtimeShards).toEqual([
      {
        configs: ["test/vitest/vitest.hooks.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-hooks",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-approval-exec",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-channel-plugin",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-cli-ui",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-device",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-diagnostics-state",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-core-utils",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-env-auth",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-events-runtime",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-file-safety",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-files-commands",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-gateway-lock-argv",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-gateway-processes",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-gateway-watch",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-heartbeat-core",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-heartbeat-runner",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-misc",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-misc-dedupe-disk",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-misc-os",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-misc-values",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-net-install",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-network-node",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-network-platform",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-outbound-actions",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-outbound-core",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-provider-push",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-repo-tooling",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-storage-state",
      },
      {
        configs: ["test/vitest/vitest.infra.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-system-runtime",
      },
      {
        configs: ["test/vitest/vitest.secrets.config.ts"],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-secrets",
      },
      {
        configs: [
          "test/vitest/vitest.logging.config.ts",
          "test/vitest/vitest.process.config.ts",
          "test/vitest/vitest.runtime-config.config.ts",
        ],
        requiresDist: false,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-infra-process",
      },
      {
        configs: ["test/vitest/vitest.tui-pty.config.ts"],
        requiresDist: true,
        runner: "blacksmith-4vcpu-ubuntu-2404",
        shardName: "core-runtime-tui-pty",
      },
      {
        configs: [
          "test/vitest/vitest.media.config.ts",
          "test/vitest/vitest.media-understanding.config.ts",
          "test/vitest/vitest.tui.config.ts",
          "test/vitest/vitest.ui.config.ts",
          "test/vitest/vitest.ui-isolated.config.ts",
          "test/vitest/vitest.wizard.config.ts",
        ],
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "core-runtime-media-ui",
      },
      {
        configs: [
          "test/vitest/vitest.acp.config.ts",
          "test/vitest/vitest.shared-core.config.ts",
          "test/vitest/vitest.tasks.config.ts",
          "test/vitest/vitest.utils.config.ts",
        ],
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "core-runtime-shared",
      },
      {
        configs: ["test/vitest/vitest.cron.config.ts"],
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "core-runtime-cron-core",
      },
      {
        configs: ["test/vitest/vitest.cron.config.ts"],
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "core-runtime-cron-isolated-agent",
      },
      {
        configs: ["test/vitest/vitest.cron.config.ts"],
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "core-runtime-cron-service",
      },
    ]);
  });

  it("keeps the full TUI PTY suite in its dedicated built-CLI shard", () => {
    const tuiPtyShard = createNodeTestShards().find(
      (shard) => shard.shardName === "core-runtime-tui-pty",
    );

    expect(tuiPtyShard).toMatchObject({
      checkName: "checks-node-core-runtime-tui-pty",
      configs: ["test/vitest/vitest.tui-pty.config.ts"],
      env: {
        OPENCLAW_TUI_PTY_INCLUDE_LOCAL: "1",
        OPENCLAW_TUI_PTY_USE_BUILT_CLI: "1",
      },
      requiresDist: true,
    });
    expect(tuiPtyShard?.includePatterns).toBeUndefined();
  });

  it("covers every infra test exactly once across core runtime infra shards", () => {
    const infraShards = createNodeTestShards().filter((shard) =>
      shard.shardName.startsWith("core-runtime-infra-"),
    );
    const actual = infraShards
      .flatMap((shard) => shard.includePatterns ?? [])
      .toSorted((a, b) => a.localeCompare(b));

    expect(infraShards.map((shard) => shard.shardName)).toEqual([
      "core-runtime-infra-approval-exec",
      "core-runtime-infra-channel-plugin",
      "core-runtime-infra-cli-ui",
      "core-runtime-infra-device",
      "core-runtime-infra-diagnostics-state",
      "core-runtime-infra-core-utils",
      "core-runtime-infra-env-auth",
      "core-runtime-infra-events-runtime",
      "core-runtime-infra-file-safety",
      "core-runtime-infra-files-commands",
      "core-runtime-infra-gateway-lock-argv",
      "core-runtime-infra-gateway-processes",
      "core-runtime-infra-gateway-watch",
      "core-runtime-infra-heartbeat-core",
      "core-runtime-infra-heartbeat-runner",
      "core-runtime-infra-misc",
      "core-runtime-infra-misc-dedupe-disk",
      "core-runtime-infra-misc-os",
      "core-runtime-infra-misc-values",
      "core-runtime-infra-net-install",
      "core-runtime-infra-network-node",
      "core-runtime-infra-network-platform",
      "core-runtime-infra-outbound-actions",
      "core-runtime-infra-outbound-core",
      "core-runtime-infra-provider-push",
      "core-runtime-infra-repo-tooling",
      "core-runtime-infra-storage-state",
      "core-runtime-infra-system-runtime",
      "core-runtime-infra-process",
    ]);
    expect(actual).toEqual(listTestFiles("src/infra"));
    expect(new Set(actual).size).toBe(actual.length);
  });

  it("covers every cron test exactly once across core runtime cron shards", () => {
    const cronShards = createNodeTestShards().filter((shard) =>
      shard.shardName.startsWith("core-runtime-cron-"),
    );
    const actual = cronShards
      .flatMap((shard) => shard.includePatterns ?? [])
      .toSorted((a, b) => a.localeCompare(b));

    expect(cronShards.map((shard) => shard.shardName)).toEqual([
      "core-runtime-cron-core",
      "core-runtime-cron-isolated-agent",
      "core-runtime-cron-service",
    ]);
    expect(actual).toEqual(listTestFiles("src/cron"));
    expect(new Set(actual).size).toBe(actual.length);
  });

  it("splits the agentic lane into control-plane, command, agent, gateway, SDK, and plugin shards", () => {
    const shards = createNodeTestShards();
    const controlPlaneShards = shards.filter((shard) =>
      shard.shardName.startsWith("agentic-control-plane-"),
    );
    const cliShard = shards.find((shard) => shard.shardName === "agentic-cli");
    const commandSupportShard = shards.find(
      (shard) => shard.shardName === "agentic-command-support",
    );
    const commandShards = shards.filter((shard) => shard.shardName.startsWith("agentic-commands-"));
    const agentShards = shards.filter((shard) => shard.shardName.startsWith("agentic-agents-"));
    const gatewayCoreShard = shards.find((shard) => shard.shardName === "agentic-gateway-core");
    const gatewayMethodsShard = shards.find(
      (shard) => shard.shardName === "agentic-gateway-methods",
    );
    const pluginSdkShard = shards.find((shard) => shard.shardName === "agentic-plugin-sdk");
    const pluginsShard = shards.find((shard) => shard.shardName === "agentic-plugins");

    expect(controlPlaneShards.map((shard) => shard.shardName)).toEqual([
      "agentic-control-plane-agent-chat",
      "agentic-control-plane-auth-node",
      "agentic-control-plane-http-models",
      "agentic-control-plane-http-plugin-ws",
      "agentic-control-plane-runtime",
      "agentic-control-plane-runtime-config",
      "agentic-control-plane-runtime-cron",
      "agentic-control-plane-runtime-network",
      "agentic-control-plane-runtime-server",
      "agentic-control-plane-runtime-shared-token",
      "agentic-control-plane-runtime-state",
      "agentic-control-plane-runtime-ui-tools",
      "agentic-control-plane-startup-config",
      "agentic-control-plane-startup-core",
      "agentic-control-plane-startup-health-runtime",
      "agentic-control-plane-startup-restart-close",
    ]);
    expect(controlPlaneShards).toEqual(
      controlPlaneShards.map((shard) => ({
        checkName: `checks-node-${shard.shardName}`,
        configs: ["test/vitest/vitest.gateway-server.config.ts"],
        ...(shard.shardName === "agentic-control-plane-startup-health-runtime"
          ? { env: { OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS: "60000" } }
          : {}),
        includePatterns: shard.includePatterns,
        requiresDist: false,
        runner:
          shard.shardName === "agentic-control-plane-startup-core"
            ? DEFAULT_NODE_TEST_RUNNER
            : "blacksmith-4vcpu-ubuntu-2404",
        shardName: shard.shardName,
      })),
    );
    const controlPlaneShardFiles = controlPlaneShards
      .flatMap((shard) => shard.includePatterns ?? [])
      .toSorted((a, b) => a.localeCompare(b));
    const expectedControlPlaneFiles = listMatchedTestFiles(
      createGatewayServerVitestConfig({
        ...process.env,
        OPENCLAW_VITEST_INCLUDE_FILE: undefined,
      }),
    );
    expect(
      listTestFiles("src/gateway")
        .filter(isGatewayServerTestFile)
        .toSorted((a, b) => a.localeCompare(b)),
    ).toEqual(expectedControlPlaneFiles);
    expect(controlPlaneShardFiles).toEqual(expectedControlPlaneFiles);
    expect(new Set(controlPlaneShardFiles).size).toBe(controlPlaneShardFiles.length);
    expect(cliShard).toEqual({
      checkName: "checks-node-agentic-cli",
      shardName: "agentic-cli",
      configs: ["test/vitest/vitest.cli.config.ts", "test/vitest/vitest.cli-process.config.ts"],
      requiresDist: false,
      runner: DEFAULT_NODE_TEST_RUNNER,
    });
    expect(commandSupportShard).toEqual({
      checkName: "checks-node-agentic-command-support",
      shardName: "agentic-command-support",
      configs: [
        "test/vitest/vitest.commands-light.config.ts",
        "test/vitest/vitest.daemon.config.ts",
      ],
      requiresDist: false,
      runner: DEFAULT_NODE_TEST_RUNNER,
    });
    expect(commandShards.map((shard) => shard.shardName)).toEqual([
      "agentic-commands-agent-channel",
      "agentic-commands-doctor",
      "agentic-commands-doctor-auth",
      "agentic-commands-doctor-config-state",
      "agentic-commands-doctor-device",
      "agentic-commands-doctor-gateway",
      "agentic-commands-doctor-platform",
      "agentic-commands-doctor-plugins-tools",
      "agentic-commands-doctor-sessions-cron",
      "agentic-commands-doctor-shared",
      "agentic-commands-doctor-whatsapp",
      "agentic-commands-doctor-workspace",
      "agentic-commands-models",
      "agentic-commands-onboard-config",
      "agentic-commands-status-tools",
    ]);
    expect(commandShards).toEqual(
      commandShards.map((shard) => ({
        checkName: `checks-node-${shard.shardName}`,
        configs: ["test/vitest/vitest.commands.config.ts"],
        includePatterns: shard.includePatterns,
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: shard.shardName,
      })),
    );
    expect(
      commandShards.find((shard) => shard.shardName === "agentic-commands-doctor-auth")
        ?.includePatterns,
    ).toContain("src/commands/oauth-tls-preflight.doctor.test.ts");
    const commandShardFiles = commandShards
      .flatMap((shard) => shard.includePatterns ?? [])
      .toSorted((a, b) => a.localeCompare(b));
    const expectedCommandFiles = listTestFiles("src/commands")
      .filter((file) => !commandsLightTestFiles.includes(file) && !file.endsWith(".e2e.test.ts"))
      .toSorted((a, b) => a.localeCompare(b));
    expect(commandShardFiles).toEqual(expectedCommandFiles);
    expect(new Set(commandShardFiles).size).toBe(commandShardFiles.length);
    expect(agentShards).toEqual([
      {
        checkName: "checks-node-agentic-agents-core-auth",
        configs: ["test/vitest/vitest.agents-core.config.ts"],
        includePatterns: agentShards[0]?.includePatterns,
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "agentic-agents-core-auth",
      },
      {
        checkName: "checks-node-agentic-agents-core-models",
        configs: ["test/vitest/vitest.agents-core.config.ts"],
        includePatterns: agentShards[1]?.includePatterns,
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "agentic-agents-core-models",
      },
      {
        checkName: "checks-node-agentic-agents-core-tools",
        configs: ["test/vitest/vitest.agents-core.config.ts"],
        includePatterns: agentShards[2]?.includePatterns,
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "agentic-agents-core-tools",
      },
      {
        checkName: "checks-node-agentic-agents-core-subagents",
        configs: ["test/vitest/vitest.agents-core.config.ts"],
        includePatterns: agentShards[3]?.includePatterns,
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "agentic-agents-core-subagents",
      },
      // cli-runner stripes: agents-core runs files serially, so the
      // import-heavy suite splits across jobs to parallelize at bin level.
      {
        checkName: "checks-node-agentic-agents-core-runner-cli-1",
        configs: ["test/vitest/vitest.agents-core.config.ts"],
        includePatterns: agentShards[4]?.includePatterns,
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "agentic-agents-core-runner-cli-1",
      },
      {
        checkName: "checks-node-agentic-agents-core-runner-cli-2",
        configs: ["test/vitest/vitest.agents-core.config.ts"],
        includePatterns: agentShards[5]?.includePatterns,
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "agentic-agents-core-runner-cli-2",
      },
      {
        checkName: "checks-node-agentic-agents-core-runner-cli-3",
        configs: ["test/vitest/vitest.agents-core.config.ts"],
        includePatterns: agentShards[6]?.includePatterns,
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "agentic-agents-core-runner-cli-3",
      },
      {
        checkName: "checks-node-agentic-agents-core-runner-commands",
        configs: ["test/vitest/vitest.agents-core.config.ts"],
        includePatterns: agentShards[7]?.includePatterns,
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "agentic-agents-core-runner-commands",
      },
      {
        checkName: "checks-node-agentic-agents-core-runner-embedded",
        configs: ["test/vitest/vitest.agents-core.config.ts"],
        includePatterns: agentShards[8]?.includePatterns,
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "agentic-agents-core-runner-embedded",
      },
      {
        checkName: "checks-node-agentic-agents-core-runner-sessions",
        configs: ["test/vitest/vitest.agents-core.config.ts"],
        includePatterns: agentShards[9]?.includePatterns,
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "agentic-agents-core-runner-sessions",
      },
      {
        checkName: "checks-node-agentic-agents-core-runtime",
        configs: ["test/vitest/vitest.agents-core.config.ts"],
        includePatterns: agentShards[10]?.includePatterns,
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "agentic-agents-core-runtime",
      },
      {
        checkName: "checks-node-agentic-agents-core-isolated",
        configs: ["test/vitest/vitest.agents-core-isolated.config.ts"],
        includePatterns: agentShards[11]?.includePatterns,
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "agentic-agents-core-isolated",
      },
      {
        checkName: "checks-node-agentic-agents-embedded",
        configs: [
          "test/vitest/vitest.agents-embedded-agent.config.ts",
          "test/vitest/vitest.agents-embedded-agent-incomplete-turn.config.ts",
          "test/vitest/vitest.agents-embedded-agent-overflow-compaction.config.ts",
          "test/vitest/vitest.agents-embedded-agent-run.config.ts",
        ],
        env: { OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS: "660000" },
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "agentic-agents-embedded",
      },
      {
        checkName: "checks-node-agentic-agents-support",
        configs: ["test/vitest/vitest.agents-support.config.ts"],
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "agentic-agents-support",
      },
      {
        checkName: "checks-node-agentic-agents-tools",
        configs: ["test/vitest/vitest.agents-tools.config.ts"],
        requiresDist: false,
        runner: DEFAULT_NODE_TEST_RUNNER,
        shardName: "agentic-agents-tools",
      },
    ]);
    expect(pluginSdkShard).toEqual({
      checkName: "checks-node-agentic-plugin-sdk",
      shardName: "agentic-plugin-sdk",
      configs: [
        "test/vitest/vitest.plugin-sdk-light.config.ts",
        "test/vitest/vitest.plugin-sdk.config.ts",
      ],
      requiresDist: false,
      runner: DEFAULT_NODE_TEST_RUNNER,
    });
    expect(gatewayCoreShard).toEqual({
      checkName: "checks-node-agentic-gateway-core",
      shardName: "agentic-gateway-core",
      configs: [
        "test/vitest/vitest.gateway-core.config.ts",
        "test/vitest/vitest.gateway-client.config.ts",
      ],
      requiresDist: false,
      runner: DEFAULT_NODE_TEST_RUNNER,
    });
    expect(gatewayMethodsShard).toEqual({
      checkName: "checks-node-agentic-gateway-methods",
      shardName: "agentic-gateway-methods",
      configs: ["test/vitest/vitest.gateway-methods.config.ts"],
      requiresDist: false,
      runner: DEFAULT_NODE_TEST_RUNNER,
    });
    expect(pluginsShard).toEqual({
      checkName: "checks-node-agentic-plugins",
      shardName: "agentic-plugins",
      configs: ["test/vitest/vitest.plugins.config.ts"],
      requiresDist: false,
      runner: DEFAULT_NODE_TEST_RUNNER,
    });
  });

  it("keeps plugin prerelease npm install coverage on the release-only agentic plugin shard", () => {
    const pluginsShard = createNodeTestShards().find(
      (shard) => shard.shardName === "agentic-plugins",
    );

    expect(pluginsShard).toEqual({
      checkName: "checks-node-agentic-plugins",
      configs: ["test/vitest/vitest.plugins.config.ts"],
      requiresDist: false,
      runner: DEFAULT_NODE_TEST_RUNNER,
      shardName: "agentic-plugins",
    });
    expect(listMatchedTestFiles(createPluginsVitestConfig({}))).toContain(
      PLUGIN_PRERELEASE_NPM_SPEC_TEST,
    );
    expect(listMatchedTestFiles(createPluginsVitestConfig({}))).toContain(
      PLUGIN_NPM_INSTALL_SECURITY_SCAN_TEST,
    );
  });

  it("covers flat agents-core and explicitly nested isolated tests exactly once", () => {
    const actual = createNodeTestShards()
      .filter((shard) => shard.shardName.startsWith("agentic-agents-core-"))
      .flatMap((shard) => shard.includePatterns ?? [])
      .toSorted((a, b) => a.localeCompare(b));
    const expected = [
      ...listTestFiles("src/agents").filter(
        (file) => !relative("src/agents", file).replaceAll("\\", "/").includes("/"),
      ),
      ...agentVitestProjectOwners.coreIsolated.include.filter((file) =>
        relative("src/agents", file).replaceAll("\\", "/").includes("/"),
      ),
    ].toSorted((a, b) => a.localeCompare(b));

    expect(actual).toEqual(expected);
    expect(new Set(actual).size).toBe(actual.length);
  });

  it("keeps embedded-agent tests in four bounded config surfaces", () => {
    const shard = createNodeTestShards().find(
      (candidate) => candidate.shardName === "agentic-agents-embedded",
    );
    const incompleteTurnFiles = new Set(agentVitestProjectOwners.embeddedIncompleteTurn.include);
    const overflowCompactionFiles = new Set(
      agentVitestProjectOwners.embeddedOverflowCompaction.include,
    );
    const actual = [
      ...globSync(agentVitestProjectOwners.embedded.include)
        .map(toRepoPath)
        .filter((file) => !incompleteTurnFiles.has(file) && !overflowCompactionFiles.has(file)),
      ...agentVitestProjectOwners.embeddedIncompleteTurn.include,
      ...agentVitestProjectOwners.embeddedOverflowCompaction.include,
      ...globSync(agentVitestProjectOwners.embeddedRun.include).map(toRepoPath),
    ].toSorted((left, right) => left.localeCompare(right));
    const expected = listTestFiles("src/agents/embedded-agent-runner").toSorted((left, right) =>
      left.localeCompare(right),
    );

    expect(shard?.configs).toEqual(embeddedAgentVitestProjectOwners.map((owner) => owner.config));
    expect(actual).toEqual(expected);
    expect(new Set(actual).size).toBe(actual.length);
  });

  it("keeps expensive plugin shards release-only when normal CI asks for the cheaper plan", () => {
    const shards = createNodeTestShards({ includeReleaseOnlyPluginShards: false });
    const shardNames = shards.map((shard) => shard.shardName);

    expect(shardNames).not.toContain("agentic-plugins");
    expect(shardNames).toContain("agentic-gateway-core");
    expect(shardNames).toContain("agentic-gateway-methods");
    expect(shardNames).toContain("agentic-plugin-sdk");
  });

  it("splits auto-reply into balanced core/top-level and reply subtree shards", () => {
    const shards = createNodeTestShards();
    const autoReplyShards = shards
      .filter((shard) => shard.shardName.startsWith("auto-reply"))
      .map((shard) => ({
        checkName: shard.checkName,
        configs: shard.configs,
        requiresDist: shard.requiresDist,
        shardName: shard.shardName,
      }));

    expect(autoReplyShards).toEqual([
      {
        checkName: "checks-node-auto-reply-core-top-level",
        configs: [
          "test/vitest/vitest.auto-reply-core.config.ts",
          "test/vitest/vitest.auto-reply-top-level.config.ts",
        ],
        requiresDist: false,
        shardName: "auto-reply-core-top-level",
      },
      {
        checkName: "checks-node-auto-reply-reply-agent-runner",
        configs: ["test/vitest/vitest.auto-reply-reply.config.ts"],
        requiresDist: false,
        shardName: "auto-reply-reply-agent-runner",
      },
      {
        checkName: "checks-node-auto-reply-reply-commands-1",
        configs: ["test/vitest/vitest.auto-reply-reply.config.ts"],
        requiresDist: false,
        shardName: "auto-reply-reply-commands-1",
      },
      {
        checkName: "checks-node-auto-reply-reply-commands-2",
        configs: ["test/vitest/vitest.auto-reply-reply.config.ts"],
        requiresDist: false,
        shardName: "auto-reply-reply-commands-2",
      },
      {
        checkName: "checks-node-auto-reply-reply-commands-3",
        configs: ["test/vitest/vitest.auto-reply-reply.config.ts"],
        requiresDist: false,
        shardName: "auto-reply-reply-commands-3",
      },
      {
        checkName: "checks-node-auto-reply-reply-dispatch",
        configs: ["test/vitest/vitest.auto-reply-reply.config.ts"],
        requiresDist: false,
        shardName: "auto-reply-reply-dispatch",
      },
      {
        checkName: "checks-node-auto-reply-reply-session",
        configs: ["test/vitest/vitest.auto-reply-reply.config.ts"],
        requiresDist: false,
        shardName: "auto-reply-reply-session",
      },
      {
        checkName: "checks-node-auto-reply-reply-state-routing",
        configs: ["test/vitest/vitest.auto-reply-reply.config.ts"],
        requiresDist: false,
        shardName: "auto-reply-reply-state-routing",
      },
    ]);
  });

  it("covers every auto-reply reply test exactly once across split shards", () => {
    const actual = createNodeTestShards()
      .filter((shard) => shard.shardName.startsWith("auto-reply-reply-"))
      .flatMap((shard) => shard.includePatterns ?? [])
      .toSorted((a, b) => a.localeCompare(b));

    expect(actual).toEqual(listTestFiles("src/auto-reply/reply"));
    expect(new Set(actual).size).toBe(actual.length);
  });
});
