import { createHash } from "node:crypto";
import { lstat, readFile, realpath } from "node:fs/promises";
import path from "node:path";
import {
  evaluateRunrailReviewSession,
  listRunrailReviewDispositions,
  listRunrailReviewSessions,
  verifyRunrailAuditV4,
  verifyRunrailReviewDisposition,
  verifyRunrailReviewSession
} from "./runrail-review-session-core.mjs";
import { verifyRunrailReviewPassport } from "./runrail-review-passport-core.mjs";

export const RUNRAIL_TRUST_PROFILE = Object.freeze({
  schemaVersion: 1,
  artifactType: "runrail-repository-trust-profile",
  profile: "runrail-repository-trust-profile-v1",
  weeklyArtifactType: "runrail-weekly-engineering-report",
  weeklyProfile: "runrail-weekly-engineering-report-v1",
  product: "Runrail Local v1",
  maximumReviews: 100,
  maximumTimelineEntries: 100,
  maximumRecurringFindings: 20
});

const SHA256_PATTERN = /^[a-f0-9]{64}$/;
const REPO_FINGERPRINT_PATTERN = /^RRF-[A-F0-9]{64}$/;
const REVIEW_ID_PATTERN = /^RRS-[A-F0-9]{24}$/;
const FINDING_ID_PATTERN = /^[A-Z][A-Z0-9_]{2,63}$/;
const MAX_AUDIT_BYTES = 2 * 1024 * 1024;
const MAX_PASSPORT_BYTES = 512 * 1024;
const verdicts = Object.freeze([
  "blocked",
  "needs-attention",
  "ready-for-human-decision"
]);

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

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

function isRecord(value) {
  return value !== null && typeof value === "object" && !Array.isArray(value);
}

function stableValue(value) {
  if (Array.isArray(value)) return value.map(stableValue);
  if (isRecord(value)) {
    return Object.fromEntries(
      Object.keys(value)
        .sort()
        .map((key) => [key, stableValue(value[key])])
    );
  }
  return value;
}

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

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

export function computeRunrailTrustProfileChecksum(value) {
  return sha256(stableRunrailTrustProfileJson(value));
}

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

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

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

function expectSha256(value, label, { nullable = false } = {}) {
  if (nullable && value === null) return;
  if (!SHA256_PATTERN.test(String(value || ""))) {
    fail("trust-profile-invalid", `${label} must be a SHA-256 digest.`);
  }
}

function canonicalTimestamp(value, label) {
  if (
    typeof value !== "string" ||
    !Number.isFinite(Date.parse(value)) ||
    new Date(value).toISOString() !== value
  ) {
    fail("trust-profile-invalid", `${label} must be a canonical UTC timestamp.`);
  }
  return value;
}

function canonicalNow(value = new Date()) {
  const parsed = value instanceof Date ? new Date(value.getTime()) : new Date(value);
  if (!Number.isFinite(parsed.getTime())) {
    fail("trust-profile-time-invalid", "The Trust Profile clock is invalid.");
  }
  return parsed;
}

function compareText(left, right) {
  return left < right ? -1 : left > right ? 1 : 0;
}

function compareSessionsOldestFirst(left, right) {
  const byTime = compareText(left.createdAt, right.createdAt);
  return byTime || compareText(left.reviewId, right.reviewId);
}

function isInsideOrEqual(candidate, parent) {
  const relative = path.relative(parent, candidate);
  return relative === "" || (
    relative !== ".." &&
    !relative.startsWith(`..${path.sep}`) &&
    !path.isAbsolute(relative)
  );
}

async function readOptionalVerifiedJson({
  filePath,
  artifactRootPath,
  maximumBytes,
  expectedFileSha256 = null,
  label
}) {
  let rootEntry;
  try {
    rootEntry = await lstat(artifactRootPath);
  } catch {
    return null;
  }
  if (!rootEntry.isDirectory() || rootEntry.isSymbolicLink()) {
    fail("trust-profile-artifact-invalid", `${label} root is not an ordinary directory.`);
  }
  const canonicalRoot = await realpath(artifactRootPath);
  if (canonicalRoot !== path.resolve(artifactRootPath)) {
    fail("trust-profile-artifact-invalid", `${label} root traverses a symbolic link.`);
  }
  const normalizedPath = path.resolve(filePath);
  if (!isInsideOrEqual(normalizedPath, canonicalRoot) || normalizedPath === canonicalRoot) {
    fail("trust-profile-artifact-boundary", `${label} escaped its local artifact root.`);
  }
  let entry;
  try {
    entry = await lstat(normalizedPath);
  } catch {
    return null;
  }
  if (
    !entry.isFile() ||
    entry.isSymbolicLink() ||
    entry.size < 2 ||
    entry.size > maximumBytes
  ) {
    fail("trust-profile-artifact-invalid", `${label} is not a bounded ordinary file.`);
  }
  const canonicalPath = await realpath(normalizedPath);
  if (canonicalPath !== normalizedPath || !isInsideOrEqual(canonicalPath, canonicalRoot)) {
    fail("trust-profile-artifact-boundary", `${label} traverses a symbolic link.`);
  }
  const bytes = await readFile(canonicalPath);
  if (
    expectedFileSha256 !== null &&
    sha256(bytes) !== expectedFileSha256
  ) {
    fail("trust-profile-artifact-tampered", `${label} no longer matches its immutable session.`);
  }
  try {
    return JSON.parse(bytes.toString("utf8"));
  } catch {
    fail("trust-profile-artifact-invalid", `${label} is not valid JSON.`);
  }
}

function latestDispositionMap(dispositions) {
  const latest = new Map();
  for (const disposition of dispositions) {
    verifyRunrailReviewDisposition(disposition);
    latest.set(disposition.findingId, disposition);
  }
  return latest;
}

function dispositionSummary(dispositions, now) {
  const latest = [...latestDispositionMap(dispositions).values()];
  const counts = {
    totalCount: dispositions.length,
    currentFindingCount: latest.length,
    usefulCount: 0,
    notRelevantCount: 0,
    acceptedExceptionCount: 0,
    activeExceptionCount: 0,
    expiredExceptionCount: 0
  };
  const expired = [];
  for (const disposition of latest) {
    if (disposition.kind === "useful") counts.usefulCount += 1;
    if (disposition.kind === "not-relevant") counts.notRelevantCount += 1;
    if (disposition.kind !== "accepted-exception") continue;
    counts.acceptedExceptionCount += 1;
    if (Date.parse(disposition.expiresAt) > now.getTime()) {
      counts.activeExceptionCount += 1;
    } else {
      counts.expiredExceptionCount += 1;
      expired.push({
        reviewId: disposition.reviewId,
        findingId: disposition.findingId,
        expiresAt: disposition.expiresAt
      });
    }
  }
  return { counts, expired };
}

function attentionCount(verdict, coverageSummary) {
  return (
    Number(coverageSummary.unreviewedCount || 0) +
    Number(coverageSummary.needsRevisionCount || 0) +
    verdict.unresolvedHighFindingIds.length +
    verdict.unresolvedMediumFindingIds.length
  );
}

function cadenceForSessions(
  sessions,
  generatedAt,
  { historyTruncated = false } = {}
) {
  const times = sessions.map((session) => Date.parse(session.createdAt));
  const intervals = times.slice(1).map((time, index) => time - times[index]);
  const averageIntervalHours = intervals.length === 0
    ? null
    : Math.round(
        intervals.reduce((total, value) => total + value, 0) /
        intervals.length /
        3_600_000
      );
  const reviewedLast7Days = times.filter(
    (time) => time >= generatedAt.getTime() - 7 * 86_400_000
  ).length;
  let label = "new";
  if (averageIntervalHours !== null) {
    if (averageIntervalHours <= 36) label = "daily";
    else if (averageIntervalHours <= 240) label = "weekly";
    else if (averageIntervalHours <= 960) label = "monthly";
    else label = "occasional";
  }
  return {
    reviewCount: sessions.length,
    firstReviewAt: sessions.at(0)?.createdAt || null,
    latestReviewAt: sessions.at(-1)?.createdAt || null,
    reviewedLast7Days,
    averageIntervalHours,
    label,
    historyTruncated,
    historyEntryLimit: RUNRAIL_TRUST_PROFILE.maximumReviews
  };
}

function preferredBase(sessions) {
  const counts = new Map();
  for (const session of sessions) {
    const current = counts.get(session.local.baseRef) || {
      ref: session.local.baseRef,
      count: 0,
      latestAt: ""
    };
    current.count += 1;
    if (session.createdAt > current.latestAt) current.latestAt = session.createdAt;
    counts.set(session.local.baseRef, current);
  }
  return [...counts.values()].sort(
    (left, right) =>
      right.count - left.count ||
      compareText(right.latestAt, left.latestAt) ||
      compareText(left.ref, right.ref)
  )[0]?.ref || null;
}

function sourceFreeStack(session) {
  return {
    trackedFileCount: session.discovery.languageStack.trackedFileCount,
    recognizedFileCount: session.discovery.languageStack.recognizedFileCount,
    otherFileCount: session.discovery.languageStack.otherFileCount,
    languages: session.discovery.languageStack.languages.map((row) => ({
      id: row.id,
      label: row.label,
      fileCount: row.fileCount
    })),
    truncated: session.discovery.languageStack.truncated
  };
}

export function buildRunrailRepositoryTrustProfile({
  sessions,
  dispositionsByReviewId = new Map(),
  artifactsByReviewId = new Map(),
  generatedAt = new Date(),
  historyTruncated = false
}) {
  const clock = canonicalNow(generatedAt);
  if (typeof historyTruncated !== "boolean") {
    fail("trust-profile-input-invalid", "Trust Profile truncation metadata must be boolean.");
  }
  if (
    !Array.isArray(sessions) ||
    sessions.length < 1 ||
    sessions.length > RUNRAIL_TRUST_PROFILE.maximumReviews
  ) {
    fail("trust-profile-input-invalid", "A Trust Profile requires one to 100 review sessions.");
  }
  const ordered = [...sessions].sort(compareSessionsOldestFirst);
  for (const session of ordered) verifyRunrailReviewSession(session);
  const repoFingerprint = ordered[0].repoFingerprint;
  if (ordered.some((session) => session.repoFingerprint !== repoFingerprint)) {
    fail("trust-profile-input-invalid", "A Trust Profile cannot combine repositories.");
  }
  if (new Set(ordered.map((session) => session.reviewId)).size !== ordered.length) {
    fail("trust-profile-input-invalid", "A Trust Profile cannot contain duplicate review sessions.");
  }
  const sessionById = new Map(ordered.map((session) => [session.reviewId, session]));
  const rows = [];
  const aggregateDispositions = {
    totalCount: 0,
    currentFindingCount: 0,
    usefulCount: 0,
    notRelevantCount: 0,
    acceptedExceptionCount: 0,
    activeExceptionCount: 0,
    expiredExceptionCount: 0
  };
  const expiredExceptions = [];
  const findingOccurrences = new Map();
  const verdictCounts = Object.fromEntries(verdicts.map((verdict) => [verdict, 0]));
  let verdictChangeCount = 0;
  let attentionItemClosedCount = 0;
  let attentionItemOpenedCount = 0;
  let contractChangeCount = 0;
  let parentLinkedCount = 0;
  let passportChecksumCount = 0;
  let artifactGapCount = 0;

  for (const session of ordered) {
    const dispositions = dispositionsByReviewId instanceof Map
      ? dispositionsByReviewId.get(session.reviewId) || []
      : dispositionsByReviewId[session.reviewId] || [];
    if (!Array.isArray(dispositions)) {
      fail("trust-profile-input-invalid", "Trust Profile dispositions must be arrays.");
    }
    const evaluated = evaluateRunrailReviewSession(session, dispositions, { now: clock });
    const disposition = dispositionSummary(dispositions, clock);
    for (const key of Object.keys(aggregateDispositions)) {
      aggregateDispositions[key] += disposition.counts[key];
    }
    expiredExceptions.push(...disposition.expired);
    verdictCounts[evaluated.status] += 1;
    for (const findingId of [
      ...session.evidence.findingIds.high,
      ...session.evidence.findingIds.medium,
      ...session.evidence.findingIds.info
    ]) {
      findingOccurrences.set(findingId, (findingOccurrences.get(findingId) || 0) + 1);
    }
    const artifacts = artifactsByReviewId instanceof Map
      ? artifactsByReviewId.get(session.reviewId) || {}
      : artifactsByReviewId[session.reviewId] || {};
    const policyFingerprint = artifacts.policyFingerprint || null;
    const passportChecksumSha256 = artifacts.passportChecksumSha256 || null;
    expectSha256(policyFingerprint, "Policy fingerprint", { nullable: true });
    expectSha256(passportChecksumSha256, "Passport checksum", { nullable: true });
    if (passportChecksumSha256) passportChecksumCount += 1;
    if (!policyFingerprint || !passportChecksumSha256) artifactGapCount += 1;

    const parent = session.parentReviewId
      ? sessionById.get(session.parentReviewId) || null
      : null;
    const parentRow = parent
      ? rows.find((row) => row.reviewId === parent.reviewId) || null
      : null;
    if (parent) parentLinkedCount += 1;
    const currentAttention = attentionCount(
      evaluated,
      session.evidence.coverageSummary
    );
    const previousAttention = parentRow?.attentionItemCount ?? null;
    const attentionClosedCount = previousAttention === null
      ? 0
      : Math.max(0, previousAttention - currentAttention);
    const attentionOpenedCount = previousAttention === null
      ? currentAttention
      : Math.max(0, currentAttention - previousAttention);
    const policyChanged = Boolean(
      parentRow &&
      parentRow.policyFingerprint &&
      policyFingerprint &&
      parentRow.policyFingerprint !== policyFingerprint
    );
    const verdictChanged = Boolean(
      parentRow && parentRow.verdict !== evaluated.status
    );
    if (verdictChanged) verdictChangeCount += 1;
    if (policyChanged) contractChangeCount += 1;
    attentionItemClosedCount += attentionClosedCount;
    attentionItemOpenedCount += attentionOpenedCount;
    rows.push({
      reviewId: session.reviewId,
      parentReviewId: session.parentReviewId,
      createdAt: session.createdAt,
      verdict: evaluated.status,
      previousVerdict: parentRow?.verdict || null,
      verdictChanged,
      attentionItemCount: currentAttention,
      attentionClosedCount,
      attentionOpenedCount,
      contractPassed: session.evidence.contractPassed,
      policyFingerprint,
      policyChanged,
      passportChecksumSha256,
      dispositionCount: disposition.counts.totalCount,
      activeExceptionCount: disposition.counts.activeExceptionCount,
      expiredExceptionCount: disposition.counts.expiredExceptionCount
    });
  }

  const recurringFindings = [...findingOccurrences.entries()]
    .filter(([, occurrenceCount]) => occurrenceCount > 1)
    .sort(
      (left, right) =>
        right[1] - left[1] ||
        compareText(left[0], right[0])
    )
    .slice(0, RUNRAIL_TRUST_PROFILE.maximumRecurringFindings)
    .map(([findingId, occurrenceCount]) => ({ findingId, occurrenceCount }));
  const currentPolicyFingerprint = rows.at(-1).policyFingerprint;
  const policyRecommendations = [];
  if (contractChangeCount > 0) {
    policyRecommendations.push({
      id: "REVIEW_POLICY_FINGERPRINT_CHANGES",
      reason: "The base-owned review contract changed across related local reviews."
    });
  }
  if (recurringFindings.length > 0) {
    policyRecommendations.push({
      id: "REVIEW_RECURRING_FINDINGS",
      reason: "One or more deterministic finding IDs recurred across local reviews."
    });
  }
  if (aggregateDispositions.expiredExceptionCount > 0) {
    policyRecommendations.push({
      id: "REVIEW_EXPIRED_EXCEPTIONS",
      reason: "One or more accepted exceptions expired and no longer affect the verdict."
    });
  }
  const latest = ordered.at(-1);
  const body = {
    schemaVersion: RUNRAIL_TRUST_PROFILE.schemaVersion,
    artifactType: RUNRAIL_TRUST_PROFILE.artifactType,
    profile: RUNRAIL_TRUST_PROFILE.profile,
    product: RUNRAIL_TRUST_PROFILE.product,
    repoFingerprint,
    generatedAt: clock.toISOString(),
    preferredBase: preferredBase(ordered),
    stack: sourceFreeStack(latest),
    reviewCadence: cadenceForSessions(ordered, clock, { historyTruncated }),
    policy: {
      authoritativeSource: "base-commit-only",
      currentFingerprint: currentPolicyFingerprint,
      contractChangeCount,
      recommendationAuthority: "advisory-only",
      recommendedChanges: policyRecommendations,
      automaticPolicyWrites: false,
      automaticPolicyLearning: false
    },
    dispositions: aggregateDispositions,
    trends: {
      verdictCounts,
      verdictChangeCount,
      attentionItemClosedCount,
      attentionItemOpenedCount,
      recurringFindings
    },
    continuity: {
      reviewCount: rows.length,
      parentLinkedCount,
      passportChecksumCount,
      artifactGapCount,
      latestPassportChecksumSha256:
        rows.at(-1).passportChecksumSha256,
      timeline: rows
    },
    expiredExceptions: expiredExceptions.sort(
      (left, right) =>
        compareText(left.expiresAt, right.expiresAt) ||
        compareText(left.reviewId, right.reviewId) ||
        compareText(left.findingId, right.findingId)
    ),
    boundaries: {
      localOnly: true,
      authority: "none",
      sourceContentIncluded: false,
      diffContentIncluded: false,
      changedPathsIncluded: false,
      commitIdentifiersIncluded: false,
      rawVerifierOutputIncluded: false,
      providerUsed: false,
      networkUsed: false,
      telemetryEnabled: false,
      projectTestsExecuted: false,
      sourceMutationPerformed: false,
      policyMutationPerformed: false,
      preferredBaseIsLocalMetadata: true,
      exportSafe: false
    }
  };
  return verifyRunrailRepositoryTrustProfile({
    ...body,
    checksumSha256: computeRunrailTrustProfileChecksum(body)
  });
}

function verifyTimelineRow(row) {
  exactKeys(row, [
    "reviewId",
    "parentReviewId",
    "createdAt",
    "verdict",
    "previousVerdict",
    "verdictChanged",
    "attentionItemCount",
    "attentionClosedCount",
    "attentionOpenedCount",
    "contractPassed",
    "policyFingerprint",
    "policyChanged",
    "passportChecksumSha256",
    "dispositionCount",
    "activeExceptionCount",
    "expiredExceptionCount"
  ], "Trust Profile timeline row");
  if (!REVIEW_ID_PATTERN.test(row.reviewId)) fail("trust-profile-invalid", "Timeline review ID is invalid.");
  if (row.parentReviewId !== null && !REVIEW_ID_PATTERN.test(row.parentReviewId)) {
    fail("trust-profile-invalid", "Timeline parent review ID is invalid.");
  }
  canonicalTimestamp(row.createdAt, "Timeline createdAt");
  if (!verdicts.includes(row.verdict)) fail("trust-profile-invalid", "Timeline verdict is invalid.");
  if (row.previousVerdict !== null && !verdicts.includes(row.previousVerdict)) {
    fail("trust-profile-invalid", "Timeline previous verdict is invalid.");
  }
  expectBoolean(row.verdictChanged, "Timeline verdict change");
  expectBoolean(row.contractPassed, "Timeline contract status");
  expectBoolean(row.policyChanged, "Timeline policy change");
  for (const key of [
    "attentionItemCount",
    "attentionClosedCount",
    "attentionOpenedCount",
    "dispositionCount",
    "activeExceptionCount",
    "expiredExceptionCount"
  ]) {
    expectInteger(row[key], `Timeline ${key}`, 0, 4_000);
  }
  expectSha256(row.policyFingerprint, "Timeline policy fingerprint", { nullable: true });
  expectSha256(row.passportChecksumSha256, "Timeline passport checksum", { nullable: true });
}

export function verifyRunrailRepositoryTrustProfile(profile) {
  exactKeys(profile, [
    "schemaVersion",
    "artifactType",
    "profile",
    "product",
    "repoFingerprint",
    "generatedAt",
    "preferredBase",
    "stack",
    "reviewCadence",
    "policy",
    "dispositions",
    "trends",
    "continuity",
    "expiredExceptions",
    "boundaries",
    "checksumSha256"
  ], "Repository Trust Profile");
  if (
    profile.schemaVersion !== RUNRAIL_TRUST_PROFILE.schemaVersion ||
    profile.artifactType !== RUNRAIL_TRUST_PROFILE.artifactType ||
    profile.profile !== RUNRAIL_TRUST_PROFILE.profile ||
    profile.product !== RUNRAIL_TRUST_PROFILE.product ||
    !REPO_FINGERPRINT_PATTERN.test(profile.repoFingerprint)
  ) {
    fail("trust-profile-invalid", "Repository Trust Profile identity is invalid.");
  }
  canonicalTimestamp(profile.generatedAt, "Trust Profile generatedAt");
  if (
    typeof profile.preferredBase !== "string" ||
    profile.preferredBase.length < 1 ||
    profile.preferredBase.length > 200
  ) {
    fail("trust-profile-invalid", "Trust Profile preferred base is invalid.");
  }
  exactKeys(profile.stack, [
    "trackedFileCount",
    "recognizedFileCount",
    "otherFileCount",
    "languages",
    "truncated"
  ], "Trust Profile stack");
  for (const key of ["trackedFileCount", "recognizedFileCount", "otherFileCount"]) {
    expectInteger(profile.stack[key], `Trust Profile stack ${key}`, 0, 20_000);
  }
  if (
    profile.stack.recognizedFileCount + profile.stack.otherFileCount !==
      profile.stack.trackedFileCount ||
    !Array.isArray(profile.stack.languages) ||
    profile.stack.languages.length > 16
  ) {
    fail("trust-profile-invalid", "Trust Profile stack summary is inconsistent.");
  }
  expectBoolean(profile.stack.truncated, "Trust Profile stack truncation");
  for (const row of profile.stack.languages) {
    exactKeys(row, ["id", "label", "fileCount"], "Trust Profile language");
    if (
      !/^[a-z][a-z0-9-]{0,31}$/.test(String(row.id || "")) ||
      typeof row.label !== "string" ||
      row.label.length < 1 ||
      row.label.length > 40
    ) {
      fail("trust-profile-invalid", "Trust Profile language is invalid.");
    }
    expectInteger(row.fileCount, "Trust Profile language file count", 1, 20_000);
  }
  exactKeys(profile.reviewCadence, [
    "reviewCount",
    "firstReviewAt",
    "latestReviewAt",
    "reviewedLast7Days",
    "averageIntervalHours",
    "label",
    "historyTruncated",
    "historyEntryLimit"
  ], "Review cadence");
  expectInteger(profile.reviewCadence.reviewCount, "Review cadence count", 1, 100);
  canonicalTimestamp(profile.reviewCadence.firstReviewAt, "Review cadence first review");
  canonicalTimestamp(profile.reviewCadence.latestReviewAt, "Review cadence latest review");
  expectInteger(profile.reviewCadence.reviewedLast7Days, "Reviews in seven days", 0, 100);
  expectBoolean(profile.reviewCadence.historyTruncated, "Review history truncation");
  if (profile.reviewCadence.historyEntryLimit !== RUNRAIL_TRUST_PROFILE.maximumReviews) {
    fail("trust-profile-invalid", "Review history entry limit is invalid.");
  }
  if (
    profile.reviewCadence.averageIntervalHours !== null &&
    (!Number.isSafeInteger(profile.reviewCadence.averageIntervalHours) ||
      profile.reviewCadence.averageIntervalHours < 0)
  ) {
    fail("trust-profile-invalid", "Review cadence average is invalid.");
  }
  if (!["new", "daily", "weekly", "monthly", "occasional"].includes(profile.reviewCadence.label)) {
    fail("trust-profile-invalid", "Review cadence label is invalid.");
  }
  exactKeys(profile.policy, [
    "authoritativeSource",
    "currentFingerprint",
    "contractChangeCount",
    "recommendationAuthority",
    "recommendedChanges",
    "automaticPolicyWrites",
    "automaticPolicyLearning"
  ], "Trust Profile policy");
  if (
    profile.policy.authoritativeSource !== "base-commit-only" ||
    profile.policy.recommendationAuthority !== "advisory-only" ||
    profile.policy.automaticPolicyWrites !== false ||
    profile.policy.automaticPolicyLearning !== false ||
    !Array.isArray(profile.policy.recommendedChanges) ||
    profile.policy.recommendedChanges.length > 3
  ) {
    fail("trust-profile-authority", "Trust Profile policy authority is invalid.");
  }
  expectSha256(profile.policy.currentFingerprint, "Current policy fingerprint", { nullable: true });
  expectInteger(profile.policy.contractChangeCount, "Contract change count", 0, 99);
  for (const recommendation of profile.policy.recommendedChanges) {
    exactKeys(recommendation, ["id", "reason"], "Policy recommendation");
    if (
      ![
        "REVIEW_POLICY_FINGERPRINT_CHANGES",
        "REVIEW_RECURRING_FINDINGS",
        "REVIEW_EXPIRED_EXCEPTIONS"
      ].includes(recommendation.id) ||
      typeof recommendation.reason !== "string" ||
      recommendation.reason.length < 1 ||
      recommendation.reason.length > 240
    ) {
      fail("trust-profile-invalid", "A policy recommendation is invalid.");
    }
  }
  exactKeys(profile.dispositions, [
    "totalCount",
    "currentFindingCount",
    "usefulCount",
    "notRelevantCount",
    "acceptedExceptionCount",
    "activeExceptionCount",
    "expiredExceptionCount"
  ], "Trust Profile dispositions");
  for (const [key, value] of Object.entries(profile.dispositions)) {
    expectInteger(value, `Trust Profile disposition ${key}`, 0, 20_000);
  }
  exactKeys(profile.trends, [
    "verdictCounts",
    "verdictChangeCount",
    "attentionItemClosedCount",
    "attentionItemOpenedCount",
    "recurringFindings"
  ], "Trust Profile trends");
  exactKeys(profile.trends.verdictCounts, verdicts, "Trust Profile verdict counts");
  for (const value of Object.values(profile.trends.verdictCounts)) {
    expectInteger(value, "Trust Profile verdict count", 0, 100);
  }
  for (const key of [
    "verdictChangeCount",
    "attentionItemClosedCount",
    "attentionItemOpenedCount"
  ]) {
    expectInteger(profile.trends[key], `Trust Profile trend ${key}`, 0, 400_000);
  }
  if (
    !Array.isArray(profile.trends.recurringFindings) ||
    profile.trends.recurringFindings.length > RUNRAIL_TRUST_PROFILE.maximumRecurringFindings
  ) {
    fail("trust-profile-invalid", "Recurring finding rows are invalid.");
  }
  for (const row of profile.trends.recurringFindings) {
    exactKeys(row, ["findingId", "occurrenceCount"], "Recurring finding");
    if (!FINDING_ID_PATTERN.test(row.findingId)) {
      fail("trust-profile-invalid", "Recurring finding ID is invalid.");
    }
    expectInteger(row.occurrenceCount, "Recurring finding count", 2, 100);
  }
  exactKeys(profile.continuity, [
    "reviewCount",
    "parentLinkedCount",
    "passportChecksumCount",
    "artifactGapCount",
    "latestPassportChecksumSha256",
    "timeline"
  ], "Trust Profile continuity");
  for (const key of [
    "reviewCount",
    "parentLinkedCount",
    "passportChecksumCount",
    "artifactGapCount"
  ]) {
    expectInteger(profile.continuity[key], `Trust Profile continuity ${key}`, 0, 100);
  }
  if (
    profile.continuity.reviewCount < 1 ||
    !Array.isArray(profile.continuity.timeline) ||
    profile.continuity.timeline.length !== profile.continuity.reviewCount
  ) {
    fail("trust-profile-invalid", "Trust Profile timeline count is invalid.");
  }
  expectSha256(
    profile.continuity.latestPassportChecksumSha256,
    "Latest passport checksum",
    { nullable: true }
  );
  for (const row of profile.continuity.timeline) verifyTimelineRow(row);
  if (!Array.isArray(profile.expiredExceptions) || profile.expiredExceptions.length > 20_000) {
    fail("trust-profile-invalid", "Expired exception rows are invalid.");
  }
  for (const row of profile.expiredExceptions) {
    exactKeys(row, ["reviewId", "findingId", "expiresAt"], "Expired exception");
    if (
      !REVIEW_ID_PATTERN.test(row.reviewId) ||
      !FINDING_ID_PATTERN.test(row.findingId)
    ) {
      fail("trust-profile-invalid", "Expired exception identity is invalid.");
    }
    canonicalTimestamp(row.expiresAt, "Expired exception expiry");
  }
  exactKeys(profile.boundaries, [
    "localOnly",
    "authority",
    "sourceContentIncluded",
    "diffContentIncluded",
    "changedPathsIncluded",
    "commitIdentifiersIncluded",
    "rawVerifierOutputIncluded",
    "providerUsed",
    "networkUsed",
    "telemetryEnabled",
    "projectTestsExecuted",
    "sourceMutationPerformed",
    "policyMutationPerformed",
    "preferredBaseIsLocalMetadata",
    "exportSafe"
  ], "Trust Profile boundaries");
  if (
    profile.boundaries.localOnly !== true ||
    profile.boundaries.authority !== "none" ||
    profile.boundaries.preferredBaseIsLocalMetadata !== true ||
    profile.boundaries.exportSafe !== false ||
    Object.entries(profile.boundaries)
      .filter(([key]) => ![
        "localOnly",
        "authority",
        "preferredBaseIsLocalMetadata",
        "exportSafe"
      ].includes(key))
      .some(([, value]) => value !== false)
  ) {
    fail("trust-profile-authority", "Trust Profile boundaries are invalid.");
  }
  const { checksumSha256, ...body } = profile;
  expectSha256(checksumSha256, "Trust Profile checksum");
  if (checksumSha256 !== computeRunrailTrustProfileChecksum(body)) {
    fail("trust-profile-checksum", "Trust Profile checksum is invalid.");
  }
  return profile;
}

export function buildRunrailWeeklyEngineeringReport({
  trustProfile,
  periodStart,
  periodEnd,
  generatedAt = periodEnd
}) {
  verifyRunrailRepositoryTrustProfile(trustProfile);
  const start = canonicalTimestamp(periodStart, "Weekly report periodStart");
  const end = canonicalTimestamp(periodEnd, "Weekly report periodEnd");
  const generated = canonicalTimestamp(generatedAt, "Weekly report generatedAt");
  if (start >= end || generated < end) {
    fail("weekly-report-time-invalid", "Weekly report timestamps are invalid.");
  }
  const timeline = trustProfile.continuity.timeline.filter(
    (row) => row.createdAt >= start && row.createdAt < end
  );
  const verdictCounts = Object.fromEntries(verdicts.map((verdict) => [verdict, 0]));
  for (const row of timeline) verdictCounts[row.verdict] += 1;
  const failedPolicyFingerprints = new Map();
  for (const row of timeline.filter((entry) => !entry.contractPassed)) {
    const fingerprint = row.policyFingerprint || "unavailable";
    failedPolicyFingerprints.set(
      fingerprint,
      (failedPolicyFingerprints.get(fingerprint) || 0) + 1
    );
  }
  const recurringPolicyFailures = [...failedPolicyFingerprints.entries()]
    .sort((left, right) => right[1] - left[1] || compareText(left[0], right[0]))
    .map(([policyFingerprint, failedReviewCount]) => ({
      policyFingerprint: policyFingerprint === "unavailable" ? null : policyFingerprint,
      failedReviewCount
    }));
  const latest = timeline.at(-1) || null;
  const body = {
    schemaVersion: RUNRAIL_TRUST_PROFILE.schemaVersion,
    artifactType: RUNRAIL_TRUST_PROFILE.weeklyArtifactType,
    profile: RUNRAIL_TRUST_PROFILE.weeklyProfile,
    product: RUNRAIL_TRUST_PROFILE.product,
    generatedAt: generated,
    period: {
      start,
      end,
      days: Math.round((Date.parse(end) - Date.parse(start)) / 86_400_000)
    },
    summary: {
      reviewedCandidateCount: timeline.length,
      verdictCounts,
      latestVerdict: latest?.verdict || null,
      unresolvedAttentionItemCount: latest?.attentionItemCount || 0,
      attentionItemClosedCount: timeline.reduce(
        (total, row) => total + row.attentionClosedCount,
        0
      ),
      recurringPolicyFailureCount: recurringPolicyFailures.reduce(
        (total, row) => total + row.failedReviewCount,
        0
      ),
      expiredExceptionCount: trustProfile.expiredExceptions.filter(
        (row) => row.expiresAt >= start && row.expiresAt < end
      ).length,
      passportChecksumCount: timeline.filter(
        (row) => row.passportChecksumSha256 !== null
      ).length,
      evidenceContinuityGapCount: timeline.filter(
        (row) =>
          row.policyFingerprint === null ||
          row.passportChecksumSha256 === null
      ).length,
      historyTruncated: trustProfile.reviewCadence.historyTruncated
    },
    recurringPolicyFailures,
    recurringFindings: trustProfile.trends.recurringFindings,
    expiredExceptions: trustProfile.expiredExceptions.filter(
      (row) => row.expiresAt < end
    ),
    reviewIds: timeline.map((row) => row.reviewId),
    sourceProfileChecksumSha256: trustProfile.checksumSha256,
    boundaries: {
      localOnly: true,
      pathFree: true,
      authority: "none",
      sourceContentIncluded: false,
      diffContentIncluded: false,
      branchNamesIncluded: false,
      commitIdentifiersIncluded: false,
      repositoryIdentityIncluded: false,
      rawVerifierOutputIncluded: false,
      providerUsed: false,
      networkUsed: false,
      telemetryEnabled: false,
      projectTestsExecuted: false,
      sourceMutationPerformed: false,
      policyMutationPerformed: false
    }
  };
  return verifyRunrailWeeklyEngineeringReport({
    ...body,
    checksumSha256: computeRunrailTrustProfileChecksum(body)
  });
}

export function verifyRunrailWeeklyEngineeringReport(report) {
  exactKeys(report, [
    "schemaVersion",
    "artifactType",
    "profile",
    "product",
    "generatedAt",
    "period",
    "summary",
    "recurringPolicyFailures",
    "recurringFindings",
    "expiredExceptions",
    "reviewIds",
    "sourceProfileChecksumSha256",
    "boundaries",
    "checksumSha256"
  ], "Weekly engineering report");
  if (
    report.schemaVersion !== RUNRAIL_TRUST_PROFILE.schemaVersion ||
    report.artifactType !== RUNRAIL_TRUST_PROFILE.weeklyArtifactType ||
    report.profile !== RUNRAIL_TRUST_PROFILE.weeklyProfile ||
    report.product !== RUNRAIL_TRUST_PROFILE.product
  ) {
    fail("weekly-report-invalid", "Weekly engineering report identity is invalid.");
  }
  canonicalTimestamp(report.generatedAt, "Weekly report generatedAt");
  exactKeys(report.period, ["start", "end", "days"], "Weekly report period");
  canonicalTimestamp(report.period.start, "Weekly report start");
  canonicalTimestamp(report.period.end, "Weekly report end");
  expectInteger(report.period.days, "Weekly report period days", 1, 31);
  exactKeys(report.summary, [
    "reviewedCandidateCount",
    "verdictCounts",
    "latestVerdict",
    "unresolvedAttentionItemCount",
    "attentionItemClosedCount",
    "recurringPolicyFailureCount",
    "expiredExceptionCount",
    "passportChecksumCount",
    "evidenceContinuityGapCount",
    "historyTruncated"
  ], "Weekly report summary");
  exactKeys(report.summary.verdictCounts, verdicts, "Weekly report verdict counts");
  for (const value of Object.values(report.summary.verdictCounts)) {
    expectInteger(value, "Weekly report verdict count", 0, 100);
  }
  for (const key of [
    "reviewedCandidateCount",
    "unresolvedAttentionItemCount",
    "attentionItemClosedCount",
    "recurringPolicyFailureCount",
    "expiredExceptionCount",
    "passportChecksumCount",
    "evidenceContinuityGapCount"
  ]) {
    expectInteger(report.summary[key], `Weekly report ${key}`, 0, 400_000);
  }
  expectBoolean(report.summary.historyTruncated, "Weekly report history truncation");
  if (report.summary.latestVerdict !== null && !verdicts.includes(report.summary.latestVerdict)) {
    fail("weekly-report-invalid", "Weekly report latest verdict is invalid.");
  }
  if (!Array.isArray(report.recurringPolicyFailures) || report.recurringPolicyFailures.length > 100) {
    fail("weekly-report-invalid", "Weekly report policy failures are invalid.");
  }
  for (const row of report.recurringPolicyFailures) {
    exactKeys(row, ["policyFingerprint", "failedReviewCount"], "Weekly policy failure");
    expectSha256(row.policyFingerprint, "Weekly policy fingerprint", { nullable: true });
    expectInteger(row.failedReviewCount, "Weekly failed review count", 1, 100);
  }
  if (!Array.isArray(report.recurringFindings) || report.recurringFindings.length > 20) {
    fail("weekly-report-invalid", "Weekly recurring findings are invalid.");
  }
  for (const row of report.recurringFindings) {
    exactKeys(row, ["findingId", "occurrenceCount"], "Weekly recurring finding");
    if (!FINDING_ID_PATTERN.test(row.findingId)) {
      fail("weekly-report-invalid", "Weekly recurring finding ID is invalid.");
    }
    expectInteger(row.occurrenceCount, "Weekly recurring finding count", 2, 100);
  }
  if (!Array.isArray(report.expiredExceptions) || report.expiredExceptions.length > 20_000) {
    fail("weekly-report-invalid", "Weekly expired exceptions are invalid.");
  }
  for (const row of report.expiredExceptions) {
    exactKeys(row, ["reviewId", "findingId", "expiresAt"], "Weekly expired exception");
    if (!REVIEW_ID_PATTERN.test(row.reviewId) || !FINDING_ID_PATTERN.test(row.findingId)) {
      fail("weekly-report-invalid", "Weekly expired exception identity is invalid.");
    }
    canonicalTimestamp(row.expiresAt, "Weekly expired exception expiry");
  }
  if (
    !Array.isArray(report.reviewIds) ||
    report.reviewIds.length !== report.summary.reviewedCandidateCount ||
    report.reviewIds.some((reviewId) => !REVIEW_ID_PATTERN.test(reviewId))
  ) {
    fail("weekly-report-invalid", "Weekly report review IDs are invalid.");
  }
  expectSha256(report.sourceProfileChecksumSha256, "Weekly source profile checksum");
  exactKeys(report.boundaries, [
    "localOnly",
    "pathFree",
    "authority",
    "sourceContentIncluded",
    "diffContentIncluded",
    "branchNamesIncluded",
    "commitIdentifiersIncluded",
    "repositoryIdentityIncluded",
    "rawVerifierOutputIncluded",
    "providerUsed",
    "networkUsed",
    "telemetryEnabled",
    "projectTestsExecuted",
    "sourceMutationPerformed",
    "policyMutationPerformed"
  ], "Weekly report boundaries");
  if (
    report.boundaries.localOnly !== true ||
    report.boundaries.pathFree !== true ||
    report.boundaries.authority !== "none" ||
    Object.entries(report.boundaries)
      .filter(([key]) => !["localOnly", "pathFree", "authority"].includes(key))
      .some(([, value]) => value !== false)
  ) {
    fail("weekly-report-authority", "Weekly report boundaries are invalid.");
  }
  const { checksumSha256, ...body } = report;
  expectSha256(checksumSha256, "Weekly report checksum");
  if (checksumSha256 !== computeRunrailTrustProfileChecksum(body)) {
    fail("weekly-report-checksum", "Weekly report checksum is invalid.");
  }
  return report;
}

async function artifactsForSession(session) {
  const audit = await readOptionalVerifiedJson({
    filePath: session.local.auditPath,
    artifactRootPath: session.local.artifactRootPath,
    maximumBytes: MAX_AUDIT_BYTES,
    expectedFileSha256: session.evidence.auditFileSha256,
    label: "Review audit"
  });
  let policyFingerprint = null;
  if (audit) {
    const verified = verifyRunrailAuditV4(audit);
    if (verified.checksumSha256 !== session.evidence.auditChecksumSha256) {
      fail("trust-profile-artifact-tampered", "Review audit checksum does not match its session.");
    }
    policyFingerprint = verified.reviewContract.contractSha256;
  }
  const passport = await readOptionalVerifiedJson({
    filePath: path.join(session.local.artifactRootPath, "REVIEW_PASSPORT.json"),
    artifactRootPath: session.local.artifactRootPath,
    maximumBytes: MAX_PASSPORT_BYTES,
    label: "Review passport"
  });
  let passportChecksumSha256 = null;
  if (passport) {
    const verified = verifyRunrailReviewPassport(passport);
    if (verified.auditChecksumSha256 !== session.evidence.auditChecksumSha256) {
      fail("trust-profile-artifact-tampered", "Review passport does not match its session.");
    }
    passportChecksumSha256 = verified.checksumSha256;
  }
  return { policyFingerprint, passportChecksumSha256 };
}

export async function loadRunrailRepositoryTrustProfile({
  historyRoot,
  repoFingerprint,
  generatedAt = new Date()
}) {
  if (!REPO_FINGERPRINT_PATTERN.test(String(repoFingerprint || ""))) {
    fail("trust-profile-input-invalid", "A valid local repository fingerprint is required.");
  }
  const sessions = await listRunrailReviewSessions({
    historyRoot,
    repoFingerprint,
    limit: RUNRAIL_TRUST_PROFILE.maximumReviews
  });
  if (sessions.length === 0) {
    fail("trust-profile-not-found", "No local review history exists for this repository.");
  }
  const dispositionsByReviewId = new Map();
  const artifactsByReviewId = new Map();
  for (const session of sessions) {
    dispositionsByReviewId.set(
      session.reviewId,
      await listRunrailReviewDispositions({
        historyRoot,
        repoFingerprint,
        reviewId: session.reviewId
      })
    );
    artifactsByReviewId.set(session.reviewId, await artifactsForSession(session));
  }
  return buildRunrailRepositoryTrustProfile({
    sessions,
    dispositionsByReviewId,
    artifactsByReviewId,
    generatedAt,
    historyTruncated:
      sessions.length === RUNRAIL_TRUST_PROFILE.maximumReviews
  });
}

export async function loadRunrailWeeklyEngineeringReport({
  historyRoot,
  repoFingerprint,
  generatedAt = new Date()
}) {
  const clock = canonicalNow(generatedAt);
  const periodEnd = new Date(clock);
  const periodStart = new Date(clock.getTime() - 7 * 86_400_000);
  const trustProfile = await loadRunrailRepositoryTrustProfile({
    historyRoot,
    repoFingerprint,
    generatedAt: clock
  });
  return buildRunrailWeeklyEngineeringReport({
    trustProfile,
    periodStart: periodStart.toISOString(),
    periodEnd: periodEnd.toISOString(),
    generatedAt: clock.toISOString()
  });
}
