/**
 * Platform Verification Plan — ref AS/AEGIS-CYBER/VERIFY/2026/001
 * VF-S6: PAM-persistence fire-and-forget durable-write loss — DEMONSTRATION
 *
 * STATUS: post-fix (T004). The VF-S6 production fix is NOW APPLIED to
 * privileged-access.ts (tenant-threaded, savepoint-contained persistPamWrite +
 * fail-closed drop + observable counters) and privileged-access-db.ts (optional
 * `runner` param on savePamRequest/savePamSession). This script is the paired
 * before/after proof:
 *
 *   PART A — MECHANISM & PRE-FIX CONTRAST (raw sinks, NO savepoint wrapper).
 *     S0  harness soundness (owner direct insert observable).
 *     S1  the sink CAN persist when a tenant is threaded + GUC matches (fix shape).
 *     S2  the raw sink with NO tenant (the OLD real-caller shape) → 42501, lost.
 *     S3  THE DISEASE: a swallowed tenant-blind raw write in a request tx poisons
 *         the tx and DESTROYS a correct, unrelated co-tx write (Mode A).
 *     S4  detached raw sink → 42501, total loss, no co-tx collateral (Mode B).
 *   These call the raw PamDB.* sinks directly (bypassing the service), so they
 *   reproduce the pre-fix behaviour regardless of the fix — they are the contrast
 *   that shows WHY the fix is necessary.
 *
 *   PART B — POST-FIX VERIFICATION (real service path, savepoint-contained).
 *     L1  POSITIVE: createAccessRequest with the authorized tenant → row LANDS,
 *         durable AND tenant-correct (the write is no longer lost).
 *     L2  FAIL-CLOSED at the PER-TENANT ACCOUNT GATE: createAccessRequest with
 *         tenant="default" (the real pre-Operation-2 resolution) → REFUSED at the
 *         account lookup ("Account not found") BEFORE any write is attempted, so
 *         NO durable request row exists (count=0). Phase B made all three PAM
 *         tables per-tenant: a "default"/absent tenant has no materialized catalog,
 *         so the account is unreachable — a stronger, earlier guarantee than the
 *         Phase-A persistPamWrite fail-closed drop (now unreachable via the service
 *         because the gate refuses first).
 *     L3  THE CURE (paired control + same-connection interlock): in ONE request
 *         tx — (a) a legit co-write (authorized tenant) LANDS + tenant-correct AND
 *         (b) a cross-tenant op (valid-looking but WRONG tenant vs the GUC) is
 *         REFUSED at the per-tenant account gate ("Account not found", no row) —
 *         the wrong tenant cannot see, and therefore cannot touch, the authorized
 *         tenant's account. The outer tx stays healthy and COMMITs; the legit
 *         co-write SURVIVES. Same-connection interlock asserts the fix's savepoint
 *         and the outer tx share one backend pid (the mechanism the legit write's
 *         containment relies on). Phase B refuses the cross-tenant write at the
 *         catalog boundary — earlier than (and superseding) the Phase-A savepoint
 *         42501 containment for this path.
 *     S5  FULL REAL PATH: create→review→start through the real (now async) service
 *         methods → all three durable rows persist, tenant-correct.
 *
 * Connections:
 *   - owner    = pg.Pool on DATABASE_URL (dev DB owner; bypasses RLS; out-of-band
 *                observer for count / positive-control insert / cleanup).
 *   - realpath = the imported sinks + singleton, which use the module `db` proxy
 *                (appPool = aegis_app restricted role; RLS-enforced). PART A's
 *                request context uses a pinned client + manual BEGIN (raw-sink
 *                contrast). PART B's request context (runRequestPhaseTx) mirrors
 *                tenantMiddleware FAITHFULLY: a Drizzle .transaction() yielding a
 *                real PgTransaction in the AsyncLocalStorage, so the fix's nested
 *                db.transaction() resolves to a genuine SAVEPOINT — exactly the
 *                production mechanism.
 */

import pg from "pg";
import { sql } from "drizzle-orm";
import {
  appPool,
  tenantContext,
  makeClientRunner,
  db,
  type DrizzleDb,
} from "../server/db";
import * as PamDB from "../server/lib/privileged-access-db";
import { privilegedAccess, type PrivilegedAccount } from "../server/lib/privileged-access";

const owner = new pg.Pool({ connectionString: process.env.DATABASE_URL });

const DEMO_TENANT = "vf-s6-tenant";
const WRONG_TENANT = "vf-s6-wrong"; // valid-looking, but != the GUC → induced 42501
const base = Date.now();
const ID = {
  s0: `VF-S6-REQ-S0-${base}`,
  s1: `VF-S6-REQ-S1POS-${base}`,
  s2: `VF-S6-REQ-S2NEG-${base}`,
  s3acct: `VF-S6-ACC-S3POISON-${base}`,
  s3req: `VF-S6-REQ-S3POISON-${base}`,
  s4: `VF-S6-REQ-S4DETACH-${base}`,
};

// service-generated ids captured for cleanup (the real methods mint their own ids)
const captured: { req: string[]; sess: string[] } = { req: [], sess: [] };

const settle = (ms = 1500) => new Promise((r) => setTimeout(r, ms));
const errStr = (e: any) => `${e?.code ?? ""} ${e?.message ?? String(e)}`.trim();
const pidFrom = (r: any): number => Number(r?.rows?.[0]?.pid);

async function countReq(id: string): Promise<number> {
  const r = await owner.query<{ n: string }>(
    "SELECT count(*)::int AS n FROM pam_requests WHERE id = $1",
    [id],
  );
  return Number(r.rows[0].n);
}
async function countAcct(id: string): Promise<number> {
  const r = await owner.query<{ n: string }>(
    "SELECT count(*)::int AS n FROM pam_accounts WHERE id = $1",
    [id],
  );
  return Number(r.rows[0].n);
}
async function countSess(id: string): Promise<number> {
  const r = await owner.query<{ n: string }>(
    "SELECT count(*)::int AS n FROM pam_sessions WHERE id = $1",
    [id],
  );
  return Number(r.rows[0].n);
}
async function tenantOf(id: string): Promise<string | null> {
  const r = await owner.query<{ t: string | null }>(
    "SELECT tenant_id AS t FROM pam_requests WHERE id = $1",
    [id],
  );
  return r.rows[0]?.t ?? null;
}

/** A sentinel pam_requests payload in the exact shape savePamRequest expects.
 *  tenantId is the ONLY variable — omitting it reproduces the real pre-fix caller. */
function reqPayload(id: string, tenantId?: string) {
  return {
    id,
    accountId: ID.s3acct,
    accountName: "VF-S6 Sentinel Account",
    requesterId: "vf-s6-requester",
    requesterName: "VF-S6 Requester",
    justification: "vf-s6 demonstration sentinel",
    requestedDurationMin: 30,
    status: "pending",
    tenantId,
  };
}

/** A sentinel pam_accounts payload (no PII encryption on this sink). */
function acctPayload(id: string, tenantId?: string) {
  const now = new Date();
  return {
    id,
    name: "VF-S6 Sentinel Account",
    type: "system",
    privilegeLevel: "admin",
    description: "vf-s6 demonstration sentinel",
    owner: "vf-s6-owner",
    credentials: {
      rotationPolicy: 90,
      lastRotated: now,
      nextRotation: new Date(now.getTime() + 90 * 86_400_000),
    },
    accessRules: {
      requiresApproval: true,
      approvers: ["vf-s6-approver"],
      maxSessionDuration: 60,
      mfaRequired: true,
      justificationRequired: true,
    },
    checkoutCount: 0,
    lastAccessed: null,
    status: "active",
    tenantId,
  };
}

interface PhaseDiag {
  commitCommand: string; // "COMMIT" = clean, "ROLLBACK" = tx was poisoned/aborted
  commitErr: string;
  phaseErr: string;
}

/** PART A request runtime: pinned appPool client + manual BEGIN + LOCAL tenant GUC
 *  + tenantContext ALS active. Used ONLY for the raw-sink contrast legs (S1–S3),
 *  which do NOT call the fixed service's nested db.transaction(). It always
 *  attempts COMMIT (as the real middleware does after a handler returns) and
 *  reports whether that COMMIT silently degraded to ROLLBACK — the Mode-A
 *  signature. (For the fixed service path use runRequestPhaseTx instead.) */
async function runRequestPhase(
  tenantId: string,
  fn: (client: pg.PoolClient) => Promise<void>,
): Promise<PhaseDiag> {
  const client = await appPool.connect();
  const diag: PhaseDiag = { commitCommand: "", commitErr: "", phaseErr: "" };
  try {
    await client.query("BEGIN");
    await client.query("SELECT set_config('app.current_tenant_id', $1, true)", [
      tenantId,
    ]);
    const runner = makeClientRunner(client);
    try {
      await tenantContext.run({ runner, tenantId }, () => fn(client));
    } catch (e: any) {
      diag.phaseErr = errStr(e);
    }
    try {
      const r = await client.query("COMMIT");
      diag.commitCommand = r.command; // pg returns "ROLLBACK" for COMMIT on aborted tx
    } catch (e: any) {
      diag.commitErr = errStr(e);
      try {
        await client.query("ROLLBACK");
      } catch {}
    }
  } finally {
    client.release();
  }
  return diag;
}

/** PART B request runtime — FAITHFUL to tenantMiddleware. A Drizzle .transaction()
 *  on a single pinned appPool client yields a REAL PgTransaction; we set the LOCAL
 *  tenant GUC inside it and stash the PgTransaction in the same AsyncLocalStorage
 *  the middleware uses. The fix's nested `db.transaction()` therefore resolves to a
 *  genuine SAVEPOINT on this connection (not a second BEGIN) — the exact
 *  production mechanism. Drizzle COMMITs when the callback returns and ROLLBACKs if
 *  it throws (we never force rollback here; every PART B leg commits). */
async function runRequestPhaseTx(
  tenantId: string,
  fn: (tx: DrizzleDb) => Promise<void>,
): Promise<PhaseDiag> {
  const client = await appPool.connect();
  const diag: PhaseDiag = { commitCommand: "", commitErr: "", phaseErr: "" };
  try {
    const tdb = makeClientRunner(client);
    try {
      await tdb.transaction(async (tx) => {
        await tx.execute(
          sql`SELECT set_config('app.current_tenant_id', ${tenantId}, true)`,
        );
        await tenantContext.run(
          { runner: tx as unknown as DrizzleDb, tenantId },
          () => fn(tx as unknown as DrizzleDb),
        );
      });
      diag.commitCommand = "COMMIT";
    } catch (e: any) {
      diag.phaseErr = errStr(e);
      diag.commitCommand = "ROLLBACK";
    }
  } finally {
    client.release();
  }
  return diag;
}

interface Row {
  id: string;
  scenario: string;
  expectation: string;
  observed: string;
  verdict: string;
}
const rows: Row[] = [];
const record = (r: Row) => rows.push(r);

async function main() {
  console.log("=".repeat(80));
  console.log("VF-S6 — PAM-persistence fire-and-forget durable-write loss — POST-FIX DEMO");
  console.log(
    "ref AS/AEGIS-CYBER/VERIFY/2026/001 | env: DEV |",
    new Date().toISOString(),
  );
  console.log("=".repeat(80));
  console.log("");
  console.log("### PART A — MECHANISM & PRE-FIX CONTRAST (raw sinks, NO savepoint) ###");

  // ── S0 — harness positive control (owner direct INSERT, bypasses RLS) ─────────
  {
    let err = "";
    try {
      await owner.query(
        `INSERT INTO pam_requests
           (id, account_id, account_name, requester_id, requester_name,
            justification, requested_duration_min, status, tenant_id)
         VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9)`,
        [
          ID.s0, ID.s3acct, "VF-S6 Sentinel Account", "vf-s6-requester",
          "VF-S6 Requester", "vf-s6 harness check", 30, "pending", DEMO_TENANT,
        ],
      );
    } catch (e) {
      err = errStr(e);
    }
    const n = await countReq(ID.s0);
    record({
      id: "S0",
      scenario: "owner direct INSERT into pam_requests (out-of-band observer)",
      expectation: "row lands; count=1 (proves the count harness detects a real row)",
      observed: `count=${n}${err ? ` err=${err}` : ""}`,
      verdict: n === 1 && !err ? "PASS (harness sound)" : "ANOMALY",
    });
  }

  // ── S1 — POSITIVE: raw sink WITH tenantId threaded + GUC set (the fix shape) ──
  {
    let threw = "no";
    let err = "";
    const diag = await runRequestPhase(DEMO_TENANT, async () => {
      try {
        await PamDB.savePamRequest(reqPayload(ID.s1, DEMO_TENANT));
      } catch (e: any) {
        threw = "YES";
        err = errStr(e);
      }
    });
    const n = await countReq(ID.s1);
    record({
      id: "S1",
      scenario: "savePamRequest — GUC set + tenantId threaded to match (FIX SHAPE)",
      expectation: "no throw; COMMIT clean; count=1 (sink CAN persist when threaded)",
      observed: `threw=${threw}${err ? `(${err})` : ""} commit=${diag.commitCommand} count=${n}`,
      verdict:
        threw === "no" && diag.commitCommand === "COMMIT" && n === 1
          ? "PASS (real persist path works — failure is a real omission, not a dead sink)"
          : "ANOMALY (positive control did not land)",
    });
  }

  // ── S2 — NEGATIVE mechanism: raw sink, NO tenantId, GUC set (OLD caller shape) ─
  {
    let threw = "no";
    let err = "";
    const diag = await runRequestPhase(DEMO_TENANT, async () => {
      try {
        await PamDB.savePamRequest(reqPayload(ID.s2)); // NO tenantId — old shape
      } catch (e: any) {
        threw = "YES";
        err = errStr(e);
      }
    });
    const n = await countReq(ID.s2);
    record({
      id: "S2",
      scenario: "savePamRequest — GUC set, NO tenantId (OLD pre-fix caller shape)",
      expectation: "RLS rejects (42501, NULL tenant_id); throw captured; count=0",
      observed: `threw=${threw}(${err}) commit=${diag.commitCommand} count=${n}`,
      verdict:
        threw === "YES" && err.startsWith("42501") && n === 0
          ? "PRE-FIX LOSS CONFIRMED (durable write FAILS in raw in-request shape, 42501)"
          : n === 1
            ? "SURPRISE: NULL tenant_id row PERSISTED (policy permits NULL)"
            : "ANOMALY",
    });
  }

  // ── S3 — MODE A (THE DISEASE): a correct co-tx write destroyed by the swallowed one ─
  {
    let legitWithinTx = -1;
    let brokenThrew = "no";
    let brokenErr = "";
    let poisoned = "unknown";

    const diag = await runRequestPhase(DEMO_TENANT, async (client) => {
      // 1. a LEGITIMATE durable write that WOULD succeed (correct tenantId, passes RLS)
      await PamDB.savePamAccount(acctPayload(ID.s3acct, DEMO_TENANT));
      // 2. confirm it is visible within the still-healthy transaction
      const within = await client.query<{ n: string }>(
        "SELECT count(*)::int AS n FROM pam_accounts WHERE id = $1",
        [ID.s3acct],
      );
      legitWithinTx = Number(within.rows[0].n);
      // 3. now the OLD raw caller shape: a tenant-blind fire-and-forget write (captured)
      try {
        await PamDB.savePamRequest(reqPayload(ID.s3req)); // NO tenantId
        brokenThrew = "no";
      } catch (e: any) {
        brokenThrew = "YES";
        brokenErr = errStr(e);
      }
      // 4. probe whether the transaction is now poisoned (aborted)
      try {
        await client.query("SELECT 1");
        poisoned = "NO (tx still healthy)";
      } catch (e: any) {
        poisoned =
          e?.code === "25P02" ? "YES (25P02 in_failed_sql_transaction)" : `other:${errStr(e)}`;
      }
    });

    // 5. out-of-band: did EITHER write survive the COMMIT?
    const acctAfter = await countAcct(ID.s3acct);
    const reqAfter = await countReq(ID.s3req);

    const modeA =
      legitWithinTx === 1 &&
      brokenThrew === "YES" &&
      brokenErr.startsWith("42501") &&
      poisoned.startsWith("YES") &&
      diag.commitCommand === "ROLLBACK" &&
      acctAfter === 0 &&
      reqAfter === 0;

    record({
      id: "S3",
      scenario:
        "MODE A (raw) — legit co-tx write + swallowed tenant-blind write in ONE request tx",
      expectation:
        "legit visible in-tx (1); broken 42501; tx poisoned (25P02); COMMIT->ROLLBACK; BOTH lost (0,0)",
      observed:
        `legitInTx=${legitWithinTx} broken=${brokenThrew}(${brokenErr}) ` +
        `poisoned=${poisoned} commit=${diag.commitCommand} ` +
        `acctAfter=${acctAfter} reqAfter=${reqAfter}`,
      verdict: modeA
        ? "DISEASE CONFIRMED (raw swallowed PAM write poisons the request tx -> a correct, unrelated durable write is DESTROYED) — cured by L3"
        : "ANOMALY (Mode A not reproduced as predicted — re-derive)",
    });
  }

  // ── S4 — MODE B CONTRAST: raw sink, NO tenantId, NO request context (detached) ─
  {
    let threw = "no";
    let err = "";
    try {
      await PamDB.savePamRequest(reqPayload(ID.s4)); // NO tenantId, NO tenantContext
    } catch (e: any) {
      threw = "YES";
      err = errStr(e);
    }
    const n = await countReq(ID.s4);
    record({
      id: "S4",
      scenario: "savePamRequest — NO tenantId, NO request context (detached shape)",
      expectation:
        "RLS rejects (42501, GUC null + NULL tenant_id); count=0; standalone, no tx to poison",
      observed: `threw=${threw}(${err}) count=${n}`,
      verdict:
        threw === "YES" && err.startsWith("42501") && n === 0
          ? "MODE B mechanism shown (total loss, NO co-tx collateral) — NOT the real-path mode (real callers run in-request, see S3/L3)"
          : "ANOMALY",
    });
  }

  console.log("");
  console.log("### PART B — POST-FIX VERIFICATION (real service path, savepoint-contained) ###");

  // Phase B — accounts are per-tenant durable + lazily seeded. Materialize the
  // DEMO_TENANT catalog inside a real request tx (getAccounts → ensureAccountsSeeded
  // runs persistPamWrite, which needs the AsyncLocalStorage tenant context + GUC);
  // the tx COMMITs so the seeded rows are visible to the L1/L2/L3/S5 legs below.
  let accounts: PrivilegedAccount[] = [];
  await runRequestPhaseTx(DEMO_TENANT, async () => {
    accounts = await privilegedAccess.getAccounts(undefined, { tenantId: DEMO_TENANT });
  });
  const seed = accounts.find((a) => a.status === "active") ?? accounts[0];

  // ── L1 — POSITIVE: createAccessRequest with authorized tenant → row LANDS ─────
  if (!seed) {
    record({
      id: "L1",
      scenario: "createAccessRequest (authorized tenant)",
      expectation: "n/a",
      observed: "SKIPPED — no in-memory seeded PAM account",
      verdict: "INCONCLUSIVE",
    });
  } else {
    let note = "";
    let id = "";
    const diag = await runRequestPhaseTx(DEMO_TENANT, async () => {
      const created = await privilegedAccess.createAccessRequest(
        {
          accountId: seed.id,
          requesterId: "vf-s6-l1-requester",
          requesterName: "VF-S6 L1 Requester",
          justification: "vf-s6 L1 land + tenant-correct",
          requestedDuration: 15,
        },
        { tenantId: DEMO_TENANT },
      );
      if ("error" in created) {
        note = created.error;
        return;
      }
      id = created.id;
      captured.req.push(id);
    });
    const n = id ? await countReq(id) : 0;
    const t = id ? await tenantOf(id) : null;
    record({
      id: "L1",
      scenario: "createAccessRequest — authorized tenant, real service path (FIX)",
      expectation: "COMMIT; count=1; tenant_id = authorized tenant (durable AND correct)",
      observed: `commit=${diag.commitCommand} count=${n} tenant_id=${t ?? "-"}${note ? ` note=${note}` : ""}`,
      verdict:
        diag.commitCommand === "COMMIT" && n === 1 && t === DEMO_TENANT
          ? "PASS (durable write LANDS, tenant-correct — the loss is fixed)"
          : `ANOMALY${note ? ` — ${note}` : ""}`,
    });
  }

  // ── L2 — FAIL-CLOSED at the per-tenant account gate: tenant="default" → REFUSED ─
  if (seed) {
    let note = "";
    let id = "";
    const diag = await runRequestPhaseTx(DEMO_TENANT, async () => {
      const created = await privilegedAccess.createAccessRequest(
        {
          accountId: seed.id,
          requesterId: "vf-s6-l2-requester",
          requesterName: "VF-S6 L2 Requester",
          justification: "vf-s6 L2 fail-closed at account gate",
          requestedDuration: 15,
        },
        { tenantId: "default" }, // the real pre-Operation-2 resolution
      );
      if ("error" in created) {
        note = created.error;
        return;
      }
      id = created.id;
      captured.req.push(id);
    });
    const n = id ? await countReq(id) : 0;
    record({
      id: "L2",
      scenario: 'createAccessRequest — tenant="default" (per-tenant account gate)',
      expectation:
        'REFUSED at account lookup (error "Account not found"); NO durable row (count=0); no id minted',
      observed: `commit=${diag.commitCommand} count=${n} returnedId=${id || "-"} note=${note || "-"}`,
      verdict:
        note === "Account not found" && n === 0 && id === ""
          ? "PASS (fail-closed at the per-tenant account gate — a default/absent tenant reaches NO account, so no request is ever written)"
          : `ANOMALY${note ? ` — ${note}` : ""}`,
    });
  }

  // ── L3 — THE CURE: legit LANDS + cross-tenant REFUSED at gate (paired control) ─
  if (seed) {
    let note = "";
    let legitId = "";
    let inducedId = "";
    let inducedNote = "";
    let outerPid = -1;
    let spPid = -1;
    let txHealthy = "unknown";

    const diag = await runRequestPhaseTx(DEMO_TENANT, async (tx) => {
      // backend pid of the OUTER request tx
      outerPid = pidFrom(await tx.execute(sql`SELECT pg_backend_pid() AS pid`));

      // (a) legit co-write — authorized tenant; savepoint RELEASEs into the outer tx
      const legit = await privilegedAccess.createAccessRequest(
        {
          accountId: seed.id,
          requesterId: "vf-s6-l3-legit",
          requesterName: "VF-S6 L3 Legit",
          justification: "vf-s6 L3 legit co-write",
          requestedDuration: 15,
        },
        { tenantId: DEMO_TENANT },
      );
      if (!("error" in legit)) {
        legitId = legit.id;
        captured.req.push(legitId);
      }

      // same-connection interlock: a savepoint opened via the resolved `db` runs on
      // the SAME backend as the outer tx (the mechanism the fix relies on).
      spPid = await db.transaction(async (sp) =>
        pidFrom(await sp.execute(sql`SELECT pg_backend_pid() AS pid`)),
      );

      // (b) cross-tenant op — valid-looking tenant but != the GUC. Phase B refuses
      //     it at the per-tenant account gate: the WRONG tenant has no materialized
      //     catalog (and cannot see DEMO_TENANT's rows under RLS), so the account
      //     lookup misses → "Account not found", BEFORE any write. No 42501 is even
      //     induced (the gate is earlier than the savepoint containment layer).
      const induced = await privilegedAccess.createAccessRequest(
        {
          accountId: seed.id,
          requesterId: "vf-s6-l3-induced",
          requesterName: "VF-S6 L3 Induced",
          justification: "vf-s6 L3 cross-tenant refused",
          requestedDuration: 15,
        },
        { tenantId: WRONG_TENANT },
      );
      if ("error" in induced) {
        inducedNote = induced.error;
      } else {
        inducedId = induced.id;
      }

      // (c) outer tx must still be HEALTHY (the cross-tenant op never poisoned it)
      try {
        await tx.execute(sql`SELECT 1`);
        txHealthy = "YES (outer tx healthy)";
      } catch (e: any) {
        txHealthy =
          e?.code === "25P02" ? "NO (25P02 poisoned)" : `other:${errStr(e)}`;
      }
    });

    const legitN = legitId ? await countReq(legitId) : 0;
    const legitT = legitId ? await tenantOf(legitId) : null;
    const inducedN = inducedId ? await countReq(inducedId) : 0;
    const sameConn = outerPid > 0 && outerPid === spPid;

    const cured =
      diag.commitCommand === "COMMIT" &&
      txHealthy.startsWith("YES") &&
      legitN === 1 &&
      legitT === DEMO_TENANT &&
      inducedNote === "Account not found" &&
      inducedId === "" &&
      inducedN === 0 &&
      sameConn;

    record({
      id: "L3",
      scenario:
        "CURE — legit co-write LANDS + cross-tenant op REFUSED at the per-tenant account gate (paired control)",
      expectation:
        'outer tx healthy; COMMIT; legit SURVIVES (1, tenant-correct); cross-tenant REFUSED ("Account not found", 0); same backend pid',
      observed:
        `commit=${diag.commitCommand} txHealthy=${txHealthy} ` +
        `legitN=${legitN} legitTenant=${legitT ?? "-"} inducedNote=${inducedNote || "-"} inducedN=${inducedN} ` +
        `outerPid=${outerPid} spPid=${spPid} sameConn=${sameConn}` +
        (note ? ` note=${note}` : ""),
      verdict: cured
        ? "PASS (POSITIVE: legit write survives + tenant-correct; NEGATIVE: cross-tenant op refused at the per-tenant account gate, no row, outer tx unpoisoned) — F-RP-01 cross-tenant read/write CLOSED for accounts"
        : `ANOMALY${note ? ` — ${note}` : ""}`,
    });
  }

  // ── S5 — FULL real method path create->review->start (now async, fixed) ──────
  if (!seed) {
    record({
      id: "S5",
      scenario: "privilegedAccess full real path (in-request)",
      expectation: "n/a",
      observed: "SKIPPED — no in-memory seeded PAM account",
      verdict: "INCONCLUSIVE",
    });
  } else {
    let note = "";
    let createdOk = "no";
    let startedOk = "no";
    let escaped = "no";
    let reqId = "";
    let sessId = "";

    const diag = await runRequestPhaseTx(DEMO_TENANT, async () => {
      try {
        const created = await privilegedAccess.createAccessRequest(
          {
            accountId: seed.id,
            requesterId: "vf-s6-e2e-requester",
            requesterName: "VF-S6 E2E Requester",
            justification: "vf-s6 end-to-end demonstration",
            requestedDuration: 15,
          },
          { tenantId: DEMO_TENANT },
        );
        if ("error" in created) {
          note = `createAccessRequest error: ${created.error}`;
          return;
        }
        createdOk = "yes";
        reqId = created.id;
        captured.req.push(reqId);

        let approved = created;
        if (created.status === "pending") {
          const rev = await privilegedAccess.reviewRequest(
            created.id,
            "vf-s6-reviewer",
            "approved",
            "vf-s6 auto-approve",
            { tenantId: DEMO_TENANT },
          );
          if ("error" in rev) {
            note = `reviewRequest error: ${rev.error}`;
            return;
          }
          approved = rev;
        }

        const sess = await privilegedAccess.startSession(approved.id, {
          tenantId: DEMO_TENANT,
        });
        if ("error" in sess) {
          note = `startSession error: ${sess.error}`;
          return;
        }
        startedOk = "yes";
        sessId = sess.id;
        captured.sess.push(sessId);
      } catch (e: any) {
        escaped = `YES(${errStr(e)})`;
      }
    });

    const reqAfter = reqId ? await countReq(reqId) : -1;
    const sessAfter = sessId ? await countSess(sessId) : -1;

    const persisted =
      createdOk === "yes" &&
      startedOk === "yes" &&
      escaped === "no" &&
      diag.commitCommand === "COMMIT" &&
      reqAfter === 1 &&
      sessAfter === 1;

    record({
      id: "S5",
      scenario:
        "privilegedAccess create->approve->startSession (full real path, in-request, FIXED)",
      expectation:
        "all methods succeed; nothing escapes; COMMIT clean; request row persists (1); session row persists (1)",
      observed:
        `created=${createdOk} started=${startedOk} escaped=${escaped} ` +
        `commit=${diag.commitCommand} reqAfter=${reqAfter} sessAfter=${sessAfter} ` +
        `reqId=${reqId || "-"} sessId=${sessId || "-"}` +
        (note ? ` note=${note}` : ""),
      verdict: persisted
        ? "PASS (full real path NOW PERSISTS — request + session durable, tenant-correct; no escape)"
        : note
          ? `INCONCLUSIVE — ${note}`
          : "ANOMALY",
    });
  }

  // ── Report ────────────────────────────────────────────────────────────────────
  console.log("");
  for (const r of rows) {
    console.log("-".repeat(80));
    console.log(`[${r.id}] ${r.scenario}`);
    console.log(`     expect  : ${r.expectation}`);
    console.log(`     observed: ${r.observed}`);
    console.log(`     VERDICT : ${r.verdict}`);
  }
  console.log("-".repeat(80));

  // ── Cleanup (owner bypasses RLS) ────────────────────────────────────────────────
  const reqIds = [ID.s0, ID.s1, ID.s2, ID.s3req, ID.s4, ...captured.req];
  const d1 = await owner.query(
    "DELETE FROM pam_requests WHERE id = ANY($1::text[]) OR tenant_id = $2",
    [reqIds, DEMO_TENANT],
  );
  const d2 = await owner.query(
    "DELETE FROM pam_accounts WHERE id = ANY($1::text[]) OR tenant_id = $2",
    [[ID.s3acct], DEMO_TENANT],
  );
  const d3 = await owner.query(
    "DELETE FROM pam_sessions WHERE id = ANY($1::text[]) OR tenant_id = $2",
    [captured.sess, DEMO_TENANT],
  );
  console.log(
    `cleanup: deleted ${d1.rowCount} pam_requests + ${d2.rowCount} pam_accounts + ${d3.rowCount} pam_sessions sentinel row(s).`,
  );
  console.log("=".repeat(80));

  await owner.end();
  await appPool.end();
}

main().catch(async (e) => {
  console.error("FATAL:", e);
  try {
    await owner.end();
  } catch {}
  try {
    await appPool.end();
  } catch {}
  process.exit(1);
});
