import { createHash } from "node:crypto";
import {
  chmodSync,
  copyFileSync,
  existsSync,
  mkdirSync,
  mkdtempSync,
  readFileSync,
  rmSync,
  writeFileSync,
} from "node:fs";
import { join } from "node:path";
import { describe, expect, test } from "bun:test";
import {
  agentRunManagedRepositoryRenderHash,
  renderAgentRunManagedRepositoryReconcilerFragment,
} from "./agentrun-managed-repository-reconciler";
import {
  parseAgentRunGitFetchCredentialCapability,
  resolveAgentRunLaneTarget,
} from "./agentrun-lanes";
import { resolveCicdDeliveryAuthority } from "./cicd-delivery-authority";
import { renderGitMirrorStatusEnvelope } from "./agentrun/git-mirror";
import { yamlLaneGitMirrorStatusScript } from "./agentrun/secrets";
import { renderPlatformInfraGiteaDesiredFragments } from "./platform-infra-gitea-desired-fragments";

const controllerPath = new URL("../native/agentrun/managed-repository-reconciler.mjs", import.meta.url).pathname;
const askPassPath = new URL("../native/agentrun/git-askpass.mjs", import.meta.url).pathname;

describe("AgentRun YAML-owned managed repository reconciler", () => {
  test("does not render the retired managed repository controller", () => {
    const spec = resolveAgentRunLaneTarget({ node: "NC01", lane: "nc01-v02" }).spec;
    expect(spec.gitMirror.repositoryReconciler.enabled).toBe(false);
    expect(renderAgentRunManagedRepositoryReconcilerFragment("NC01")).toBe("");
    expect(renderAgentRunManagedRepositoryReconcilerFragment("JD01")).toBe("");

    const controllerSource = readFileSync(controllerPath, "utf8");
    expect(controllerSource).not.toContain("agent_skills");
    expect(controllerSource).not.toContain("pikasTech/");
    expect(controllerSource).not.toContain("github.com");
  });

  test("registers after PaC-owned admission objects without identity or separator conflicts", () => {
    const fragment = renderPlatformInfraGiteaDesiredFragments("NC01");
    expect(fragment).not.toContain("---\n---");
    const documents = fragment
      .split(/^---\s*$/mu)
      .map((item) => Bun.YAML.parse(item) as any);
    expect(documents.map((item) => item.kind)).toEqual([
      "Role",
      "RoleBinding",
      "Role",
      "RoleBinding",
      "Role",
      "RoleBinding",
      "Role",
      "RoleBinding",
      "ValidatingAdmissionPolicy",
      "ValidatingAdmissionPolicyBinding",
    ]);
    const identities = documents.map((item) => [
      item.apiVersion,
      item.kind,
      item.metadata.namespace ?? "_cluster",
      item.metadata.name,
    ].join("/"));
    expect(new Set(identities).size).toBe(documents.length);

    expect(fragment).not.toContain("managed-repository-reconciler");
  });

  test("requires every repository entry to own a matching remote", () => {
    const temporary = mkdtempSync("/tmp/unidesk-agentrun-repository-config-");
    try {
      const source = readFileSync(new URL("../../config/agentrun.yaml", import.meta.url), "utf8");
      const invalid = source.replace(
        "remote: https://github.com/pikasTech/agent_skills.git",
        "remote: https://github.com/pikasTech/unidesk.git",
      );
      const configPath = join(temporary, "agentrun.yaml");
      writeFileSync(configPath, invalid);
      expect(() => resolveAgentRunLaneTarget(
        { node: "NC01", lane: "nc01-v02" },
        { ...process.env, AGENTRUN_CONTROL_PLANE_CONFIG: configPath },
      )).toThrow("same repository entry");
    } finally {
      rmSync(temporary, { recursive: true, force: true });
    }
  });

  test("fails closed on non-canonical remotes and malformed credential capabilities", () => {
    const source = readFileSync(new URL("../../config/agentrun.yaml", import.meta.url), "utf8");
    const canonical = "https://github.com/pikasTech/agent_skills.git";
    const invalidRemotes = [
      "ssh://git@ssh.github.com:443/pikasTech/agent_skills.git",
      "https://user@github.com/pikasTech/agent_skills.git",
      "https://github.com:443/pikasTech/agent_skills.git",
      "https://github.com/pikasTech/agent_skills.git?token=forbidden",
      "https://github.com/pikasTech/agent_skills.git#forbidden",
      "https://example.com/pikasTech/agent_skills.git",
      "https://github.com/pikasTech/unidesk.git",
    ];
    const temporary = mkdtempSync("/tmp/unidesk-agentrun-remote-contract-");
    try {
      for (const [index, remote] of invalidRemotes.entries()) {
        const configPath = join(temporary, `invalid-${index}.yaml`);
        writeFileSync(configPath, source.replace(`remote: ${canonical}`, `remote: ${remote}`));
        expect(() => resolveAgentRunLaneTarget(
          { node: "NC01", lane: "nc01-v02" },
          { ...process.env, AGENTRUN_CONTROL_PLANE_CONFIG: configPath },
        )).toThrow();
      }
    } finally {
      rmSync(temporary, { recursive: true, force: true });
    }

    const validCapability = {
      apiVersion: "unidesk.ai/v1",
      kind: "GitFetchCredential",
      authMode: "github-https-token",
      host: "github.com",
      secretRef: { namespace: "devops-infra", name: "gitea-github-sync-secrets", key: "github-token" },
    };
    expect(parseAgentRunGitFetchCredentialCapability(validCapability)).toEqual(validCapability);
    for (const invalid of [
      { ...validCapability, kind: "Secret" },
      { ...validCapability, authMode: "ssh" },
      { ...validCapability, host: "example.com" },
      { ...validCapability, secretRef: { ...validCapability.secretRef, key: "invalid/key" } },
    ]) expect(() => parseAgentRunGitFetchCredentialCapability(invalid)).toThrow();
  });

  test("renders host networking only from the explicit reconciler fields", () => {
    const temporary = mkdtempSync("/tmp/unidesk-agentrun-repository-network-");
    try {
      const source = readFileSync(new URL("../../config/agentrun.yaml", import.meta.url), "utf8")
        .replace("repositoryReconciler:\n          enabled: false", "repositoryReconciler:\n          enabled: true");
      const nonLoopbackProxy = source.replace(
        "githubProxy:\n          host: 127.0.0.1\n          port: 10808",
        "githubProxy:\n          host: proxy.internal.example\n          port: 10808",
      );
      const nonLoopbackPath = join(temporary, "non-loopback.yaml");
      writeFileSync(nonLoopbackPath, nonLoopbackProxy);
      const nonLoopbackEnv = { ...process.env, AGENTRUN_CONTROL_PLANE_CONFIG: nonLoopbackPath };
      const nonLoopbackDeployment = renderAgentRunManagedRepositoryReconcilerFragment("NC01", nonLoopbackEnv)
        .split(/^---\s*$/mu)
        .map((item) => Bun.YAML.parse(item) as any)
        .find((item) => item.kind === "Deployment");
      expect(nonLoopbackDeployment.spec.template.spec.hostNetwork).toBe(true);
      expect(nonLoopbackDeployment.spec.template.spec.dnsPolicy).toBe("ClusterFirstWithHostNet");

      const clusterNetwork = source.replace(
        "hostNetwork: true\n          dnsPolicy: ClusterFirstWithHostNet",
        "hostNetwork: false\n          dnsPolicy: ClusterFirst",
      );
      const clusterNetworkPath = join(temporary, "cluster-network.yaml");
      writeFileSync(clusterNetworkPath, clusterNetwork);
      const clusterNetworkEnv = { ...process.env, AGENTRUN_CONTROL_PLANE_CONFIG: clusterNetworkPath };
      const clusterNetworkSpec = resolveAgentRunLaneTarget(
        { node: "NC01", lane: "nc01-v02" },
        clusterNetworkEnv,
      ).spec;
      const clusterNetworkDeployment = renderAgentRunManagedRepositoryReconcilerFragment("NC01", clusterNetworkEnv)
        .split(/^---\s*$/mu)
        .map((item) => Bun.YAML.parse(item) as any)
        .find((item) => item.kind === "Deployment");
      expect(clusterNetworkDeployment.spec.template.spec.hostNetwork).toBe(false);
      expect(clusterNetworkDeployment.spec.template.spec.dnsPolicy).toBe("ClusterFirst");
      const defaultSpec = resolveAgentRunLaneTarget({ node: "NC01", lane: "nc01-v02" }).spec;
      expect(agentRunManagedRepositoryRenderHash(clusterNetworkSpec)).not.toBe(agentRunManagedRepositoryRenderHash(defaultSpec));

      const invalidHostNetworkPath = join(temporary, "invalid-host-network.yaml");
      writeFileSync(invalidHostNetworkPath, source.replace("dnsPolicy: ClusterFirstWithHostNet", "dnsPolicy: ClusterFirst"));
      expect(() => resolveAgentRunLaneTarget(
        { node: "NC01", lane: "nc01-v02" },
        { ...process.env, AGENTRUN_CONTROL_PLANE_CONFIG: invalidHostNetworkPath },
      )).toThrow("must be ClusterFirstWithHostNet when");

      const invalidClusterNetworkPath = join(temporary, "invalid-cluster-network.yaml");
      writeFileSync(invalidClusterNetworkPath, source.replace("hostNetwork: true", "hostNetwork: false"));
      expect(() => resolveAgentRunLaneTarget(
        { node: "NC01", lane: "nc01-v02" },
        { ...process.env, AGENTRUN_CONTROL_PLANE_CONFIG: invalidClusterNetworkPath },
      )).toThrow("must not be ClusterFirstWithHostNet when");
    } finally {
      rmSync(temporary, { recursive: true, force: true });
    }
  });

  test("materializes source refs, exposes health, and retains undeclared cache content", () => {
    const temporary = mkdtempSync("/tmp/unidesk-agentrun-managed-repository-");
    try {
      const work = join(temporary, "work");
      const remote = join(temporary, "remote.git");
      const cache = join(temporary, "cache");
      const auth = join(temporary, "auth");
      const fakeBin = join(temporary, "bin");
      const gitObservationPath = join(temporary, "git-observations.jsonl");
      const tokenPath = join(auth, "token");
      const fixtureAskPassPath = join(auth, "git-askpass.mjs");
      mkdirSync(work, { recursive: true });
      mkdirSync(cache, { recursive: true });
      mkdirSync(auth, { recursive: true });
      mkdirSync(fakeBin, { recursive: true });
      git(["init", work]);
      git(["-C", work, "config", "user.name", "UniDesk fixture"]);
      git(["-C", work, "config", "user.email", "fixture@unidesk.invalid"]);
      writeFileSync(join(work, "README.md"), "managed repository fixture\n");
      git(["-C", work, "add", "README.md"]);
      git(["-C", work, "commit", "-m", "fixture"]);
      git(["-C", work, "branch", "-M", "main"]);
      git(["clone", "--bare", work, remote]);
      const fixtureToken = "github_pat_fixture_not_for_logs";
      writeFileSync(tokenPath, `${fixtureToken}\n`);
      copyFileSync(askPassPath, fixtureAskPassPath);
      chmodSync(fixtureAskPassPath, 0o555);

      const retainedPath = join(cache, "undeclared", "retained.git");
      mkdirSync(retainedPath, { recursive: true });
      writeFileSync(join(retainedPath, "marker"), "retain\n");

      const remoteUrl = "https://github.com/acme/example.git";
      writeGitShim({
        path: join(fakeBin, "git"),
        realGit: Bun.which("git")!,
        observationPath: gitObservationPath,
        remoteUrl,
        replacementRemoteUrl: `file://${remote}`,
      });
      const repository = {
        key: "fixture",
        repository: "acme/example",
        remote: remoteUrl,
        sourceBranch: "main",
        desiredFingerprint: sha256(["fixture", "acme/example", remoteUrl, "main"].join("\0")),
      };
      const desired = {
        schemaVersion: 1,
        kind: "AgentRunManagedRepositoryReconciler",
        nodeId: "fixture-node",
        lane: "fixture-lane",
        cacheMountPath: cache,
        stateDirectory: ".managed-state",
        reconcileIntervalMs: 1000,
        fetchTimeoutMs: 10000,
        shutdownGraceMs: 1000,
        maxConcurrentRepositories: 1,
        retry: { maxAttempts: 1, initialDelayMs: 10, maxDelayMs: 10 },
        freshness: { maxAgeMs: 60000 },
        lifecycle: { undeclaredRepositoryPolicy: "retain", managedRefs: "source-branch-only" },
        repositories: [repository],
        remoteAuth: {
          configRef: "config/platform-infra/gitea.yaml#sourceAuthority.credentials.github.gitFetchCredential",
          capabilitySha256: "a".repeat(64),
          authMode: "github-https-token",
          host: "github.com",
          tokenFile: tokenPath,
          askPassFile: fixtureAskPassPath,
          proxy: { host: "127.0.0.1", port: 10808 },
        },
      };
      const config = { ...desired, desiredHash: sha256(JSON.stringify(desired)) };
      const configPath = join(temporary, "config.json");
      writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`);

      const once = Bun.spawnSync(["node", controllerPath, "--once", "--config", configPath], {
        stdout: "pipe",
        stderr: "pipe",
        env: inheritedHostileGitEnvironment(fakeBin, fixtureToken),
      });
      expect(once.exitCode, once.stderr.toString()).toBe(0);
      expect(`${once.stdout.toString()}\n${once.stderr.toString()}`).not.toContain(fixtureToken);
      const onceStatus = JSON.parse(once.stdout.toString());
      expect(onceStatus.ready).toBe(true);
      expect(onceStatus.repositories[0].remoteFingerprint).toBe(`sha256:${sha256(remoteUrl)}`);
      expect(existsSync(join(retainedPath, "marker"))).toBe(true);
      const gitObservations = readFileSync(gitObservationPath, "utf8")
        .trim()
        .split("\n")
        .map((line) => JSON.parse(line));
      expect(gitObservations.some((item) => item.args.includes(remoteUrl))).toBe(true);
      expect(gitObservations.every((item) => item.inheritedGitSsh === false)).toBe(true);
      expect(gitObservations.every((item) => item.inheritedGitConfig === false)).toBe(true);
      expect(gitObservations.every((item) => item.inheritedGithubToken === false)).toBe(true);
      expect(gitObservations.every((item) => item.askPassConfigured === true)).toBe(true);
      expect(gitObservations.every((item) => item.tlsVerifyForced === true)).toBe(true);
      expect(readFileSync(gitObservationPath, "utf8")).not.toContain(fixtureToken);

      const mirroredCommit = git([
        "--git-dir",
        join(cache, "acme", "example.git"),
        "rev-parse",
        "--verify",
        "refs/heads/main^{commit}",
      ]).trim();
      expect(mirroredCommit).toMatch(/^[0-9a-f]{40}$/u);
      expect(readFileSync(join(cache, "acme", "example.git", "config"), "utf8")).not.toContain(fixtureToken);
      expect(readFileSync(join(cache, ".managed-state", "status.json"), "utf8")).not.toContain(fixtureToken);
      git([
        "--git-dir",
        join(cache, "acme", "example.git"),
        "update-ref",
        "refs/heads/retained-gitops",
        mirroredCommit,
      ]);
      const secondOnce = Bun.spawnSync(["node", controllerPath, "--once", "--config", configPath], {
        stdout: "pipe",
        stderr: "pipe",
        env: inheritedHostileGitEnvironment(fakeBin, fixtureToken),
      });
      expect(secondOnce.exitCode, secondOnce.stderr.toString()).toBe(0);
      expect(git([
        "--git-dir",
        join(cache, "acme", "example.git"),
        "rev-parse",
        "--verify",
        "refs/heads/retained-gitops^{commit}",
      ])).toBe(mirroredCommit);
      expect(git([
        "--git-dir",
        join(cache, "acme", "example.git"),
        "for-each-ref",
        "--format=%(refname)",
        "refs/agentrun-managed",
      ])).toBe("");

      const health = Bun.spawnSync(["node", controllerPath, "--health", "--config", configPath], {
        stdout: "pipe",
        stderr: "pipe",
        env: inheritedHostileGitEnvironment(fakeBin, fixtureToken),
      });
      expect(health.exitCode, health.stderr.toString()).toBe(0);
      const healthStatus = JSON.parse(health.stdout.toString());
      expect(healthStatus.ready).toBe(true);
      expect(healthStatus.repositories[0]).toMatchObject({
        refPresent: true,
        fresh: true,
        commit: mirroredCommit,
        remoteFingerprintAligned: true,
      });
    } finally {
      rmSync(temporary, { recursive: true, force: true });
    }
  });

  test("keeps readiness false and skips Git when the projected credential is missing or empty", () => {
    const temporary = mkdtempSync("/tmp/unidesk-agentrun-managed-repository-credential-");
    try {
      const cache = join(temporary, "cache");
      const auth = join(temporary, "auth");
      const fakeBin = join(temporary, "bin");
      const gitMarker = join(temporary, "git-invoked");
      const tokenPath = join(auth, "token");
      const fixtureAskPassPath = join(auth, "git-askpass.mjs");
      mkdirSync(cache, { recursive: true });
      mkdirSync(auth, { recursive: true });
      mkdirSync(fakeBin, { recursive: true });
      copyFileSync(askPassPath, fixtureAskPassPath);
      chmodSync(fixtureAskPassPath, 0o555);
      writeFileSync(join(fakeBin, "git"), `#!/bin/sh\ntouch ${JSON.stringify(gitMarker)}\nexit 99\n`);
      chmodSync(join(fakeBin, "git"), 0o755);

      const configPath = join(temporary, "config.json");
      writeControllerConfig(configPath, { cache, tokenPath, askPassFile: fixtureAskPassPath });
      writeFileSync(tokenPath, "\n");
      const empty = Bun.spawnSync(["node", controllerPath, "--once", "--config", configPath], {
        stdout: "pipe",
        stderr: "pipe",
        env: inheritedHostileGitEnvironment(fakeBin, "inherited-token-must-not-leak"),
      });
      expect(empty.exitCode).toBe(1);
      const emptyStatus = lastJsonLine(empty.stdout.toString());
      expect(emptyStatus).toMatchObject({
        ready: false,
        credential: { ready: false, errorCode: "credential-empty", valuesPrinted: false },
        repositories: [{ lastAttemptOk: false, errorCode: "credential-empty" }],
        valuesPrinted: false,
      });
      expect(existsSync(gitMarker)).toBe(false);

      rmSync(tokenPath);
      const missing = Bun.spawnSync(["node", controllerPath, "--health", "--config", configPath], {
        stdout: "pipe",
        stderr: "pipe",
        env: inheritedHostileGitEnvironment(fakeBin, "inherited-token-must-not-leak"),
      });
      expect(missing.exitCode).toBe(1);
      expect(JSON.parse(missing.stdout.toString())).toMatchObject({
        ready: false,
        credential: { ready: false, errorCode: "credential-file-missing", valuesPrinted: false },
        valuesPrinted: false,
      });
      expect(existsSync(gitMarker)).toBe(false);
    } finally {
      rmSync(temporary, { recursive: true, force: true });
    }
  });

  test("redacts authentication failures from logs, status, and repository config", () => {
    const temporary = mkdtempSync("/tmp/unidesk-agentrun-managed-repository-redaction-");
    try {
      const work = join(temporary, "work");
      const remote = join(temporary, "remote.git");
      const cache = join(temporary, "cache");
      const auth = join(temporary, "auth");
      const fakeBin = join(temporary, "bin");
      const tokenPath = join(auth, "token");
      const fixtureAskPassPath = join(auth, "git-askpass.mjs");
      const gitObservationPath = join(temporary, "git-observations.jsonl");
      const remoteUrl = "https://github.com/acme/example.git";
      const sensitive = "github_pat_sensitive_authentication_failure";
      mkdirSync(work, { recursive: true });
      mkdirSync(cache, { recursive: true });
      mkdirSync(auth, { recursive: true });
      mkdirSync(fakeBin, { recursive: true });
      git(["init", work]);
      git(["clone", "--bare", work, remote]);
      writeFileSync(tokenPath, `${sensitive}\n`);
      copyFileSync(askPassPath, fixtureAskPassPath);
      chmodSync(fixtureAskPassPath, 0o555);
      writeGitShim({
        path: join(fakeBin, "git"),
        realGit: Bun.which("git")!,
        observationPath: gitObservationPath,
        remoteUrl,
        replacementRemoteUrl: `file://${remote}`,
        failFetchMessage: `authentication failed for ${sensitive}`,
      });
      const configPath = join(temporary, "config.json");
      writeControllerConfig(configPath, { cache, tokenPath, askPassFile: fixtureAskPassPath });
      const once = Bun.spawnSync(["node", controllerPath, "--once", "--config", configPath], {
        stdout: "pipe",
        stderr: "pipe",
        env: inheritedHostileGitEnvironment(fakeBin, sensitive),
      });
      expect(once.exitCode).toBe(1);
      const combined = `${once.stdout.toString()}\n${once.stderr.toString()}`;
      expect(combined).not.toContain(sensitive);
      const status = lastJsonLine(once.stdout.toString());
      expect(status.repositories[0]).toMatchObject({
        lastAttemptOk: false,
        errorCode: "authentication-failed",
      });
      expect(status.repositories[0].errorFingerprint).toMatch(/^[0-9a-f]{16}$/u);
      expect(readFileSync(gitObservationPath, "utf8")).not.toContain(sensitive);
      expect(readFileSync(join(cache, ".managed-state", "status.json"), "utf8")).not.toContain(sensitive);
      expect(existsSync(join(cache, "acme", "example.git"))).toBe(false);
    } finally {
      rmSync(temporary, { recursive: true, force: true });
    }
  });

  test("keeps the legacy default summary contract and bounds the final CLI envelope", () => {
    const target = resolveAgentRunLaneTarget({ node: "NC01", lane: "nc01-v02" });
    const spec = target.spec;
    const authority = resolveCicdDeliveryAuthority({
      node: spec.nodeId,
      lane: spec.lane,
      sourceRepository: spec.source.repository,
      sourceBranch: spec.source.branch,
      declaredSourceAuthorityMode: spec.source.sourceAuthority?.mode ?? null,
      declaredConfigRef: target.configPath,
    });
    expect(authority.kind).toBe("pac-pr-merge");
    const defaultRepositoryLimit = spec.gitMirror.repositoryReconciler.status.defaultRepositoryLimit;
    const fixtureRepositoryTotal = defaultRepositoryLimit + 2;
    const repositories = Array.from({ length: fixtureRepositoryTotal }, (_, index) => ({
      key: `repo-${index}`,
      repository: `acme/repo-${index}`,
      sourceBranch: "main",
      cacheCommit: String(index).repeat(40),
      cacheRefPresent: true,
      servedCommit: String(index).repeat(40),
      servedRefPresent: true,
      refAligned: true,
      remoteFingerprintAligned: true,
      fresh: true,
    }));
    const summary = {
      ok: true,
      repository: "pikasTech/agentrun",
      sourceBranch: "v0.2",
      gitopsBranch: "nc01-v0.2-gitops",
      sourceCommit: "a".repeat(40),
      gitopsCommit: "b".repeat(40),
      controller: {
        deploymentReady: true,
        configRendered: true,
        workloadRendered: true,
        statusAligned: true,
        heartbeatFresh: true,
      },
      repositories,
      firstDrift: null,
      valuesPrinted: false,
    };
    const observation = {
      ok: true,
      summary,
      raw: JSON.stringify(summary),
      result: { exitCode: 0, stdout: JSON.stringify(summary), stderr: "" },
    } as any;
    const baseOptions = { node: "NC01", lane: "nc01-v02" };
    const compact = renderGitMirrorStatusEnvelope(
      target,
      authority,
      observation,
      { ...baseOptions, full: false, raw: false },
    ) as any;
    expect(compact.summary).toMatchObject({
      repository: "pikasTech/agentrun",
      sourceBranch: "v0.2",
      gitopsBranch: "nc01-v0.2-gitops",
      sourceCommit: "a".repeat(40),
      gitopsCommit: "b".repeat(40),
    });
    expect(compact.summary.repositories).toHaveLength(defaultRepositoryLimit);
    expect(compact.summary.repositoryView).toEqual({
      limit: defaultRepositoryLimit,
      total: fixtureRepositoryTotal,
      shown: defaultRepositoryLimit,
      omitted: fixtureRepositoryTotal - defaultRepositoryLimit,
    });
    expect(compact.target.repositoryView).toEqual({
      limit: defaultRepositoryLimit,
      total: spec.gitMirror.repositories.length,
      shown: spec.gitMirror.repositories.length,
      omitted: 0,
    });
    expect(compact.probe.stdoutTailOmitted).toBe(true);
    expect(compact.disclosure.probeTailOmitted).toBe(true);
    expect(compact.next).toMatchObject({ status: expect.any(String), history: expect.any(String) });
    expect(compact.next.sync).toBeUndefined();

    for (const options of [
      { ...baseOptions, full: true, raw: false },
      { ...baseOptions, full: false, raw: true },
    ]) {
      const expanded = renderGitMirrorStatusEnvelope(target, authority, observation, options) as any;
      expect(expanded.summary.repositories).toHaveLength(fixtureRepositoryTotal);
      expect(expanded.summary.repositoryView).toEqual({
        limit: null,
        total: fixtureRepositoryTotal,
        shown: fixtureRepositoryTotal,
        omitted: 0,
      });
      expect(expanded.target.repositories).toHaveLength(spec.gitMirror.repositories.length);
      expect(expanded.target.repositoryView).toEqual({
        limit: null,
        total: spec.gitMirror.repositories.length,
        shown: spec.gitMirror.repositories.length,
        omitted: 0,
      });
      expect(expanded.probe.stdoutTailOmitted).toBe(!options.raw);
      expect(expanded.probe.stdoutTail).toBe(options.raw ? JSON.stringify(summary) : undefined);
      expect(expanded.disclosure.probeTailOmitted).toBe(!options.raw);
    }
  });

  test("keeps legacy main-repository fields and bounds per-repository probes", () => {
    const spec = resolveAgentRunLaneTarget({ node: "NC01", lane: "nc01-v02" }).spec;
    const script = yamlLaneGitMirrorStatusScript(spec);
    expect(script).toContain("'repository': os.environ.get('REPOSITORY')");
    expect(script).toContain("'sourceCommit': legacy_ref(");
    expect(script).toContain("'gitopsCommit': legacy_ref(");
    expect(script.match(/timeout 20 kubectl/gu)?.length).toBe(spec.gitMirror.repositories.length);
    expect(script.match(/timeout 20 kubectl[^\n]+ &/gu)?.length).toBe(spec.gitMirror.repositories.length);
    expect(script).toContain("remoteFingerprintAligned");
  });
});

function git(args: string[]): string {
  const result = Bun.spawnSync(["git", ...args], { stdout: "pipe", stderr: "pipe" });
  if (result.exitCode !== 0) throw new Error(`git ${args[0]} failed: ${result.stderr.toString()}`);
  return result.stdout.toString().trim();
}

function sha256(value: string): string {
  return createHash("sha256").update(value).digest("hex");
}

function writeControllerConfig(path: string, input: { cache: string; tokenPath: string; askPassFile: string }): void {
  const remote = "https://github.com/acme/example.git";
  const repository = {
    key: "fixture",
    repository: "acme/example",
    remote,
    sourceBranch: "main",
    desiredFingerprint: sha256(["fixture", "acme/example", remote, "main"].join("\0")),
  };
  const desired = {
    schemaVersion: 1,
    kind: "AgentRunManagedRepositoryReconciler",
    nodeId: "fixture-node",
    lane: "fixture-lane",
    cacheMountPath: input.cache,
    stateDirectory: ".managed-state",
    reconcileIntervalMs: 1000,
    fetchTimeoutMs: 10000,
    shutdownGraceMs: 1000,
    maxConcurrentRepositories: 1,
    retry: { maxAttempts: 1, initialDelayMs: 10, maxDelayMs: 10 },
    freshness: { maxAgeMs: 60000 },
    lifecycle: { undeclaredRepositoryPolicy: "retain", managedRefs: "source-branch-only" },
    repositories: [repository],
    remoteAuth: {
      configRef: "config/platform-infra/gitea.yaml#sourceAuthority.credentials.github.gitFetchCredential",
      capabilitySha256: "a".repeat(64),
      authMode: "github-https-token",
      host: "github.com",
      tokenFile: input.tokenPath,
      askPassFile: input.askPassFile,
      proxy: { host: "127.0.0.1", port: 10808 },
    },
  };
  writeFileSync(path, `${JSON.stringify({ ...desired, desiredHash: sha256(JSON.stringify(desired)) }, null, 2)}\n`);
}

function lastJsonLine(output: string): any {
  const lines = output.trim().split("\n");
  return JSON.parse(lines.at(-1) ?? "null");
}

function inheritedHostileGitEnvironment(fakeBin: string, fixtureToken: string): NodeJS.ProcessEnv {
  return {
    ...process.env,
    PATH: `${fakeBin}:${process.env.PATH ?? ""}`,
    GIT_SSH: "/tmp/inherited-git-ssh",
    GIT_SSH_COMMAND: "inherited-ssh-command",
    GIT_CONFIG: "/tmp/inherited-git-config",
    GIT_CONFIG_COUNT: "1",
    GIT_CONFIG_KEY_0: "credential.helper",
    GIT_CONFIG_VALUE_0: "!inherited-credential-helper",
    GIT_SSL_NO_VERIFY: "1",
    GH_TOKEN: fixtureToken,
    GITHUB_TOKEN: fixtureToken,
  };
}

function writeGitShim(input: {
  path: string;
  realGit: string;
  observationPath: string;
  remoteUrl: string;
  replacementRemoteUrl: string;
  failFetchMessage?: string;
}): void {
  writeFileSync(input.path, `#!/usr/bin/env node
import { appendFileSync } from "node:fs";
import { spawnSync } from "node:child_process";
const args = process.argv.slice(2);
appendFileSync(${JSON.stringify(input.observationPath)}, JSON.stringify({
  args,
  inheritedGitSsh: Object.hasOwn(process.env, "GIT_SSH") || Object.hasOwn(process.env, "GIT_SSH_COMMAND"),
  inheritedGitConfig: Object.hasOwn(process.env, "GIT_CONFIG") || Object.hasOwn(process.env, "GIT_CONFIG_COUNT") || Object.keys(process.env).some((key) => /^GIT_CONFIG_(?:KEY|VALUE)_/u.test(key)),
  inheritedGithubToken: Object.hasOwn(process.env, "GH_TOKEN") || Object.hasOwn(process.env, "GITHUB_TOKEN"),
  askPassConfigured: typeof process.env.GIT_ASKPASS === "string" && process.env.GIT_ASKPASS.length > 0 && process.env.GIT_ASKPASS_REQUIRE === "force",
  tlsVerifyForced: process.env.GIT_SSL_NO_VERIFY === "0" && args.includes("http.sslVerify=true"),
}) + "\\n");
if (args.includes("fetch") && ${JSON.stringify(input.failFetchMessage ?? null)} !== null) {
  process.stderr.write(${JSON.stringify(input.failFetchMessage ?? "")} + "\\n");
  process.exit(1);
}
const mapped = args.map((arg) => arg === ${JSON.stringify(input.remoteUrl)} ? ${JSON.stringify(input.replacementRemoteUrl)} : arg);
const result = spawnSync(${JSON.stringify(input.realGit)}, mapped, { env: process.env, stdio: "inherit" });
process.exit(result.status ?? 1);
`);
  chmodSync(input.path, 0o755);
}
