import { createHash } from "node:crypto";
import { isDeepStrictEqual } from "node:util";
import { evaluateRunrailReviewContract } from "./runrail-review-contract-core.mjs";
import { deriveRunrailReviewDecision } from "./runrail-review-policy-core.mjs";

export const RUNRAIL_DEEPSEEK_ADVISORY = Object.freeze({
  artifactType: "runrail-deepseek-candidate-advisory",
  endpoint: "https://api.deepseek.com/chat/completions",
  provider: "deepseek",
  supportedModels: Object.freeze(["deepseek-v4-flash", "deepseek-v4-pro"]),
  productionModel: "deepseek-v4-pro",
  defaultTimeoutMs: 15_000,
  maximumTimeoutMs: 60_000
});

export const RUNRAIL_DEEPSEEK_CANDIDATE_LABELS = Object.freeze({
  RUN_PROJECT_TESTS: "Run project tests locally",
  REVIEW_DEPENDENCY_CHANGES: "Review dependency changes locally",
  REVIEW_SECURITY_SENSITIVE_PATHS: "Review security-sensitive paths locally",
  REVIEW_PYTHON_IMPORTS: "Review Python imports locally",
  MANUAL_REVIEW: "Perform a manual review",
  ABSTAIN: "No advisory candidate selected"
});

const candidateOrder = Object.freeze(Object.keys(RUNRAIL_DEEPSEEK_CANDIDATE_LABELS));
const candidateIdSet = new Set(candidateOrder);
const supportedModelSet = new Set(RUNRAIL_DEEPSEEK_ADVISORY.supportedModels);
const extensionBuckets = Object.freeze([
  ".c",
  ".cpp",
  ".css",
  ".go",
  ".html",
  ".java",
  ".js",
  ".jsx",
  ".json",
  ".md",
  ".mjs",
  ".py",
  ".rb",
  ".rs",
  ".sh",
  ".toml",
  ".ts",
  ".tsx",
  ".yaml",
  ".yml",
  "none",
  "other"
]);
const extensionBucketSet = new Set(extensionBuckets);
const dependencyBasenames = new Set([
  "cargo.lock",
  "cargo.toml",
  "composer.json",
  "composer.lock",
  "deno.json",
  "deno.lock",
  "gemfile",
  "gemfile.lock",
  "go.mod",
  "go.sum",
  "package-lock.json",
  "package.json",
  "pnpm-lock.yaml",
  "poetry.lock",
  "pyproject.toml",
  "requirements.in",
  "requirements.txt",
  "uv.lock",
  "yarn.lock"
]);
const securityPathParts = new Set([
  ".github",
  "auth",
  "authentication",
  "authorization",
  "crypto",
  "iam",
  "permissions",
  "policy",
  "security",
  "secrets"
]);
const testPathParts = new Set(["test", "tests", "__tests__", "spec", "specs"]);
const transmittedFields = Object.freeze([
  "schemaVersion",
  "metadata.auditPassed",
  "metadata.preflightPassed",
  "metadata.projectTestsExecuted",
  "metadata.semanticCorrectnessEvaluated",
  "metadata.securityReviewPerformed",
  "metadata.sourceCheckoutUnchanged",
  "metadata.containmentBoundaryPassed",
  "metadata.changedFileCountBucket",
  "metadata.diffLineCountBucket",
  "metadata.materializedFileCountBucket",
  "metadata.materializedTotalBytesBucket",
  "metadata.changedFileExtensionCounts",
  "metadata.addedChangesPresent",
  "metadata.modifiedChangesPresent",
  "metadata.deletedChangesPresent",
  "metadata.pythonChangesPresent",
  "metadata.dependencyChangesPresent",
  "metadata.securitySensitiveChangesPresent",
  "metadata.testChangesPresent",
  "metadata.secretFindingsPresent",
  "metadata.symlinksPresent",
  "metadata.specialEntriesPresent",
  "metadata.binaryDiffsPresent"
]);

const systemPrompt = [
  "You are a non-authoritative Runrail candidate advisory classifier.",
  "Use only the supplied aggregate buckets, booleans, and allowlisted file-extension counts.",
  "Return exactly one JSON object with exactly candidateIds and confidence.",
  `candidateIds may contain only: ${candidateOrder.join(", ")}.`,
  "ABSTAIN must be the only candidate ID and must use confidence 0.",
  "For any other selection, confidence must be greater than 0 and at most 1.",
  'Example output shape only: {"candidateIds":["RUN_PROJECT_TESTS"],"confidence":0.5}.',
  "Do not return rationale, prose, markdown, commands, patches, verifier choices, answers, apply instructions, or authority."
].join(" ");

export class RunrailDeepSeekAdvisoryError extends Error {
  constructor(code, message) {
    super(message);
    this.name = "RunrailDeepSeekAdvisoryError";
    this.code = code;
  }
}

function fail(code, message) {
  throw new RunrailDeepSeekAdvisoryError(code, message);
}

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

function isRecord(value) {
  if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
  const prototype = Object.getPrototypeOf(value);
  return prototype === Object.prototype || prototype === null;
}

function stableValue(value, seen = new Set()) {
  if (value === null || typeof value === "string" || typeof value === "boolean") return value;
  if (typeof value === "number") {
    if (!Number.isFinite(value)) fail("invalid-json-value", "The value must be finite JSON data.");
    return value;
  }
  if (Array.isArray(value)) {
    if (seen.has(value)) fail("invalid-json-value", "The value must not contain cycles.");
    seen.add(value);
    const result = value.map((entry) => stableValue(entry, seen));
    seen.delete(value);
    return result;
  }
  if (!isRecord(value)) fail("invalid-json-value", "The value must contain only plain JSON objects.");
  if (seen.has(value)) fail("invalid-json-value", "The value must not contain cycles.");
  seen.add(value);
  const result = Object.fromEntries(
    Object.keys(value)
      .sort()
      .map((key) => [key, stableValue(value[key], seen)])
  );
  seen.delete(value);
  return result;
}

function stableJson(value) {
  return `${JSON.stringify(stableValue(value), null, 2)}\n`;
}

function exactKeys(value, expectedKeys, label, code = "invalid-audit") {
  if (!isRecord(value)) fail(code, `${label} must be a plain object.`);
  const actual = Object.keys(value).sort();
  const expected = [...expectedKeys].sort();
  if (actual.length !== expected.length || actual.some((key, index) => key !== expected[index])) {
    fail(code, `${label} has an invalid field set.`);
  }
}

function expectBoolean(value, label) {
  if (typeof value !== "boolean") fail("invalid-audit", `${label} must be a boolean.`);
}

function expectInteger(value, label, minimum = 0, maximum = Number.MAX_SAFE_INTEGER) {
  if (!Number.isSafeInteger(value) || value < minimum || value > maximum) {
    fail("invalid-audit", `${label} must be a bounded integer.`);
  }
}

function expectSha256(value, label) {
  if (typeof value !== "string" || !/^[a-f0-9]{64}$/.test(value)) {
    fail("invalid-audit", `${label} must be a lowercase SHA-256 value.`);
  }
}

function safeAuditPath(value) {
  if (typeof value !== "string" || value.length < 1 || value.length > 240) return false;
  if (value.startsWith("/") || value.includes("\\") || /[\0-\x1f\x7f\u202a-\u202e\u2066-\u2069]/u.test(value)) return false;
  const parts = value.split("/");
  return !parts.includes("") && !parts.includes(".") && !parts.includes("..");
}

function auditBodyWithoutChecksum(audit) {
  return Object.fromEntries(Object.entries(audit).filter(([key]) => key !== "checksumSha256"));
}

export function computeRunrailCandidateAuditChecksum(auditBody) {
  if (!isRecord(auditBody)) fail("invalid-audit", "The audit body must be a plain object.");
  return sha256(stableJson(auditBody));
}

function validateRunrailCandidateAudit(audit) {
  if (!isRecord(audit)) fail("invalid-audit", "A Runrail candidate audit object is required.");
  expectSha256(audit.checksumSha256, "audit.checksumSha256");
  const body = auditBodyWithoutChecksum(audit);
  if (computeRunrailCandidateAuditChecksum(body) !== audit.checksumSha256) {
    fail("audit-checksum-mismatch", "The Runrail candidate audit checksum does not match its content.");
  }

  const topLevelKeys = [
    "schemaVersion",
    "artifactType",
    "product",
    "runId",
    "passed",
    "preflightPassed",
    "scope",
    "source",
    "policy",
    "verifier",
    "materialized",
    "boundaries",
    "checksumSha256"
  ];
  if (audit.schemaVersion >= 2) topLevelKeys.splice(topLevelKeys.indexOf("verifier"), 0, "decision");
  if (audit.schemaVersion >= 4) topLevelKeys.splice(topLevelKeys.indexOf("verifier"), 0, "reviewContract");
  exactKeys(audit, topLevelKeys, "audit");
  if (![1, 2, 3, 4].includes(audit.schemaVersion)) fail("invalid-audit", "The audit schema version must be 1, 2, 3, or 4.");
  if (audit.artifactType !== "runrail-candidate-branch-review") {
    fail("invalid-audit", "The artifact must be a Runrail candidate branch review.");
  }
  if (audit.product !== "Runrail Local v1") fail("invalid-audit", "The audit product identity is invalid.");
  if (typeof audit.runId !== "string" || !/^RRV-[A-F0-9]{16}-[a-f0-9]{8}$/.test(audit.runId)) {
    fail("invalid-audit", "The audit run identifier is invalid.");
  }
  expectBoolean(audit.passed, "audit.passed");
  expectBoolean(audit.preflightPassed, "audit.preflightPassed");
  if (audit.preflightPassed !== audit.passed) fail("invalid-audit", "The audit outcome fields must agree.");

  const scopeKeys = [
    "policyAndSyntaxPreflight",
    "projectTestsExecuted",
    "semanticCorrectnessEvaluated",
    "securityReviewPerformed"
  ];
  if (audit.schemaVersion >= 4) scopeKeys.splice(1, 0, "reviewContractEvaluated");
  exactKeys(audit.scope, scopeKeys, "audit.scope");
  for (const key of Object.keys(audit.scope)) expectBoolean(audit.scope[key], `audit.scope.${key}`);
  if (
    audit.scope.policyAndSyntaxPreflight !== true ||
    (audit.schemaVersion >= 4 && audit.scope.reviewContractEvaluated !== true) ||
    audit.scope.projectTestsExecuted !== false ||
    audit.scope.semanticCorrectnessEvaluated !== false ||
    audit.scope.securityReviewPerformed !== false
  ) {
    fail("invalid-audit", "The candidate review scope boundary is invalid.");
  }

  exactKeys(audit.source, [
    "baseCommit",
    "candidateCommit",
    "sourceCheckoutUnchanged",
    "sourceApplyPerformed"
  ], "audit.source");
  if (!/^[a-f0-9]{40,64}$/.test(audit.source.baseCommit || "")) {
    fail("invalid-audit", "The base commit identity is invalid.");
  }
  if (!/^[a-f0-9]{40,64}$/.test(audit.source.candidateCommit || "")) {
    fail("invalid-audit", "The candidate commit identity is invalid.");
  }
  if (audit.source.baseCommit === audit.source.candidateCommit) {
    fail("invalid-audit", "The candidate commit must differ from the base commit.");
  }
  expectBoolean(audit.source.sourceCheckoutUnchanged, "audit.source.sourceCheckoutUnchanged");
  expectBoolean(audit.source.sourceApplyPerformed, "audit.source.sourceApplyPerformed");
  if (audit.source.sourceApplyPerformed !== false) fail("invalid-audit", "The source apply boundary must remain false.");

  exactKeys(audit.policy, [
    "changedFileCount",
    "changedFiles",
    "diffLineCount",
    "diffSha256",
    "secretFindingCount",
    "pathBoundaryPassed",
    "symlinkCount",
    "specialEntryCount",
    "binaryDiffCount",
    "arbitraryCommandAccepted"
  ], "audit.policy");
  expectInteger(audit.policy.changedFileCount, "audit.policy.changedFileCount", 1, 100);
  if (!Array.isArray(audit.policy.changedFiles) || audit.policy.changedFiles.length !== audit.policy.changedFileCount) {
    fail("invalid-audit", "The changed file rows must match the changed file count.");
  }
  const changedPathSet = new Set();
  for (const row of audit.policy.changedFiles) {
    exactKeys(row, ["status", "path"], "audit.policy.changedFiles row");
    if (!new Set(["A", "M", "D"]).has(row.status) || !safeAuditPath(row.path)) {
      fail("invalid-audit", "A changed file row is invalid.");
    }
    if (changedPathSet.has(row.path)) fail("invalid-audit", "Changed file paths must be unique.");
    changedPathSet.add(row.path);
  }
  expectInteger(audit.policy.diffLineCount, "audit.policy.diffLineCount", 1, 5_000);
  expectSha256(audit.policy.diffSha256, "audit.policy.diffSha256");
  expectInteger(audit.policy.secretFindingCount, "audit.policy.secretFindingCount", 0, 0);
  expectBoolean(audit.policy.pathBoundaryPassed, "audit.policy.pathBoundaryPassed");
  if (audit.policy.pathBoundaryPassed !== true) fail("invalid-audit", "The path boundary must have passed.");
  expectInteger(audit.policy.symlinkCount, "audit.policy.symlinkCount", 0, 0);
  expectInteger(audit.policy.specialEntryCount, "audit.policy.specialEntryCount", 0, 0);
  expectInteger(audit.policy.binaryDiffCount, "audit.policy.binaryDiffCount", 0, 0);
  expectBoolean(audit.policy.arbitraryCommandAccepted, "audit.policy.arbitraryCommandAccepted");
  if (audit.policy.arbitraryCommandAccepted !== false) fail("invalid-audit", "Arbitrary commands must remain disabled.");

  if (audit.schemaVersion >= 4) {
    exactKeys(audit.reviewContract, [
      "profile",
      "contractPath",
      "source",
      "baselineBound",
      "candidateCouldWeakenBaseline",
      "contractSha256",
      "sourceBlobSha256",
      "contract",
      "candidateContractChanged",
      "changedFileBudgetExceeded",
      "diffLineBudgetExceeded",
      "missingCompanionGroupCount",
      "matchedRuleCount",
      "matchedFileCount",
      "unmatchedChangedFileCount",
      "requiredReviewLanes",
      "requiredEvidence",
      "matches",
      "passed"
    ], "audit.reviewContract");
    expectSha256(audit.reviewContract.contractSha256, "audit.reviewContract.contractSha256");
    if (audit.reviewContract.source === "baseline-file") {
      expectSha256(audit.reviewContract.sourceBlobSha256, "audit.reviewContract.sourceBlobSha256");
    } else if (audit.reviewContract.source !== "built-in" || audit.reviewContract.sourceBlobSha256 !== null) {
      fail("invalid-audit", "The review contract source is invalid.");
    }
    if (computeRunrailCandidateAuditChecksum(audit.reviewContract.contract) !== audit.reviewContract.contractSha256) {
      fail("invalid-audit", "The normalized review contract checksum is invalid.");
    }
    const expectedReviewContract = evaluateRunrailReviewContract({
      contract: audit.reviewContract.contract,
      changedFiles: audit.policy.changedFiles,
      diffLineCount: audit.policy.diffLineCount,
      source: audit.reviewContract.source,
      contractSha256: audit.reviewContract.contractSha256,
      sourceBlobSha256: audit.reviewContract.sourceBlobSha256,
      candidateContractChanged: audit.reviewContract.candidateContractChanged
    });
    if (!isDeepStrictEqual(audit.reviewContract, expectedReviewContract)) {
      fail("invalid-audit", "The review contract evaluation does not match the signed audit evidence.");
    }
  }

  if (audit.schemaVersion >= 2) {
    exactKeys(audit.decision, [
      "policyProfile",
      "riskLevel",
      "recommendation",
      "candidateIds",
      "humanApprovalRequired",
      "mergeReady",
      "projectTestsRequired",
      "specialistReviewRequired",
      "findingCounts",
      "findings"
    ], "audit.decision");
    if (audit.decision.policyProfile !== "runrail-review-policy-v1") {
      fail("invalid-audit", "The review policy profile is invalid.");
    }
    if (!new Set(["low", "medium", "high"]).has(audit.decision.riskLevel)) {
      fail("invalid-audit", "The deterministic risk level is invalid.");
    }
    if (!new Set(["manual-review", "project-tests-required", "specialist-review"]).has(audit.decision.recommendation)) {
      fail("invalid-audit", "The deterministic recommendation is invalid.");
    }
    if (!Array.isArray(audit.decision.candidateIds) || audit.decision.candidateIds.length < 1) {
      fail("invalid-audit", "The deterministic candidate list is invalid.");
    }
    const decisionCandidateSet = new Set();
    for (const candidateId of audit.decision.candidateIds) {
      if (!candidateIdSet.has(candidateId) || candidateId === "ABSTAIN" || decisionCandidateSet.has(candidateId)) {
        fail("invalid-audit", "The deterministic candidate list contains an unsupported or duplicate ID.");
      }
      decisionCandidateSet.add(candidateId);
    }
    for (const key of ["humanApprovalRequired", "mergeReady", "projectTestsRequired", "specialistReviewRequired"]) {
      expectBoolean(audit.decision[key], `audit.decision.${key}`);
    }
    if (
      audit.decision.humanApprovalRequired !== true ||
      audit.decision.mergeReady !== false ||
      audit.decision.projectTestsRequired !== true ||
      audit.decision.specialistReviewRequired !== (audit.decision.riskLevel === "high")
    ) {
      fail("invalid-audit", "The deterministic decision boundary is invalid.");
    }
    exactKeys(audit.decision.findingCounts, ["high", "medium", "info"], "audit.decision.findingCounts");
    for (const key of ["high", "medium", "info"]) {
      expectInteger(audit.decision.findingCounts[key], `audit.decision.findingCounts.${key}`, 0, 20);
    }
    if (!Array.isArray(audit.decision.findings) || audit.decision.findings.length < 1 || audit.decision.findings.length > 20) {
      fail("invalid-audit", "The deterministic findings list is invalid.");
    }
    const observedCounts = { high: 0, medium: 0, info: 0 };
    const findingIds = new Set();
    for (const finding of audit.decision.findings) {
      exactKeys(finding, ["id", "severity", "title", "detail", "fileCount"], "audit.decision.findings row");
      if (typeof finding.id !== "string" || !/^[A-Z][A-Z0-9_]{2,63}$/.test(finding.id) || findingIds.has(finding.id)) {
        fail("invalid-audit", "A deterministic finding ID is invalid or duplicated.");
      }
      if (!new Set(["high", "medium", "info"]).has(finding.severity)) {
        fail("invalid-audit", "A deterministic finding severity is invalid.");
      }
      if (typeof finding.title !== "string" || finding.title.length < 3 || finding.title.length > 120) {
        fail("invalid-audit", "A deterministic finding title is invalid.");
      }
      if (typeof finding.detail !== "string" || finding.detail.length < 10 || finding.detail.length > 400) {
        fail("invalid-audit", "A deterministic finding detail is invalid.");
      }
      expectInteger(finding.fileCount, "audit.decision.findings.fileCount", 1, 100);
      findingIds.add(finding.id);
      observedCounts[finding.severity] += 1;
    }
    for (const key of ["high", "medium", "info"]) {
      if (observedCounts[key] !== audit.decision.findingCounts[key]) {
        fail("invalid-audit", "The deterministic finding counts do not match the findings list.");
      }
    }
    const expectedRisk = observedCounts.high > 0 ? "high" : observedCounts.medium > 0 ? "medium" : "low";
    const expectedRecommendation = expectedRisk === "high"
      ? "specialist-review"
      : expectedRisk === "medium"
        ? "project-tests-required"
        : "manual-review";
    if (audit.decision.riskLevel !== expectedRisk || audit.decision.recommendation !== expectedRecommendation) {
      fail("invalid-audit", "The deterministic risk and recommendation do not match the findings.");
    }
  }

  const legacyVerifier = audit.schemaVersion < 4;
  exactKeys(audit.verifier, legacyVerifier ? [
    "profile",
    "commandClass",
    "pythonRuntimeSource",
    "pythonFileCount",
    "passed",
    "returnCode",
    "arbitraryCommandAccepted",
    "repositoryCodeImported",
    "externalPluginsEnabled",
    "osSandboxEnabled",
    "rawOutputStored"
  ] : [
    "profile",
    "commandClass",
    "checks",
    "checkedFileCount",
    "unsupportedChangedSourceFileCount",
    "passed",
    "returnCode",
    "arbitraryCommandAccepted",
    "repositoryCodeImported",
    "projectCodeExecuted",
    "externalPluginsEnabled",
    "osSandboxEnabled",
    "rawOutputStored"
  ], "audit.verifier");
  if (legacyVerifier) {
    if (audit.verifier.profile !== "python-compile") fail("invalid-audit", "The audit verifier profile is invalid.");
    if (audit.verifier.commandClass !== "python-isolated-mode-stdlib-compile") {
      fail("invalid-audit", "The audit verifier class is invalid.");
    }
    if (!new Set(["runrail-pinned-environment", "resolved-system-python"]).has(audit.verifier.pythonRuntimeSource)) {
      fail("invalid-audit", "The audit Python runtime source is invalid.");
    }
    expectInteger(audit.verifier.pythonFileCount, "audit.verifier.pythonFileCount", 1, 2_000);
  } else {
    if (!new Set(["safe-static", "python-compile"]).has(audit.verifier.profile)) {
      fail("invalid-audit", "The audit verifier profile is invalid.");
    }
    const expectedCommandClass = audit.verifier.profile === "safe-static"
      ? "bounded-native-parser-static-validation"
      : "python-isolated-mode-stdlib-compile";
    if (audit.verifier.commandClass !== expectedCommandClass) {
      fail("invalid-audit", "The audit verifier class is invalid.");
    }
    if (!Array.isArray(audit.verifier.checks) || audit.verifier.checks.length < 1 || audit.verifier.checks.length > 4) {
      fail("invalid-audit", "The audit verifier checks are invalid.");
    }
    const languages = new Set();
    let checkedFileCount = 0;
    for (const check of audit.verifier.checks) {
      exactKeys(check, ["language", "parser", "fileCount", "status", "returnCode", "runtimeSource"], "audit.verifier check");
      if (!new Set(["python", "javascript", "json", "typescript"]).has(check.language) || languages.has(check.language)) {
        fail("invalid-audit", "The audit verifier language is invalid.");
      }
      if (typeof check.parser !== "string" || check.parser.length < 8 || check.parser.length > 80) {
        fail("invalid-audit", "The audit verifier parser is invalid.");
      }
      expectInteger(check.fileCount, "audit.verifier.check.fileCount", 0, 2_000);
      if (!new Set(["passed", "failed", "not-applicable"]).has(check.status)) {
        fail("invalid-audit", "The audit verifier status is invalid.");
      }
      expectInteger(check.returnCode, "audit.verifier.check.returnCode", 0, 255);
      if ((check.status === "failed") !== (check.returnCode !== 0)) {
        fail("invalid-audit", "The audit verifier check outcome is inconsistent.");
      }
      if (typeof check.runtimeSource !== "string" || check.runtimeSource.length < 8 || check.runtimeSource.length > 80) {
        fail("invalid-audit", "The audit verifier runtime source is invalid.");
      }
      languages.add(check.language);
      checkedFileCount += check.fileCount;
    }
    if (
      !languages.has("python") ||
      (audit.verifier.profile === "safe-static") !== (languages.has("javascript") && languages.has("json")) ||
      audit.verifier.checkedFileCount !== checkedFileCount
    ) {
      fail("invalid-audit", "The audit verifier language coverage is inconsistent.");
    }
    expectInteger(
      audit.verifier.unsupportedChangedSourceFileCount,
      "audit.verifier.unsupportedChangedSourceFileCount",
      0,
      audit.policy.changedFileCount
    );
  }
  expectBoolean(audit.verifier.passed, "audit.verifier.passed");
  expectInteger(audit.verifier.returnCode, "audit.verifier.returnCode", 0, 255);
  if ((audit.verifier.returnCode === 0) !== audit.verifier.passed) {
    fail("invalid-audit", "The verifier outcome and return code must agree.");
  }
  for (const key of [
    "arbitraryCommandAccepted",
    "repositoryCodeImported",
    ...(legacyVerifier ? [] : ["projectCodeExecuted"]),
    "externalPluginsEnabled",
    "osSandboxEnabled",
    "rawOutputStored"
  ]) {
    expectBoolean(audit.verifier[key], `audit.verifier.${key}`);
    if (audit.verifier[key] !== false) fail("invalid-audit", "The verifier safety boundary is invalid.");
  }

  const materializedKeys = [
    "fileCount",
    "totalBytes",
    "pythonFileCount",
    "regularBlobCount",
    "pathBoundaryCheckedFileCount",
    "postWriteContainmentCheckedCount",
    "gitCheckoutPerformed",
    "gitHookExecutionPathUsed",
    "checkoutFilterPathUsed"
  ];
  if (audit.schemaVersion >= 3) {
    materializedKeys.splice(materializedKeys.indexOf("pathBoundaryCheckedFileCount"), 0, "portablePathIdentityCount");
    materializedKeys.splice(materializedKeys.indexOf("postWriteContainmentCheckedCount"), 0, "materializedHashCheckedCount");
  }
  if (audit.schemaVersion >= 4) {
    materializedKeys.splice(materializedKeys.indexOf("regularBlobCount"), 0, "javaScriptFileCount", "jsonFileCount");
    materializedKeys.splice(materializedKeys.indexOf("gitCheckoutPerformed"), 0, "gitObjectFormat");
  }
  exactKeys(audit.materialized, materializedKeys, "audit.materialized");
  expectInteger(audit.materialized.fileCount, "audit.materialized.fileCount", 1, 2_000);
  expectInteger(audit.materialized.totalBytes, "audit.materialized.totalBytes", 0, 25 * 1024 * 1024);
  expectInteger(
    audit.materialized.pythonFileCount,
    "audit.materialized.pythonFileCount",
    audit.schemaVersion >= 4 ? 0 : 1,
    2_000
  );
  if (audit.schemaVersion >= 4) {
    expectInteger(audit.materialized.javaScriptFileCount, "audit.materialized.javaScriptFileCount", 0, 2_000);
    expectInteger(audit.materialized.jsonFileCount, "audit.materialized.jsonFileCount", 0, 2_000);
  }
  expectInteger(audit.materialized.regularBlobCount, "audit.materialized.regularBlobCount", 1, 2_000);
  if (audit.schemaVersion >= 3) {
    expectInteger(audit.materialized.portablePathIdentityCount, "audit.materialized.portablePathIdentityCount", 1, 2_000);
  }
  expectInteger(audit.materialized.pathBoundaryCheckedFileCount, "audit.materialized.pathBoundaryCheckedFileCount", 1, 2_000);
  if (audit.schemaVersion >= 3) {
    expectInteger(audit.materialized.materializedHashCheckedCount, "audit.materialized.materializedHashCheckedCount", 1, 2_000);
  }
  expectInteger(audit.materialized.postWriteContainmentCheckedCount, "audit.materialized.postWriteContainmentCheckedCount", 1, 2_000);
  if (audit.schemaVersion >= 4 && !new Set(["sha1", "sha256"]).has(audit.materialized.gitObjectFormat)) {
    fail("invalid-audit", "The Git object format evidence is invalid.");
  }
  const pythonCheck = legacyVerifier
    ? null
    : audit.verifier.checks.find((check) => check.language === "python");
  if (
    audit.materialized.regularBlobCount !== audit.materialized.fileCount ||
    (audit.schemaVersion >= 3 && audit.materialized.portablePathIdentityCount !== audit.materialized.fileCount) ||
    audit.materialized.pathBoundaryCheckedFileCount !== audit.materialized.fileCount ||
    (audit.schemaVersion >= 3 && audit.materialized.materializedHashCheckedCount !== audit.materialized.fileCount) ||
    audit.materialized.postWriteContainmentCheckedCount !== audit.materialized.fileCount ||
    (
      legacyVerifier
        ? audit.materialized.pythonFileCount !== audit.verifier.pythonFileCount
        : audit.materialized.pythonFileCount !== pythonCheck?.fileCount
    )
  ) {
    fail("invalid-audit", "The materialized file counts are inconsistent.");
  }
  for (const key of ["gitCheckoutPerformed", "gitHookExecutionPathUsed", "checkoutFilterPathUsed"]) {
    expectBoolean(audit.materialized[key], `audit.materialized.${key}`);
    if (audit.materialized[key] !== false) fail("invalid-audit", "The materialization safety boundary is invalid.");
  }

  exactKeys(audit.boundaries, [
    "networkRequired",
    "browserExecutionEnabled",
    "repositoryUploadEnabled",
    "automaticSourceApplyEnabled",
    "osSandboxEnabled",
    "localOperatorMachineTrustRequired",
    "learnedRuntimeAuthorityAdded"
  ], "audit.boundaries");
  for (const key of Object.keys(audit.boundaries)) expectBoolean(audit.boundaries[key], `audit.boundaries.${key}`);
  if (
    audit.boundaries.networkRequired !== false ||
    audit.boundaries.browserExecutionEnabled !== false ||
    audit.boundaries.repositoryUploadEnabled !== false ||
    audit.boundaries.automaticSourceApplyEnabled !== false ||
    audit.boundaries.osSandboxEnabled !== false ||
    audit.boundaries.localOperatorMachineTrustRequired !== true ||
    audit.boundaries.learnedRuntimeAuthorityAdded !== false
  ) {
    fail("invalid-audit", "The candidate audit boundary fields are invalid.");
  }
  if (
    audit.passed !== (
      audit.verifier.passed &&
      audit.source.sourceCheckoutUnchanged &&
      (audit.schemaVersion < 4 || audit.reviewContract.passed)
    )
  ) {
    fail("invalid-audit", "The candidate audit outcome is inconsistent with local preflight evidence.");
  }
  if (audit.schemaVersion >= 2) {
    const expectedDecision = deriveRunrailReviewDecision({
      changedFiles: audit.policy.changedFiles,
      diffLineCount: audit.policy.diffLineCount,
      verifierPassed: audit.verifier.passed,
      reviewContract: audit.schemaVersion >= 4 ? audit.reviewContract : null
    });
    if (!isDeepStrictEqual(audit.decision, expectedDecision)) {
      fail("invalid-audit", "The deterministic decision does not match the signed audit evidence.");
    }
  }
  return audit;
}

export function verifyRunrailCandidateAudit(audit) {
  validateRunrailCandidateAudit(audit);
  return true;
}

function extensionBucket(relativePath) {
  const basename = relativePath.split("/").at(-1).toLowerCase();
  const dot = basename.lastIndexOf(".");
  if (dot <= 0 || dot === basename.length - 1) return "none";
  const extension = basename.slice(dot);
  return extensionBucketSet.has(extension) && extension !== "none" && extension !== "other" ? extension : "other";
}

function isDependencyPath(relativePath) {
  const basename = relativePath.toLowerCase().split("/").at(-1);
  return dependencyBasenames.has(basename) || /^requirements(?:-[a-z0-9_.-]+)?\.txt$/.test(basename);
}

function isSecuritySensitivePath(relativePath) {
  const parts = relativePath.toLowerCase().split("/");
  const basename = parts.at(-1);
  return (
    parts.some((part) => securityPathParts.has(part)) ||
    /(?:^|[._-])(auth|crypto|permission|policy|security|secret)(?:[._-]|$)/.test(basename)
  );
}

function isTestPath(relativePath) {
  const parts = relativePath.toLowerCase().split("/");
  const basename = parts.at(-1);
  return (
    parts.some((part) => testPathParts.has(part)) ||
    /(?:^|[._-])(test|spec)(?:[._-]|$)/.test(basename)
  );
}

function deriveMetadataFromValidatedAudit(audit) {
  const extensionCounts = Object.fromEntries(extensionBuckets.map((extension) => [extension, 0]));
  let addedChangesPresent = false;
  let modifiedChangesPresent = false;
  let deletedChangesPresent = false;
  let pythonChangesPresent = false;
  let dependencyChangesPresent = false;
  let securitySensitiveChangesPresent = false;
  let testChangesPresent = false;

  for (const row of audit.policy.changedFiles) {
    if (row.status === "A") addedChangesPresent = true;
    if (row.status === "M") modifiedChangesPresent = true;
    if (row.status === "D") deletedChangesPresent = true;
    const extension = extensionBucket(row.path);
    extensionCounts[extension] += 1;
    if (extension === ".py") pythonChangesPresent = true;
    if (isDependencyPath(row.path)) dependencyChangesPresent = true;
    if (isSecuritySensitivePath(row.path)) securitySensitiveChangesPresent = true;
    if (isTestPath(row.path)) testChangesPresent = true;
  }

  const changedFileExtensionCounts = Object.fromEntries(
    extensionBuckets.filter((extension) => extensionCounts[extension] > 0).map((extension) => [extension, extensionCounts[extension]])
  );
  return {
    auditPassed: audit.passed,
    preflightPassed: audit.preflightPassed,
    projectTestsExecuted: audit.scope.projectTestsExecuted,
    semanticCorrectnessEvaluated: audit.scope.semanticCorrectnessEvaluated,
    securityReviewPerformed: audit.scope.securityReviewPerformed,
    sourceCheckoutUnchanged: audit.source.sourceCheckoutUnchanged,
    containmentBoundaryPassed: audit.policy.pathBoundaryPassed,
    changedFileCountBucket: {
      oneToFive: audit.policy.changedFileCount <= 5,
      sixToTwenty: audit.policy.changedFileCount >= 6 && audit.policy.changedFileCount <= 20,
      twentyOneToOneHundred: audit.policy.changedFileCount >= 21
    },
    diffLineCountBucket: {
      upToOneHundred: audit.policy.diffLineCount <= 100,
      oneHundredOneToOneThousand: audit.policy.diffLineCount >= 101 && audit.policy.diffLineCount <= 1_000,
      oneThousandOneToFiveThousand: audit.policy.diffLineCount >= 1_001
    },
    materializedFileCountBucket: {
      upToOneHundred: audit.materialized.fileCount <= 100,
      oneHundredOneToFiveHundred: audit.materialized.fileCount >= 101 && audit.materialized.fileCount <= 500,
      fiveHundredOneToTwoThousand: audit.materialized.fileCount >= 501
    },
    materializedTotalBytesBucket: {
      upToOneMiB: audit.materialized.totalBytes <= 1024 * 1024,
      oneMiBToTenMiB: audit.materialized.totalBytes > 1024 * 1024 && audit.materialized.totalBytes <= 10 * 1024 * 1024,
      tenMiBToTwentyFiveMiB: audit.materialized.totalBytes > 10 * 1024 * 1024
    },
    changedFileExtensionCounts,
    addedChangesPresent,
    modifiedChangesPresent,
    deletedChangesPresent,
    pythonChangesPresent,
    dependencyChangesPresent,
    securitySensitiveChangesPresent,
    testChangesPresent,
    secretFindingsPresent: audit.policy.secretFindingCount > 0,
    symlinksPresent: audit.policy.symlinkCount > 0,
    specialEntriesPresent: audit.policy.specialEntryCount > 0,
    binaryDiffsPresent: audit.policy.binaryDiffCount > 0
  };
}

export function deriveRunrailCandidateAuditMetadata(audit) {
  return deriveMetadataFromValidatedAudit(validateRunrailCandidateAudit(audit));
}

function buildRequest(model, metadata) {
  const body = {
    model,
    messages: [
      { role: "system", content: systemPrompt },
      { role: "user", content: stableJson({ schemaVersion: 1, metadata }) }
    ],
    response_format: { type: "json_object" },
    thinking: { type: "disabled" },
    temperature: 0,
    stream: false,
    max_tokens: 160
  };
  const bodyText = stableJson(body);
  return { bodyText, requestSha256: sha256(bodyText) };
}

function productionTransport(url, init) {
  return fetch(url, init);
}

function readByokEnvironment(environment) {
  if (!environment || typeof environment !== "object") {
    fail("advisory-disabled", "The Runrail DeepSeek candidate advisory is disabled.");
  }
  if (environment.RUNRAIL_DEEPSEEK_ADVISORY_ENABLED !== "true") {
    fail("advisory-disabled", "RUNRAIL_DEEPSEEK_ADVISORY_ENABLED must be exactly true.");
  }
  const apiKey = environment.RUNRAIL_DEEPSEEK_ADVISORY_API_KEY;
  if (typeof apiKey !== "string" || apiKey.trim() === "" || apiKey.length > 4_096) {
    fail("api-key-required", "RUNRAIL_DEEPSEEK_ADVISORY_API_KEY is required.");
  }
  return apiKey.trim();
}

async function sendWithTimeout({ transport, apiKey, bodyText, timeoutMs }) {
  const controller = new AbortController();
  let timeoutHandle;
  const timeout = new Promise((_, reject) => {
    timeoutHandle = setTimeout(() => {
      controller.abort();
      reject(new RunrailDeepSeekAdvisoryError("provider-timeout", "The DeepSeek candidate advisory request timed out."));
    }, timeoutMs);
  });
  try {
    return await Promise.race([
      Promise.resolve().then(() => transport(RUNRAIL_DEEPSEEK_ADVISORY.endpoint, {
        method: "POST",
        headers: {
          Accept: "application/json",
          Authorization: `Bearer ${apiKey}`,
          "Content-Type": "application/json"
        },
        body: bodyText,
        signal: controller.signal
      })),
      timeout
    ]);
  } catch (error) {
    if (error instanceof RunrailDeepSeekAdvisoryError) throw error;
    fail("provider-error", "The DeepSeek candidate advisory provider request failed.");
  } finally {
    clearTimeout(timeoutHandle);
  }
}

function responseIsSuccessful(response) {
  if (!response || typeof response !== "object") return false;
  if (typeof response.ok === "boolean") return response.ok;
  return Number.isInteger(response.status) && response.status >= 200 && response.status < 300;
}

async function readProviderBody(response) {
  if (!responseIsSuccessful(response)) fail("provider-error", "The DeepSeek candidate advisory provider returned an error.");
  if (typeof response.text !== "function") fail("provider-error", "The DeepSeek candidate advisory provider response is unreadable.");
  let content;
  try {
    content = await response.text();
  } catch {
    fail("provider-error", "The DeepSeek candidate advisory provider response is unreadable.");
  }
  if (typeof content !== "string" || content.trim() === "") {
    fail("empty-provider-response", "The DeepSeek candidate advisory provider returned an empty response.");
  }
  if (Buffer.byteLength(content, "utf8") > 128 * 1024) {
    fail("provider-response-too-large", "The DeepSeek candidate advisory provider response exceeded the size limit.");
  }
  return content;
}

function parseProviderEnvelope(content) {
  let envelope;
  try {
    envelope = JSON.parse(content);
  } catch {
    fail("invalid-provider-json", "The DeepSeek candidate advisory provider response was not valid JSON.");
  }
  if (!isRecord(envelope) || !Array.isArray(envelope.choices) || envelope.choices.length !== 1) {
    fail("invalid-provider-response", "The DeepSeek candidate advisory provider response shape is invalid.");
  }
  const choice = envelope.choices[0];
  if (
    !isRecord(choice) ||
    choice.finish_reason !== "stop" ||
    !isRecord(choice.message) ||
    typeof choice.message.content !== "string"
  ) {
    fail("invalid-provider-response", "The DeepSeek candidate advisory provider response shape is invalid.");
  }
  const candidateContent = choice.message.content.trim();
  if (candidateContent === "") fail("empty-provider-content", "The DeepSeek candidate advisory provider returned no candidate content.");
  return candidateContent;
}

function parseCandidateSelection(candidateContent) {
  let selection;
  try {
    selection = JSON.parse(candidateContent);
  } catch {
    fail("invalid-advisory-json", "The DeepSeek candidate selection was not valid JSON.");
  }
  exactKeys(selection, ["candidateIds", "confidence"], "candidate selection", "invalid-advisory-schema");
  if (!Array.isArray(selection.candidateIds) || selection.candidateIds.length < 1 || selection.candidateIds.length > 5) {
    fail("invalid-advisory-schema", "The candidate ID list is invalid.");
  }
  if (selection.candidateIds.some((id) => typeof id !== "string" || !candidateIdSet.has(id))) {
    fail("invalid-advisory-schema", "The response contains an unknown candidate ID.");
  }
  if (new Set(selection.candidateIds).size !== selection.candidateIds.length) {
    fail("invalid-advisory-schema", "The candidate IDs must be unique.");
  }
  if (typeof selection.confidence !== "number" || !Number.isFinite(selection.confidence)) {
    fail("invalid-advisory-schema", "The candidate confidence must be a finite number.");
  }
  const abstained = selection.candidateIds.includes("ABSTAIN");
  if (abstained && (selection.candidateIds.length !== 1 || selection.confidence !== 0)) {
    fail("invalid-advisory-schema", "ABSTAIN must be the only candidate ID with confidence 0.");
  }
  if (!abstained && (selection.confidence <= 0 || selection.confidence > 1)) {
    fail("invalid-advisory-schema", "Candidate confidence must be greater than 0 and at most 1.");
  }
  return {
    candidateIds: candidateOrder.filter((id) => selection.candidateIds.includes(id)),
    confidence: selection.confidence,
    abstained
  };
}

function buildArtifact({ audit, model, selection, requestSha256, responseSha256 }) {
  return {
    schemaVersion: 1,
    artifactType: RUNRAIL_DEEPSEEK_ADVISORY.artifactType,
    advisoryOnly: true,
    provider: RUNRAIL_DEEPSEEK_ADVISORY.provider,
    model,
    candidateIds: selection.candidateIds,
    candidates: selection.candidateIds.map((id) => ({ id, label: RUNRAIL_DEEPSEEK_CANDIDATE_LABELS[id] })),
    abstained: selection.abstained,
    confidence: selection.confidence,
    authority: "none",
    sourceChecksumSha256: audit.checksumSha256,
    requestSha256,
    responseSha256,
    transmittedFields: [...transmittedFields],
    redactions: {
      auditRunIdTransmitted: false,
      rawSourceTransmitted: false,
      rawDiffTransmitted: false,
      filePathsTransmitted: false,
      fileNamesTransmitted: false,
      commitIdsTransmitted: false,
      sourceChecksumTransmitted: false,
      diffHashTransmitted: false,
      repositoryIdentityTransmitted: false,
      taskTextTransmitted: false,
      apiKeyPersisted: false,
      apiKeyLogged: false,
      rawProviderContentPersisted: false,
      rawProviderContentLogged: false
    }
  };
}

async function requestCandidateAdvisoryForTest(options = {}) {
  exactKeys(
    options,
    ["audit", "allowNetwork", "environment", "model", "transport", "timeoutMs"],
    "test-only candidate advisory options",
    "invalid-options"
  );
  const { audit, allowNetwork, environment, model, transport, timeoutMs } = options;
  if (allowNetwork !== true) {
    fail("network-consent-required", "Explicit allowNetwork true consent is required for a DeepSeek candidate advisory request.");
  }
  const apiKey = readByokEnvironment(environment);
  if (!supportedModelSet.has(model)) fail("unsupported-model", "The selected DeepSeek candidate advisory model is not supported.");
  if (typeof transport !== "function") fail("invalid-transport", "The candidate advisory transport must be a function.");
  if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > RUNRAIL_DEEPSEEK_ADVISORY.maximumTimeoutMs) {
    fail("invalid-timeout", "The candidate advisory timeout must be a bounded positive integer.");
  }

  const verifiedAudit = validateRunrailCandidateAudit(audit);
  if (verifiedAudit.passed !== true || verifiedAudit.preflightPassed !== true) {
    fail("preflight-not-passed", "DeepSeek candidate advisory requires a passing local Runrail preflight.");
  }
  const metadata = deriveMetadataFromValidatedAudit(verifiedAudit);
  const request = buildRequest(model, metadata);
  const response = await sendWithTimeout({ transport, apiKey, bodyText: request.bodyText, timeoutMs });
  const providerContent = await readProviderBody(response);
  const selection = parseCandidateSelection(parseProviderEnvelope(providerContent));
  return buildArtifact({
    audit: verifiedAudit,
    model,
    selection,
    requestSha256: request.requestSha256,
    responseSha256: sha256(providerContent)
  });
}

export const RUNRAIL_DEEPSEEK_ADVISORY_TEST_ONLY = Object.freeze({
  requestCandidateAdvisory: requestCandidateAdvisoryForTest
});

export async function runRunrailDeepSeekCandidateAdvisory(options = {}) {
  exactKeys(options, ["audit", "allowNetwork"], "candidate advisory options", "invalid-options");
  return requestCandidateAdvisoryForTest({
    audit: options.audit,
    allowNetwork: options.allowNetwork,
    environment: process.env,
    model: RUNRAIL_DEEPSEEK_ADVISORY.productionModel,
    transport: productionTransport,
    timeoutMs: RUNRAIL_DEEPSEEK_ADVISORY.defaultTimeoutMs
  });
}
