import assert from "node:assert/strict";
import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import test from "node:test";

import { validate } from "@codeflowmu/protocol";
import type {
  TmpaConformanceResult,
  TmpaGovernanceObject,
} from "@codeflowmu/protocol";

import {
  canonicalBytes,
  compareUnicodeCodePoints,
  finalizeTmpaObject,
} from "../canonical.ts";
import { projectFcopToTmpa } from "../FcopSourceAdapter.ts";
import { createTmpaGovernanceReader } from "../GovernanceReader.ts";
import { createCodeFlowMuTmpaProfile } from "../profile.ts";
import { readTmpaSourceRevisionRecords } from "../SourceRevisionStore.ts";
import type { TmpaSourceCandidate } from "../types.ts";
import { TaskFrontmatterStore } from "../../lifecycle/TaskFrontmatterStore.ts";

function object(
  id: string,
  type: string,
  overrides: Partial<TmpaGovernanceObject> = {},
): TmpaGovernanceObject {
  const role = overrides.role ?? "DEV";
  const creator = overrides.creator ?? "dev-1";
  return finalizeTmpaObject({
    tmpa_version: "S1.0",
    id,
    type,
    governed_work: overrides.governed_work ?? {
      id: type === "TASK" ? id : "TASK-20260808-001",
      primary_carrier_id:
        type === "TASK" ? id : "TASK-20260808-001",
    },
    stream: overrides.stream ?? { id: `stream:${creator}:${type}`, sequence: 1 },
    creator,
    role,
    created_at: overrides.created_at ?? "2026-08-08T00:00:00.000Z",
    lifecycle: overrides.lifecycle ?? {
      profile: "codeflowmu-fcop-tmpa-s1.0",
      state: "inbox",
    },
    references: overrides.references ?? [],
    ...(overrides.claims ? { claims: overrides.claims } : {}),
    ...(overrides.risk ? { risk: overrides.risk } : {}),
    content: overrides.content ?? {
      media_type: "application/json",
      body: {},
    },
    extensions: overrides.extensions ?? {},
  });
}

function source(id: string, value: TmpaGovernanceObject): TmpaSourceCandidate {
  return {
    source_id: id,
    media_type: "application/json",
    bytes: canonicalBytes(value),
  };
}

function reader() {
  return createTmpaGovernanceReader({
    lifecycleProfile: createCodeFlowMuTmpaProfile({
      assignments: [
        { identity: "dev-1", role: "DEV", actions: ["submit_review"] },
        {
          identity: "pm-1",
          role: "PM",
          actions: [
            "runtime_dispatch",
            "approve_review",
            "reject_review",
            "resolve_review_conflict",
            "archive_task",
          ],
        },
        {
          identity: "qa-1",
          role: "QA",
          actions: [
            "approve_review",
            "reject_review",
            "resolve_review_conflict",
          ],
        },
        {
          identity: "qa-2",
          role: "QA",
          actions: [
            "approve_review",
            "reject_review",
            "resolve_review_conflict",
          ],
        },
      ],
    }),
  });
}

function conflictingReviewFixture() {
  const task = object("TASK-20260808-001", "TASK");
  const report = object("REPORT-20260808-001", "REPORT", {
    references: [{ relation: "reports", target: task.id }],
  });
  const approve = object("REVIEW-20260808-001", "REVIEW", {
    creator: "qa-1",
    role: "QA",
    stream: { id: "stream:qa-1", sequence: 1 },
    references: [{ relation: "reviews", target: report.id }],
    content: { media_type: "application/json", body: { decision: "approved" } },
  });
  const reject = object("REVIEW-20260808-002", "REVIEW", {
    creator: "qa-2",
    role: "QA",
    stream: { id: "stream:qa-2", sequence: 1 },
    references: [{ relation: "reviews", target: report.id }],
    content: { media_type: "application/json", body: { decision: "rejected" } },
  });
  return { task, report, approve, reject };
}

test("C11 same source set produces byte-equivalent output for every permutation", async () => {
  const task = object("TASK-20260808-001", "TASK");
  const report = object("REPORT-20260808-001", "REPORT", {
    references: [{ relation: "reports", target: task.id }],
  });
  const review = object("REVIEW-20260808-001", "REVIEW", {
    creator: "qa-1",
    role: "QA",
    stream: { id: "stream:qa-1", sequence: 1 },
    references: [{ relation: "reviews", target: report.id }],
    content: { media_type: "application/json", body: { decision: "approved" } },
  });
  const sources = [source("task", task), source("report", report), source("review", review)];
  const governanceReader = reader();
  const first = await governanceReader.read(sources);
  const second = await governanceReader.read([sources[2]!, sources[0]!, sources[1]!]);
  assert.equal(first.source_set_digest, second.source_set_digest);
  assert.deepEqual(first, second);
});

test("C11 uses locale-independent Unicode code-point ordering", async () => {
  const values = [
    object("c11-\u{10000}", "TASK"),
    object("c11-b", "TASK"),
    object("c11-\uE000", "TASK"),
    object("c11-a", "TASK"),
  ];
  const result = await reader().read(
    values.map((value) => source(`source-${value.id}`, value)),
  );
  assert.deepEqual(
    result.nodes.map((node) => node.id),
    ["c11-a", "c11-b", "c11-\uE000", "c11-\u{10000}"],
  );
});

test("C01 all four published TMPA S1.0 schema surfaces compile and validate", async () => {
  const task = object("TASK-20260808-001", "TASK");
  const governance = await validate("tmpa-governance-object", task);
  assert.equal(governance.valid, true, JSON.stringify(governance.errors));

  const profile = createCodeFlowMuTmpaProfile();
  const lifecycle = await validate("tmpa-lifecycle-profile", profile);
  assert.equal(lifecycle.valid, true, JSON.stringify(lifecycle.errors));

  const result = await createTmpaGovernanceReader({ lifecycleProfile: profile }).read([
    source("task", task),
  ]);
  const readerResult = await validate("tmpa-reader-result", result);
  assert.equal(readerResult.valid, true, JSON.stringify(readerResult.errors));

  const digest = `sha256:${"0".repeat(64)}`;
  const conformance: TmpaConformanceResult = {
    core_version: "S1.0",
    implementation: { id: "codeflowmu", version: "V1.8.0" },
    input_bundle_digest: digest,
    criteria: Array.from({ length: 14 }, (_, index) => ({
      id: `C${String(index + 1).padStart(2, "0")}` as
        | "C01"
        | "C02"
        | "C03"
        | "C04"
        | "C05"
        | "C06"
        | "C07"
        | "C08"
        | "C09"
        | "C10"
        | "C11"
        | "C12"
        | "C13"
        | "C14",
      verdict: "NOT RUN" as const,
      run_state: "completed" as const,
      manifest_digest: digest,
      result_digest: digest,
    })),
    aggregate_verdict: "NOT RUN",
    evidence_level: "implemented",
  };
  const conformanceResult = await validate("tmpa-conformance-result", conformance);
  assert.equal(conformanceResult.valid, true, JSON.stringify(conformanceResult.errors));

  const invalidDate = structuredClone(task);
  invalidDate.created_at = "2026-99-99";
  const invalidDateResult = await validate("tmpa-governance-object", invalidDate);
  assert.equal(invalidDateResult.valid, false);
  assert.ok(invalidDateResult.errors?.some((error) => error.keyword === "format"));
});

test("S0.6/I0.8 compatibility mode remains executable", async () => {
  const legacy = object("TASK-LEGACY-S06", "TASK", {
    lifecycle: {
      profile: "codeflowmu-fcop-tmpa-s0.6",
      state: "inbox",
    },
  });
  legacy.tmpa_version = "S0.6";
  legacy.integrity.canonicalization = "";
  legacy.integrity.digest = "";
  const finalizedLegacy = finalizeTmpaObject(legacy);
  const profile = createCodeFlowMuTmpaProfile({ coreVersion: "S0.6" });
  const result = await createTmpaGovernanceReader({
    lifecycleProfile: profile,
    coreVersion: "S0.6",
  }).read([source("legacy-s06", finalizedLegacy)]);
  assert.equal(result.core_version, "S0.6");
  assert.equal(result.judgment, "valid");
  assert.equal(
    (await validate("tmpa-s0.6-governance-object", finalizedLegacy)).valid,
    true,
  );
  assert.equal((await validate("tmpa-s0.6-lifecycle-profile", profile)).valid, true);
  assert.equal((await validate("tmpa-s0.6-reader-result", result)).valid, true);
});

test("S0.5/I0.7 compatibility mode remains executable", async () => {
  const legacy = object("TASK-LEGACY-S05", "TASK", {
    lifecycle: {
      profile: "codeflowmu-fcop-tmpa-s0.5",
      state: "inbox",
    },
  });
  legacy.tmpa_version = "S0.5";
  legacy.integrity.digest = "";
  const finalizedLegacy = finalizeTmpaObject(legacy);
  const profile = createCodeFlowMuTmpaProfile({ coreVersion: "S0.5" });
  const result = await createTmpaGovernanceReader({
    lifecycleProfile: profile,
    coreVersion: "S0.5",
  }).read([source("legacy", finalizedLegacy)]);
  assert.equal(result.core_version, "S0.5");
  assert.equal(result.judgment, "valid");
  assert.equal(
    (await validate("tmpa-s0.5-governance-object", finalizedLegacy)).valid,
    true,
  );
  assert.equal((await validate("tmpa-s0.5-lifecycle-profile", profile)).valid, true);
  assert.equal((await validate("tmpa-s0.5-reader-result", result)).valid, true);
});

test("C03 same id with different canonical content is quarantined", async () => {
  const left = object("TASK-20260808-001", "TASK", {
    content: { media_type: "application/json", body: { title: "left" } },
  });
  const right = object("TASK-20260808-001", "TASK", {
    content: { media_type: "application/json", body: { title: "right" } },
  });
  const result = await reader().read([source("left", left), source("right", right)]);
  assert.equal(result.judgment, "invalid");
  assert.equal(result.view_state, "quarantined");
  assert.ok(result.issues.some((issue) => issue.code === "DUPLICATE_ID_CONFLICT"));
});

test("C03 byte-identical observations retain every deterministically ordered source", async () => {
  const value = object("TASK-C03-IDENTICAL", "TASK");
  const result = await reader().read([
    source("source-b", value),
    source("source-a", value),
  ]);
  assert.equal(result.nodes.length, 1);
  assert.deepEqual(result.nodes[0]?.source_ids, ["source-a", "source-b"]);
});

test("C09 missing references remain visible and undetermined", async () => {
  const task = object("TASK-20260808-001", "TASK", {
    references: [{ relation: "depends_on", target: "TASK-20260808-404" }],
  });
  const result = await reader().read([source("task", task)]);
  assert.equal(result.judgment, "undetermined");
  assert.equal(result.view_state, "partial");
  assert.ok(result.issues.some((issue) => issue.code === "MISSING_REFERENCE"));
});

test("C12 contradictory valid reviews remain disputed until resolution", async () => {
  const { task, report, approve, reject } = conflictingReviewFixture();
  const result = await reader().read([
    source("task", task),
    source("report", report),
    source("approve", approve),
    source("reject", reject),
  ]);
  assert.equal(result.view_state, "disputed");
  assert.ok(result.issues.some((issue) => issue.code === "UNRESOLVED_CONFLICT"));
});

test("C12 unauthorized DECISION is retained but cannot resolve contradictory reviews", async () => {
  const { task, report, approve, reject } = conflictingReviewFixture();
  const decision = object("DECISION-20260808-001", "DECISION", {
    creator: "dev-1",
    role: "DEV",
    stream: { id: "stream:dev-decision", sequence: 1 },
    references: [
      { relation: "resolves", target: approve.id },
      { relation: "resolves", target: reject.id },
    ],
    content: { media_type: "application/json", body: { selects: approve.id } },
  });
  const result = await reader().read(
    [task, report, approve, reject, decision].map((value) => source(value.id, value)),
  );
  assert.equal(result.judgment, "invalid");
  assert.equal(result.view_state, "disputed");
  assert.ok(result.issues.some((issue) => issue.code === "AUTHORITY_DENIED"));
  assert.ok(result.issues.some((issue) => issue.code === "UNRESOLVED_CONFLICT"));
  assert.equal(
    result.nodes.find((node) => node.id === decision.id)?.view_state,
    "rejected",
  );
});

test("C12 authorized PM DECISION resolves contradictory reviews", async () => {
  const { task, report, approve, reject } = conflictingReviewFixture();
  const decision = object("DECISION-20260808-001", "DECISION", {
    creator: "pm-1",
    role: "PM",
    stream: { id: "stream:pm-decision", sequence: 1 },
    references: [
      { relation: "resolves", target: approve.id },
      { relation: "resolves", target: reject.id },
    ],
    content: { media_type: "application/json", body: { selects: approve.id } },
  });
  const result = await reader().read(
    [task, report, approve, reject, decision].map((value) => source(value.id, value)),
  );
  assert.equal(result.judgment, "valid");
  assert.equal(result.view_state, "authoritative");
  assert.ok(!result.issues.some((issue) => issue.code === "UNRESOLVED_CONFLICT"));
  assert.ok(!result.issues.some((issue) => issue.code.startsWith("AUTHORITY_")));
});

test("C06 authorized independent lifecycle evidence reaches accepted done state", async () => {
  const task = object("TASK-20260808-001", "TASK", {
    creator: "pm-1",
    role: "PM",
    stream: { id: "stream:pm-1", sequence: 1 },
  });
  const report = object("REPORT-20260808-001", "REPORT", {
    creator: "dev-1",
    role: "DEV",
    stream: { id: "stream:dev-1", sequence: 1 },
    references: [{ relation: "reports", target: task.id }],
  });
  const dispatch = object("TRANSITION-001", "TRANSITION", {
    creator: "CODEFLOWMU-RUNTIME",
    role: "SYSTEM",
    stream: { id: "stream:system", sequence: 1 },
    lifecycle: {
      profile: "codeflowmu-fcop-tmpa-s0.5",
      state: "active",
      transition: { from: "inbox", action: "runtime_dispatch", to: "active" },
    },
  });
  const submit = object("TRANSITION-002", "TRANSITION", {
    creator: "dev-1",
    role: "DEV",
    stream: { id: "stream:dev-transition", sequence: 1 },
    lifecycle: {
      profile: "codeflowmu-fcop-tmpa-s0.5",
      state: "review",
      transition: { from: "active", action: "submit_review", to: "review" },
    },
    references: [
      { relation: "depends_on", target: dispatch.id },
      { relation: "reports", target: report.id },
    ],
  });
  const approve = object("TRANSITION-003", "TRANSITION", {
    creator: "pm-1",
    role: "PM",
    stream: { id: "stream:pm-transition", sequence: 1 },
    lifecycle: {
      profile: "codeflowmu-fcop-tmpa-s0.5",
      state: "done",
      transition: { from: "review", action: "approve_review", to: "done" },
    },
    references: [
      { relation: "depends_on", target: submit.id },
      { relation: "accepts", target: report.id },
    ],
  });
  const result = await reader().read(
    [task, report, dispatch, submit, approve].map((value) => source(value.id, value)),
  );
  assert.equal(result.judgment, "valid");
  assert.deepEqual(
    (result.extensions?.summary as Record<string, Record<string, string>>).work_state,
    { "TASK-20260808-001": "done" },
  );
  assert.deepEqual(
    (result.extensions?.summary as Record<string, Record<string, string>>)
      .acceptance_state,
    { "TASK-20260808-001": "accepted" },
  );
});

test("C06 missing independent acceptance reports lifecycle and acceptance uncertainty", async () => {
  const task = object("TASK-20260808-001", "TASK", {
    creator: "pm-1",
    role: "PM",
    stream: { id: "stream:pm-1", sequence: 1 },
  });
  const report = object("REPORT-20260808-001", "REPORT", {
    creator: "dev-1",
    role: "DEV",
    stream: { id: "stream:dev-1", sequence: 1 },
    references: [{ relation: "reports", target: task.id }],
  });
  const dispatch = object("TRANSITION-001", "TRANSITION", {
    creator: "CODEFLOWMU-RUNTIME",
    role: "SYSTEM",
    stream: { id: "stream:system", sequence: 1 },
    lifecycle: {
      profile: "codeflowmu-fcop-tmpa-s0.5",
      state: "active",
      transition: { from: "inbox", action: "runtime_dispatch", to: "active" },
    },
  });
  const submit = object("TRANSITION-002", "TRANSITION", {
    creator: "dev-1",
    role: "DEV",
    stream: { id: "stream:dev-transition", sequence: 1 },
    lifecycle: {
      profile: "codeflowmu-fcop-tmpa-s0.5",
      state: "review",
      transition: { from: "active", action: "submit_review", to: "review" },
    },
    references: [
      { relation: "depends_on", target: dispatch.id },
      { relation: "reports", target: report.id },
    ],
  });
  const approveWithoutAcceptance = object("TRANSITION-003", "TRANSITION", {
    creator: "pm-1",
    role: "PM",
    stream: { id: "stream:pm-transition", sequence: 1 },
    lifecycle: {
      profile: "codeflowmu-fcop-tmpa-s0.5",
      state: "done",
      transition: { from: "review", action: "approve_review", to: "done" },
    },
    references: [{ relation: "depends_on", target: submit.id }],
  });
  const result = await reader().read(
    [task, report, dispatch, submit, approveWithoutAcceptance].map((value) =>
      source(value.id, value),
    ),
  );
  assert.equal(result.judgment, "undetermined");
  assert.equal(result.view_state, "partial");
  assert.ok(result.issues.some((issue) => issue.code === "LIFECYCLE_UNDETERMINED"));
  assert.ok(result.issues.some((issue) => issue.code === "ACCEPTANCE_UNDETERMINED"));
  const summary = result.extensions?.summary as Record<string, Record<string, string>>;
  assert.deepEqual(summary.work_state, { "TASK-20260808-001": "review" });
  assert.deepEqual(summary.acceptance_state, {
    "TASK-20260808-001": "undetermined",
  });
});

test("C05 high-risk work without ADMIN approval remains pending human", async () => {
  const task = object("TASK-20260808-001", "TASK", {
    risk: { level: "high", requires_human_approval: true },
  });
  const result = await reader().read([source("task", task)]);
  assert.equal(result.judgment, "undetermined");
  assert.equal(result.view_state, "pending_human");
  assert.ok(result.issues.some((issue) => issue.code === "HUMAN_APPROVAL_REQUIRED"));
});

test("C07 same security identity review is rejected even across role labels", async () => {
  const task = object("TASK-20260808-001", "TASK");
  const report = object("REPORT-20260808-001", "REPORT", {
    creator: "shared-agent",
    role: "DEV",
    references: [{ relation: "reports", target: task.id }],
  });
  const review = object("REVIEW-20260808-001", "REVIEW", {
    creator: "shared-agent",
    role: "QA",
    stream: { id: "stream:shared-review", sequence: 1 },
    references: [{ relation: "reviews", target: report.id }],
    content: { media_type: "application/json", body: { decision: "approved" } },
  });
  const result = await reader().read([
    source("task", task),
    source("report", report),
    source("review", review),
  ]);
  assert.equal(result.judgment, "invalid");
  assert.ok(result.issues.some((issue) => issue.code === "SOD_VIOLATION"));
});

test("C07 high-risk approval enforces type, assignment, role, decision, and independence", async () => {
  const run = async (
    riskCreator: string,
    approvalCreator: string,
    approvalType: string,
    approvalRole: string,
    decision: string,
  ) => {
    const approval = object("DECISION-C07", approvalType, {
      creator: approvalCreator,
      role: approvalRole,
      governed_work: {
        id: "WORK-C07-RISK",
        primary_carrier_id: "TASK-C07-RISK",
      },
      content: { media_type: "application/json", body: { decision } },
    });
    const risk = object("TASK-C07-RISK", "TASK", {
      creator: riskCreator,
      role: riskCreator === "human:ADMIN" ? "ADMIN" : "DEV",
      governed_work: {
        id: "WORK-C07-RISK",
        primary_carrier_id: "TASK-C07-RISK",
      },
      risk: { level: "high", requires_human_approval: true },
      references: [{ relation: "human_approves", target: approval.id }],
    });
    return reader().read([source("risk", risk), source("approval", approval)]);
  };

  for (const result of [
    await run("dev-1", "human:ADMIN", "REVIEW", "ADMIN", "approve"),
    await run("dev-1", "unassigned-admin", "DECISION", "ADMIN", "approve"),
    await run("dev-1", "qa-1", "DECISION", "QA", "approve"),
    await run("dev-1", "human:ADMIN", "DECISION", "ADMIN", "reject"),
    await run("human:ADMIN", "human:ADMIN", "DECISION", "ADMIN", "approve"),
  ]) {
    assert.equal(result.view_state, "pending_human");
    assert.ok(result.issues.some((issue) => issue.code === "HUMAN_APPROVAL_REQUIRED"));
  }

  const valid = await run(
    "dev-1",
    "human:ADMIN",
    "DECISION",
    "ADMIN",
    "approved",
  );
  assert.equal(valid.view_state, "authoritative");
  assert.ok(!valid.issues.some((issue) => issue.code === "HUMAN_APPROVAL_REQUIRED"));
});

test("C13 FCoP adapter supports fresh-reader recovery from persistent evidence", async () => {
  const root = await mkdtemp(join(tmpdir(), "codeflowmu-tmpa-adapter-"));
  try {
    await mkdir(join(root, "fcop", "_lifecycle", "review"), { recursive: true });
    await mkdir(join(root, "fcop", "reports"), { recursive: true });
    await writeFile(
      join(root, "codeflowmu.team.json"),
      JSON.stringify({ members: [{ agent_id: "DEV-01", role: "DEV" }] }),
      "utf8",
    );
    await writeFile(
      join(root, "fcop", "_lifecycle", "review", "TASK-20260808-001-ADMIN-to-DEV.md"),
      [
        "---",
        "protocol: fcop",
        "task_id: TASK-20260808-001",
        "sender: ADMIN",
        "recipient: DEV",
        "state: review",
        "transitions:",
        "  - at: 2026-08-08T01:00:00Z",
        "    from: inbox",
        "    to: active",
        "    by: CodeFlowMu",
        "    action: runtime_dispatch",
        "  - at: 2026-08-08T02:00:00Z",
        "    from: active",
        "    to: review",
        "    by: DEV",
        "    action: submit_review",
        "    report: REPORT-20260808-001-DEV-to-PM",
        "---",
        "# Task",
      ].join("\n"),
      "utf8",
    );
    await writeFile(
      join(root, "fcop", "reports", "REPORT-20260808-001-DEV-to-PM.md"),
      [
        "---",
        "protocol: fcop",
        "report_id: REPORT-20260808-001-DEV-to-PM",
        "task_id: TASK-20260808-001",
        "sender: DEV",
        "recipient: PM",
        "created_at: 2026-08-08T02:00:00Z",
        "---",
        "# Report",
      ].join("\n"),
      "utf8",
    );

    const projection = await projectFcopToTmpa(root);
    assert.equal(projection.source_file_count, 2);
    assert.equal(projection.projected_object_count, 5);
    assert.deepEqual(
      projection.sources
        .map((candidate) => candidate.object.type)
        .sort(compareUnicodeCodePoints),
      ["REPORT", "STATE_OBSERVATION", "TASK", "TRANSITION", "TRANSITION"],
    );
    const result = await createTmpaGovernanceReader({
      lifecycleProfile: projection.profile,
    }).read(projection.sources);
    const recovered = await createTmpaGovernanceReader({
      lifecycleProfile: projection.profile,
    }).read([...projection.sources].reverse());
    assert.equal(result.judgment, "valid");
    assert.equal(result.view_state, "authoritative");
    assert.deepEqual(result, recovered);
  } finally {
    await rm(root, { recursive: true, force: true });
  }
});

test("C02 TASK mutation preserves content-addressed immutable revisions", async () => {
  const root = await mkdtemp(join(tmpdir(), "codeflowmu-tmpa-revision-"));
  try {
    const taskDir = join(root, "fcop", "_lifecycle", "active");
    await mkdir(taskDir, { recursive: true });
    const taskPath = join(taskDir, "TASK-20260808-099-ADMIN-to-DEV.md");
    const original = [
      "---",
      "protocol: fcop",
      "task_id: TASK-20260808-099",
      "sender: ADMIN",
      "recipient: DEV",
      "state: inbox",
      "---",
      "# Immutable source",
    ].join("\n");
    await writeFile(taskPath, original, "utf8");
    const store = new TaskFrontmatterStore();
    await store.patch(taskPath, { state: "active" });

    const revisions = await readTmpaSourceRevisionRecords(root);
    assert.equal(revisions.length, 2);
    assert.ok(revisions.some((revision) => revision.raw_text === original));
    assert.equal(new Set(revisions.map((revision) => revision.content_digest)).size, 2);

    const projection = await projectFcopToTmpa(root);
    assert.equal(
      projection.sources.filter((candidate) => candidate.object.type === "TASK").length,
      1,
    );
    assert.equal(
      projection.sources.filter((candidate) => candidate.object.type === "CORRECTION")
        .length,
      1,
    );
    const task = projection.sources.find((candidate) => candidate.object.type === "TASK");
    const correction = projection.sources.find(
      (candidate) => candidate.object.type === "CORRECTION",
    );
    assert.equal(
      (task?.object.content.body as Record<string, unknown>).state,
      "inbox",
    );
    assert.deepEqual(correction?.object.references, [
      { relation: "supersedes", target: "TASK-20260808-099" },
    ]);
  } finally {
    await rm(root, { recursive: true, force: true });
  }
});

test("C04 writer-stream gaps remain explicit and undetermined", async () => {
  const first = object("TASK-20260808-001", "TASK", {
    stream: { id: "stream:dev", sequence: 1 },
  });
  const third = object("TASK-20260808-003", "TASK", {
    governed_work: {
      id: "TASK-20260808-003",
      primary_carrier_id: "TASK-20260808-003",
    },
    stream: { id: "stream:dev", sequence: 3 },
  });
  const result = await reader().read([source("first", first), source("third", third)]);
  assert.equal(result.judgment, "undetermined");
  assert.ok(result.issues.some((issue) => issue.code === "STREAM_GAP"));
});

test("C05 declared identity cannot execute an action outside its authority", async () => {
  const task = object("TASK-20260808-001", "TASK");
  const unauthorized = object("TRANSITION-UNAUTHORIZED", "TRANSITION", {
    creator: "dev-1",
    role: "DEV",
    stream: { id: "stream:unauthorized", sequence: 1 },
    lifecycle: {
      profile: "codeflowmu-fcop-tmpa-s0.5",
      state: "active",
      transition: { from: "inbox", action: "runtime_dispatch", to: "active" },
    },
  });
  const result = await reader().read([
    source("task", task),
    source("transition", unauthorized),
  ]);
  assert.equal(result.judgment, "invalid");
  assert.ok(result.issues.some((issue) => issue.code === "AUTHORITY_DENIED"));
});

test("C06 illegal lifecycle transitions are rejected", async () => {
  const task = object("TASK-20260808-001", "TASK");
  const illegal = object("TRANSITION-ILLEGAL", "TRANSITION", {
    creator: "pm-1",
    role: "PM",
    stream: { id: "stream:illegal", sequence: 1 },
    lifecycle: {
      profile: "codeflowmu-fcop-tmpa-s0.5",
      state: "archive",
      transition: { from: "inbox", action: "archive_task", to: "archive" },
    },
  });
  const result = await reader().read([
    source("task", task),
    source("transition", illegal),
  ]);
  assert.equal(result.judgment, "invalid");
  assert.ok(result.issues.some((issue) => issue.code === "ILLEGAL_TRANSITION"));
});

test("C08 covered-content tampering is quarantined", async () => {
  const task = object("TASK-20260808-001", "TASK");
  task.content = { media_type: "application/json", body: { tampered: true } };
  const result = await reader().read([source("tampered", task)]);
  assert.equal(result.judgment, "invalid");
  assert.equal(result.view_state, "quarantined");
  assert.ok(result.issues.some((issue) => issue.code === "INTEGRITY_MISMATCH"));
});

test("C10 prohibited dependency cycles are quarantined without hiding nodes", async () => {
  const left = object("TASK-20260808-001", "TASK", {
    references: [{ relation: "depends_on", target: "TASK-20260808-002" }],
  });
  const right = object("TASK-20260808-002", "TASK", {
    governed_work: {
      id: "TASK-20260808-002",
      primary_carrier_id: "TASK-20260808-002",
    },
    references: [{ relation: "depends_on", target: "TASK-20260808-001" }],
  });
  const result = await reader().read([source("left", left), source("right", right)]);
  assert.equal(result.view_state, "quarantined");
  assert.equal(result.nodes.length, 2);
  assert.ok(result.issues.some((issue) => issue.code === "PROHIBITED_CYCLE"));
});

test("C14 archive state retains complete task, report and transition history", async () => {
  const task = object("TASK-20260808-001", "TASK", {
    creator: "pm-1",
    role: "PM",
    stream: { id: "stream:task", sequence: 1 },
  });
  const report = object("REPORT-20260808-001", "REPORT", {
    creator: "dev-1",
    role: "DEV",
    stream: { id: "stream:report", sequence: 1 },
    references: [{ relation: "reports", target: task.id }],
  });
  const transitions = [
    object("TRANSITION-001", "TRANSITION", {
      creator: "CODEFLOWMU-RUNTIME",
      role: "SYSTEM",
      stream: { id: "stream:t1", sequence: 1 },
      lifecycle: {
        profile: "codeflowmu-fcop-tmpa-s0.5",
        state: "active",
        transition: { from: "inbox", action: "runtime_dispatch", to: "active" },
      },
    }),
    object("TRANSITION-002", "TRANSITION", {
      creator: "dev-1",
      role: "DEV",
      stream: { id: "stream:t2", sequence: 1 },
      lifecycle: {
        profile: "codeflowmu-fcop-tmpa-s0.5",
        state: "review",
        transition: { from: "active", action: "submit_review", to: "review" },
      },
      references: [
        { relation: "depends_on", target: "TRANSITION-001" },
        { relation: "reports", target: report.id },
      ],
    }),
    object("TRANSITION-003", "TRANSITION", {
      creator: "pm-1",
      role: "PM",
      stream: { id: "stream:t3", sequence: 1 },
      lifecycle: {
        profile: "codeflowmu-fcop-tmpa-s0.5",
        state: "done",
        transition: { from: "review", action: "approve_review", to: "done" },
      },
      references: [
        { relation: "depends_on", target: "TRANSITION-002" },
        { relation: "accepts", target: report.id },
      ],
    }),
    object("TRANSITION-004", "TRANSITION", {
      creator: "pm-1",
      role: "PM",
      stream: { id: "stream:t4", sequence: 1 },
      lifecycle: {
        profile: "codeflowmu-fcop-tmpa-s0.5",
        state: "archive",
        transition: { from: "done", action: "archive_task", to: "archive" },
      },
      references: [
        { relation: "depends_on", target: "TRANSITION-003" },
        { relation: "archives", target: task.id },
      ],
    }),
  ];
  const values = [task, report, ...transitions];
  const result = await reader().read(
    values.map((value) => source(value.id, value)),
  );
  assert.equal(result.judgment, "valid");
  assert.equal(result.nodes.length, values.length);
  const summary = result.extensions?.summary as
    | { work_state?: Record<string, string> }
    | undefined;
  assert.equal(
    summary?.work_state?.[task.id],
    "archive",
  );
});
