// Seed data for Violet ITSM prototype
// Tickets span the scoped Tier-1 bucket. Each has a full agent trace.

const now = new Date('2026-04-20T14:22:00');
const ago = (min) => {
  const d = new Date(now.getTime() - min * 60000);
  return d.toISOString();
};
const inFuture = (min) => {
  const d = new Date(now.getTime() + min * 60000);
  return d.toISOString();
};

const USERS = {
  'mgrant': { upn: 'maria.grant@nyulangone.org', name: 'Maria Grant', dept: 'Cardiology', title: 'RN, Cardiac ICU', location: '1 Park Ave · 12W · Room 1208', manager: 'David Chen', tenure: '4y 2mo', phone: '+1 (212) 555-0144' },
  'jokoye': { upn: 'james.okoye@nyulangone.org', name: 'James Okoye', dept: 'Radiology', title: 'Radiology Tech', location: '550 First Ave · Tisch B2', manager: 'Priya Shah', tenure: '1y 8mo', phone: '+1 (212) 555-0188' },
  'rpatel': { upn: 'rohan.patel@nyulangone.org', name: 'Rohan Patel, MD', dept: 'Emergency Medicine', title: 'Attending Physician', location: '550 First Ave · ED', manager: 'Sarah Kim, MD', tenure: '6y 11mo', phone: '+1 (212) 555-0211' },
  'awu': { upn: 'alice.wu@nyulangone.org', name: 'Alice Wu', dept: 'Revenue Cycle', title: 'Billing Analyst', location: '1 Park Ave · 8E · 0841', manager: 'Tom Ricci', tenure: '2y 3mo', phone: '+1 (212) 555-0399' },
  'dcarr': { upn: 'daniel.carr@nyulangone.org', name: 'Daniel Carr', dept: 'Oncology', title: 'Clinical Research Coord.', location: 'Off-site · Remote', manager: 'Laila Bhatt', tenure: '11mo', phone: '+1 (212) 555-0477' },
  'lchen': { upn: 'lisa.chen@nyulangone.org', name: 'Lisa Chen', dept: 'Pharmacy', title: 'Pharmacist', location: '1 Park Ave · 4C', manager: 'Mike Frye', tenure: '5y 6mo', phone: '+1 (212) 555-0522' },
  'ktorres': { upn: 'kevin.torres@nyulangone.org', name: 'Kevin Torres', dept: 'Facilities', title: 'Ops Supervisor', location: '1 Park Ave · B1', manager: 'Anna Lee', tenure: '3y 1mo', phone: '+1 (212) 555-0610' },
};

const DEVICES = {
  'd-441': { id: 'NYU-LT-441', model: 'Dell Latitude 7440', os: 'Win 11 23H2', compliant: true, lastSeen: '2 min ago', user: 'mgrant' },
  'd-892': { id: 'NYU-WS-892', model: 'HP EliteDesk 800', os: 'Win 11 23H2', compliant: true, lastSeen: '14 min ago', user: 'awu' },
  'd-203': { id: 'NYU-LT-203', model: 'MacBook Pro 14" M3', os: 'macOS 14.4', compliant: true, lastSeen: '1 hr ago', user: 'rpatel' },
  'd-556': { id: 'NYU-LT-556', model: 'Dell Latitude 5430', os: 'Win 11 22H2', compliant: false, lastSeen: '3 days ago', user: 'jokoye' },
  'd-778': { id: 'NYU-MP-778', model: 'iPhone 14', os: 'iOS 17.4', compliant: true, lastSeen: '19 min ago', user: 'dcarr' },
  'd-334': { id: 'NYU-LT-334', model: 'Dell Latitude 7440', os: 'Win 11 23H2', compliant: true, lastSeen: '2 hr ago', user: 'lchen' },
  'd-661': { id: 'NYU-LT-661', model: 'Dell Latitude 7440', os: 'Win 11 23H2', compliant: true, lastSeen: '32 min ago', user: 'ktorres' },
};

// Agent trace: each step is what the LLM + tools did.
// status: done | running | queued | failed | hitl
const TICKETS = [
  {
    id: 'INC-0041287',
    subject: 'Locked out of my account again',
    user: 'mgrant',
    device: 'd-441',
    source: 'teams',
    category: 'Account & access',
    subcategory: 'Account unlock',
    urgency: 'high',
    status: 'auto-resolved',
    disposition: 'resolved-by-agent',
    confidence: 0.97,
    createdAt: ago(8),
    closedAt: ago(6),
    slaDueAt: inFuture(52),
    assignedTo: 'Violet',
    ttr: '1m 47s',
    humanBaseline: '11m',
    phi: false,
    verifierModel: 'Claude Sonnet 4.6',
    plannerModel: 'Claude Sonnet 4.6',
    classifierModel: 'Claude Haiku 4.6',
    originalMessage: "Hi — I'm locked out of my account again. I need to get into Epic for morning rounds in 20 min. Can someone help fast? Thanks, Maria",
    trace: [
      { t: '14:14:13', agent: 'ingest', tool: null, action: 'Normalized Teams webhook → ticket', detail: 'Channel: #desktop-support-1pa · Author: Maria Grant', status: 'done', duration: 120 },
      { t: '14:14:14', agent: 'classify', tool: null, action: 'Intent · Category · Urgency', detail: 'Intent: account_unlock (0.97) · Category: Account & access · Urgency: High — morning rounds cited', status: 'done', duration: 340, model: 'Haiku 4.6' },
      { t: '14:14:14', agent: 'classify', tool: 'phi-classifier', action: 'PHI scan on ticket body', detail: 'No PHI detected. Safe for all-model routing.', status: 'done', duration: 80 },
      { t: '14:14:15', agent: 'enrich', tool: 'cmdb-mcp', action: 'Resolve user + primary device', detail: 'Maria Grant · Cardiology · NYU-LT-441 (compliant)', status: 'done', duration: 210 },
      { t: '14:14:15', agent: 'enrich', tool: 'ldap-mcp', action: 'Query AD account state', detail: 'sAMAccountName=mgrant · lockoutTime=2026-04-20 14:09:41 · badPwdCount=5', status: 'done', duration: 180 },
      { t: '14:14:15', agent: 'memory', tool: 'knowledge-mcp', action: 'Retrieve past-resolution pattern', detail: '3 prior unlocks in last 30d · pattern: typing errors after PTO returns · runbook RB-0042 matched (0.94)', status: 'done', duration: 260 },
      { t: '14:14:16', agent: 'dispatch', tool: null, action: 'Route → Account specialist', detail: 'allow-list: ldap-mcp · comms-mcp', status: 'done', duration: 40 },
      { t: '14:14:16', agent: 'plan', tool: null, action: 'Draft plan · confidence 0.97', detail: 'Step 1: verify identity via recent MFA · Step 2: Unlock AD account · Step 3: Notify user in same thread · Step 4: Verify Epic SSO works', status: 'done', duration: 520, model: 'Sonnet 4.6' },
      { t: '14:14:17', agent: 'account', tool: 'ldap-mcp', action: 'verify_recent_mfa(upn=mgrant)', detail: 'DUO push accepted at 14:12:58 from trusted device NYU-LT-441. Identity confirmed.', status: 'done', duration: 340 },
      { t: '14:14:18', agent: 'account', tool: 'ldap-mcp', action: 'unlock_account(upn=mgrant)', detail: 'Unlocked. lockoutTime reset to 0. Replicated across 4 DCs.', status: 'done', duration: 820 },
      { t: '14:14:19', agent: 'verify', tool: 'ldap-mcp', action: 'Independent verification (separate LLM call)', detail: 'Queried AD account state with different prompt. lockoutTime=0 confirmed. Last interactive logon 14:15:02. Safe to close.', status: 'done', duration: 610, model: 'Sonnet 4.6' },
      { t: '14:14:19', agent: 'respond', tool: 'comms-mcp', action: 'Reply in original Teams thread', detail: "Template: unlock_success_warm. Message: 'Hi Maria — you're unlocked. Try signing in now; if Epic still blocks you I can push a fresh cert. — Violet'", status: 'done', duration: 240 },
      { t: '14:16:00', agent: 'follow-up', tool: null, action: 'Monitor for reopen 72h', detail: 'Reopen watcher armed. Pulse survey queued for +15 min.', status: 'done', duration: 10 },
    ],
    notes: [
      { author: 'Violet', type: 'work', body: 'Unlocked mgrant via ldap-mcp. DUO MFA confirmed ≤2 min ago. User re-authed into Epic at 14:15:02. Closing.', ts: ago(6) },
    ],
    userMessages: [
      { from: 'user', body: "Hi — I'm locked out of my account again. I need to get into Epic for morning rounds in 20 min. Can someone help fast? Thanks, Maria", ts: ago(8) },
      { from: 'agent', body: "Hi Maria — you're unlocked. Try signing in now; if Epic still blocks you I can push a fresh cert. — Violet", ts: ago(6) },
      { from: 'user', body: "Thank you!! Just got in.", ts: ago(4) },
    ],
    kbas: [
      { id: 'RB-0042', title: 'AD account unlock — post-absence pattern', score: 0.94 },
      { id: 'KBA-1109', title: 'When to require fresh MFA before unlock', score: 0.71 },
    ],
    related: [{ id: 'INC-0039221', subject: 'Locked out after PTO', age: '14d' }, { id: 'INC-0036104', subject: 'Account unlock', age: '42d' }],
  },

  {
    id: 'INC-0041301',
    subject: 'Lost my laptop on the M15 bus last night',
    user: 'jokoye',
    device: 'd-556',
    source: 'portal',
    category: 'Device',
    subcategory: 'Lost/stolen — Intune wipe',
    urgency: 'critical',
    status: 'hitl-required',
    disposition: 'awaiting-human',
    confidence: 0.99,
    createdAt: ago(22),
    slaDueAt: inFuture(8),
    assignedTo: 'HITL queue',
    ttr: null,
    humanBaseline: '24m',
    phi: true,
    phiReason: 'Device may contain cached patient images from Radiology workflow.',
    verifierModel: 'Claude Sonnet 4.6',
    plannerModel: 'Claude Sonnet 4.6',
    classifierModel: 'Claude Haiku 4.6',
    originalMessage: "I think I left my work laptop on the M15 bus last night on the way home. I realized this morning when I got to work. It's the Dell Latitude. Please help — I know it had some patient imaging notes cached from Friday's workflow.",
    trace: [
      { t: '14:00:03', agent: 'ingest', tool: null, action: 'Normalized portal form → ticket', status: 'done', duration: 90 },
      { t: '14:00:04', agent: 'classify', tool: 'phi-classifier', action: 'PHI scan', detail: '⚠ PHI boundary engaged — user self-disclosed cached patient imaging. Redaction active for all external model routes.', status: 'done', duration: 120 },
      { t: '14:00:04', agent: 'classify', tool: null, action: 'Intent · Category · Urgency', detail: 'Intent: device_lost_stolen (0.99) · Urgency: Critical', status: 'done', duration: 310, model: 'Haiku 4.6' },
      { t: '14:00:05', agent: 'enrich', tool: 'intune-mcp', action: 'Device posture check', detail: 'NYU-LT-556 · last check-in 3 days ago · BitLocker enabled · compliance lapsed (MDM)', status: 'done', duration: 420 },
      { t: '14:00:05', agent: 'enrich', tool: 'cmdb-mcp', action: 'Resolve owner + recent activity', detail: 'James Okoye · Radiology · 17 Epic sessions last 7d', status: 'done', duration: 180 },
      { t: '14:00:06', agent: 'plan', tool: null, action: 'Draft plan · confidence 0.99', detail: 'Step 1: Suspend AD account · Step 2: Revoke MFA tokens · Step 3: Initiate Intune selective wipe · Step 4: File security incident · Step 5: Start loaner request', status: 'done', duration: 640, model: 'Sonnet 4.6' },
      { t: '14:00:07', agent: 'gate', tool: null, action: 'Destructive-action gate engaged', detail: 'Intune wipe is destructive. Always HITL regardless of confidence (0.99). Queued for Lead review.', status: 'hitl', duration: 20 },
      { t: '14:00:07', agent: 'prepare', tool: null, action: 'Assemble HITL packet', detail: 'Proposed 5-step plan · BitLocker key pre-staged · security@ pre-drafted · loaner L-022 held', status: 'done', duration: 380 },
      { t: '14:22:00', agent: 'wait', tool: null, action: 'Awaiting human approval', detail: 'Lead: any of 3 on duty. SLA 30m — 8m remaining.', status: 'running', duration: null },
    ],
    notes: [
      { author: 'Violet', type: 'work', body: 'Plan ready. Device is BitLocker-encrypted and has not checked in for 3 days — loss window is bounded. Requesting HITL approval to execute full 5-step plan. Loaner L-022 pre-staged at 1 PA concierge. Suggest notifying security@nyulangone.org on approval.', ts: ago(22) },
    ],
    userMessages: [
      { from: 'user', body: "I think I left my work laptop on the M15 bus last night on the way home. I realized this morning when I got to work. It's the Dell Latitude. Please help — I know it had some patient imaging notes cached from Friday's workflow.", ts: ago(22), redactedBody: "I think I left my work laptop on the [TRANSIT] last night on the way home. I realized this morning when I got to work. It's the Dell Latitude. Please help — I know it had some [PHI-REDACTED: patient imaging notes cached] from Friday's workflow." },
      { from: 'agent', body: "Hi James — I've routed this to a lead for approval because a device wipe is involved. They'll act within 30 min; I've already staged a loaner at the 1 Park Ave concierge. — Violet", ts: ago(21) },
    ],
    kbas: [
      { id: 'RB-0101', title: 'Lost/stolen device — 5-step remediation', score: 0.99 },
      { id: 'KBA-0712', title: 'BitLocker recovery key escrow', score: 0.88 },
      { id: 'POL-0004', title: 'HIPAA breach assessment thresholds', score: 0.85 },
    ],
    related: [],
  },

  {
    id: 'INC-0041295',
    subject: "Teams won't open after this morning's update",
    user: 'awu',
    device: 'd-892',
    source: 'email',
    category: 'Endpoint',
    subcategory: 'App remediation',
    urgency: 'medium',
    status: 'in-progress',
    disposition: 'agent-working',
    confidence: 0.88,
    createdAt: ago(3),
    slaDueAt: inFuture(117),
    assignedTo: 'Violet',
    ttr: null,
    humanBaseline: '18m',
    phi: false,
    verifierModel: 'Claude Sonnet 4.6',
    plannerModel: 'Claude Sonnet 4.6',
    classifierModel: 'Claude Haiku 4.6',
    originalMessage: "Teams won't launch. I click the icon and nothing happens. Also noticed my Outlook profile looks weird since this morning. Already tried restarting twice.",
    trace: [
      { t: '14:19:04', agent: 'ingest', tool: null, action: 'Normalized email → ticket', status: 'done', duration: 110 },
      { t: '14:19:05', agent: 'classify', tool: null, action: 'Intent · Category · Urgency', detail: 'Primary: app_won_t_open (Teams). Secondary: outlook_profile_anomaly. Urgency: Medium.', status: 'done', duration: 330, model: 'Haiku 4.6' },
      { t: '14:19:05', agent: 'enrich', tool: 'cmdb-mcp', action: 'Resolve user + device', detail: 'Alice Wu · Revenue Cycle · NYU-WS-892', status: 'done', duration: 220 },
      { t: '14:19:06', agent: 'enrich', tool: 'intune-mcp', action: 'Device posture + update history', detail: 'Compliant · Teams 24.073 pushed 08:41 · WebView2 runtime update pending reboot', status: 'done', duration: 450 },
      { t: '14:19:06', agent: 'memory', tool: 'knowledge-mcp', action: 'Past-resolution retrieval', detail: '12 similar tickets in last 24h across the fleet · root cause: WebView2 install requires reboot · runbook RB-0218', status: 'done', duration: 300 },
      { t: '14:19:07', agent: 'plan', tool: null, action: 'Draft plan · confidence 0.88', detail: 'Step 1: Clear Teams cache · Step 2: Trigger WebView2 repair via Intune · Step 3: Prompt user to reboot · Step 4: Verify launch · Step 5 (optional): Rebuild Outlook profile if secondary issue persists', status: 'done', duration: 590, model: 'Sonnet 4.6' },
      { t: '14:19:08', agent: 'endpoint', tool: 'intune-mcp', action: 'clear_app_cache(app=teams, device=NYU-WS-892)', detail: 'Cache cleared. 412 MB freed.', status: 'done', duration: 2100 },
      { t: '14:19:10', agent: 'endpoint', tool: 'intune-mcp', action: 'repair_runtime(name=webview2)', detail: 'Repair initiated. Awaiting device ack.', status: 'running', duration: null },
      { t: null, agent: 'endpoint', tool: 'comms-mcp', action: 'Prompt user to reboot', detail: 'Queued.', status: 'queued', duration: null },
      { t: null, agent: 'verify', tool: 'intune-mcp', action: 'Post-reboot app-launch verification', detail: 'Queued.', status: 'queued', duration: null },
    ],
    notes: [
      { author: 'Violet', type: 'work', body: "Matched 12 fleet-wide cases from this morning's Teams 24.073 push. WebView2 needs a reboot to finalize. Cache cleared, repair running. Will prompt Alice to reboot once repair acks, then verify.", ts: ago(3) },
    ],
    userMessages: [
      { from: 'user', body: "Teams won't launch. I click the icon and nothing happens. Also noticed my Outlook profile looks weird since this morning. Already tried restarting twice.", ts: ago(3) },
      { from: 'agent', body: "Hi Alice — I'm on it. This is a known side-effect of this morning's Teams update across a few workstations; I'm running a repair now and will ask you to reboot once in about a minute. — Violet", ts: ago(3) },
    ],
    kbas: [
      { id: 'RB-0218', title: 'Teams 24.073 WebView2 repair runbook', score: 0.96 },
      { id: 'KBA-0444', title: 'Outlook profile rebuild — when and how', score: 0.68 },
    ],
    related: [{ id: 'INC-0041290', subject: "Teams won't open", age: '12m' }, { id: 'INC-0041288', subject: 'Teams crash loop', age: '18m' }],
  },

  {
    id: 'INC-0041276',
    subject: 'Grant my resident Epic InBasket coverage access',
    user: 'rpatel',
    device: 'd-203',
    source: 'portal',
    category: 'Account & access',
    subcategory: 'EPIC entitlement',
    urgency: 'medium',
    status: 'escalated',
    disposition: 'routed-to-human',
    confidence: 0.62,
    createdAt: ago(41),
    slaDueAt: inFuture(79),
    assignedTo: 'Desktop Support · 1 PA',
    ttr: null,
    humanBaseline: '22m',
    phi: false,
    verifierModel: 'Claude Sonnet 4.6',
    plannerModel: 'Claude Sonnet 4.6',
    classifierModel: 'Claude Haiku 4.6',
    originalMessage: "Please grant Dr. Sarah Liang (my fellow) InBasket coverage for my patients starting tomorrow through next Friday. She's covering my service while I'm at a conference.",
    trace: [
      { t: '13:41:00', agent: 'ingest', tool: null, action: 'Normalized portal form', status: 'done', duration: 90 },
      { t: '13:41:01', agent: 'classify', tool: null, action: 'Intent · Category', detail: 'Intent: epic_entitlement_grant · InBasket coverage · clinical', status: 'done', duration: 280, model: 'Haiku 4.6' },
      { t: '13:41:01', agent: 'enrich', tool: 'epic-ops-mcp', action: 'Read entitlement shape', detail: 'epic-ops-mcp is READ-ONLY outside HITL. Retrieved current InBasket ACLs only.', status: 'done', duration: 340 },
      { t: '13:41:02', agent: 'plan', tool: null, action: 'Draft plan · confidence 0.62', detail: 'Candidate path requires epic-ops-mcp.grant — not in Account specialist allow-list.', status: 'done', duration: 480, model: 'Sonnet 4.6' },
      { t: '13:41:02', agent: 'gate', tool: null, action: 'Confidence gate', detail: 'Confidence 0.62 < threshold 0.85. Escalating per policy.', status: 'done', duration: 10 },
      { t: '13:41:02', agent: 'prepare', tool: null, action: 'Build handoff packet', detail: 'Triage notes · Parties · Proposed ACL diff · Suggested approver · ETA', status: 'done', duration: 420 },
      { t: '13:41:03', agent: 'escalate', tool: null, action: 'Route to Desktop Support · 1 PA', detail: 'Handoff packet delivered. Agent stepping back.', status: 'done', duration: 80 },
    ],
    notes: [
      { author: 'Violet', type: 'work', body: "Below confidence threshold (0.62) for self-service. EPIC entitlement grants require HITL; I've packaged the proposed ACL diff and a suggested approver (Dr. Kim per on-call). Next recommended step in context panel.", ts: ago(41) },
    ],
    userMessages: [
      { from: 'user', body: "Please grant Dr. Sarah Liang (my fellow) InBasket coverage for my patients starting tomorrow through next Friday. She's covering my service while I'm at a conference.", ts: ago(41) },
      { from: 'agent', body: "Hi Dr. Patel — EPIC coverage grants need a human approver. I've prepped everything and routed it to the 1 Park Ave Desktop Support lead; expected ≤60 min. — Violet", ts: ago(40) },
    ],
    kbas: [
      { id: 'POL-0019', title: 'EPIC entitlement — who can approve what', score: 0.91 },
      { id: 'RB-0312', title: 'InBasket coverage — timeboxed grants', score: 0.87 },
    ],
    related: [],
  },

  {
    id: 'INC-0041262',
    subject: 'Need Tableau Desktop installed',
    user: 'dcarr',
    device: 'd-334',
    source: 'portal',
    category: 'Endpoint',
    subcategory: 'Catalog install',
    urgency: 'low',
    status: 'auto-resolved',
    disposition: 'resolved-by-agent',
    confidence: 0.94,
    createdAt: ago(72),
    closedAt: ago(67),
    slaDueAt: ago(-40),
    ttr: '4m 52s',
    humanBaseline: '23m',
    phi: false,
    assignedTo: 'Violet',
    verifierModel: 'Claude Sonnet 4.6',
    plannerModel: 'Claude Sonnet 4.6',
    classifierModel: 'Claude Haiku 4.6',
    originalMessage: "Can I get Tableau Desktop installed on my laptop? I need it for the oncology cohort analysis we're presenting to the IRB next week. License is already approved through my grant — Laila signed off.",
    trace: [
      { t: '13:10:08', agent: 'ingest', tool: null, action: 'Normalized portal form → ticket', detail: 'Source: Service Portal · Template: software_request', status: 'done', duration: 100 },
      { t: '13:10:09', agent: 'classify', tool: null, action: 'Intent · Category · Urgency', detail: 'Intent: catalog_install (0.94) · App: Tableau Desktop · Urgency: Low', status: 'done', duration: 290, model: 'Haiku 4.6' },
      { t: '13:10:09', agent: 'enrich', tool: 'cmdb-mcp', action: 'Resolve user + device', detail: 'Daniel Carr · Oncology · NYU-LT-334 · remote · compliant', status: 'done', duration: 200 },
      { t: '13:10:10', agent: 'enrich', tool: 'catalog-mcp', action: 'Lookup Tableau entitlement + license pool', detail: 'App: Tableau Desktop 2024.1 · License: Grant-funded pool "ONC-IRB-01" · 3/5 seats used · Laila Bhatt is approver on file', status: 'done', duration: 380 },
      { t: '13:10:10', agent: 'enrich', tool: 'hr-mcp', action: 'Verify manager approval', detail: 'Laila Bhatt approved grant seat assignment to dcarr on 2026-04-18. Record matches user claim.', status: 'done', duration: 240 },
      { t: '13:10:11', agent: 'plan', tool: null, action: 'Draft plan · confidence 0.94', detail: 'Step 1: Assign license from ONC-IRB-01 pool · Step 2: Push install via Intune · Step 3: Stage starter workbooks · Step 4: Notify user · Step 5: Verify launch', status: 'done', duration: 510, model: 'Sonnet 4.6' },
      { t: '13:10:11', agent: 'catalog', tool: 'catalog-mcp', action: 'assign_license(pool=ONC-IRB-01, user=dcarr)', detail: 'Seat 4/5 assigned. License key escrowed.', status: 'done', duration: 620 },
      { t: '13:10:12', agent: 'endpoint', tool: 'intune-mcp', action: 'deploy_app(app=tableau-desktop-2024.1, device=NYU-LT-334)', detail: 'Install package queued. Device ack: accepting.', status: 'done', duration: 2800 },
      { t: '13:12:18', agent: 'endpoint', tool: 'intune-mcp', action: 'Monitor install', detail: 'Install succeeded. Exit code 0. Version 2024.1.3 installed.', status: 'done', duration: 980 },
      { t: '13:13:02', agent: 'verify', tool: 'intune-mcp', action: 'Independent verification', detail: 'Queried device app inventory with separate prompt. Tableau Desktop 2024.1.3 present. Registry keys valid.', status: 'done', duration: 480, model: 'Sonnet 4.6' },
      { t: '13:13:02', agent: 'respond', tool: 'comms-mcp', action: 'Reply in original portal thread', detail: "Template: catalog_install_success. Includes quick-start link to two starter workbooks in the oncology template library.", status: 'done', duration: 210 },
      { t: '13:15:00', agent: 'follow-up', tool: null, action: 'Monitor 7d for launch', detail: 'Launch watcher armed. If app not launched in 7d, Violet will ping with help offer.', status: 'done', duration: 10 },
    ],
    notes: [
      { author: 'Violet', type: 'work', body: 'Assigned seat 4/5 from grant pool ONC-IRB-01 (Laila Bhatt approver on record). Intune install completed in 2m 06s. User notified with starter workbook links. Closing.', ts: ago(67) },
    ],
    userMessages: [
      { from: 'user', body: "Can I get Tableau Desktop installed on my laptop? I need it for the oncology cohort analysis we're presenting to the IRB next week. License is already approved through my grant — Laila signed off.", ts: ago(72) },
      { from: 'agent', body: "Hi Daniel — done. Tableau Desktop 2024.1 is installed on NYU-LT-334 and pulled a seat from the ONC-IRB-01 grant pool (Laila was the approver on file, so we were good to go). I dropped two oncology starter workbooks into your Documents/Tableau folder. Launch it when you're ready. — Violet", ts: ago(67) },
    ],
    kbas: [
      { id: 'RB-0157', title: 'Catalog install with pre-approved grant license', score: 0.93 },
      { id: 'KBA-0831', title: 'Tableau onboarding — oncology workbook library', score: 0.78 },
    ],
    related: [{ id: 'INC-0038112', subject: 'Tableau Desktop install', age: '3mo' }],
  },

  {
    id: 'INC-0041284',
    subject: "Can't print to the 12W nurses' station printer",
    user: 'lchen',
    device: 'd-334',
    source: 'teams',
    category: 'Endpoint',
    subcategory: 'Printer mapping',
    urgency: 'medium',
    status: 'auto-resolved',
    disposition: 'resolved-by-agent',
    confidence: 0.96,
    createdAt: ago(16),
    closedAt: ago(15),
    slaDueAt: ago(-44),
    ttr: '42s',
    humanBaseline: '9m',
    phi: false,
    assignedTo: 'Violet',
    verifierModel: 'Claude Sonnet 4.6',
    plannerModel: 'Claude Sonnet 4.6',
    classifierModel: 'Claude Haiku 4.6',
    originalMessage: "The 12W nurses' station printer isn't showing up for me. I need to print wristbands. I can see other printers fine. Floated to 12W this week from 4C.",
    trace: [
      { t: '14:06:15', agent: 'ingest', tool: null, action: 'Normalized Teams webhook → ticket', detail: 'Channel: #desktop-support-1pa', status: 'done', duration: 110 },
      { t: '14:06:16', agent: 'classify', tool: null, action: 'Intent · Category · Urgency', detail: 'Intent: printer_mapping (0.96) · Urgency: Medium — clinical workflow (wristbands)', status: 'done', duration: 260, model: 'Haiku 4.6' },
      { t: '14:06:16', agent: 'enrich', tool: 'cmdb-mcp', action: 'Resolve user · device · home unit', detail: 'Lisa Chen · Pharmacy · home unit 4C · NYU-LT-334', status: 'done', duration: 190 },
      { t: '14:06:16', agent: 'enrich', tool: 'print-mcp', action: 'Enumerate printers mapped to user vs. location 12W', detail: 'User mapped to: prn-4c-01, prn-4c-02, prn-4c-wb · 12W station expects: prn-12w-wb (Zebra ZD620 wristband). Missing mapping.', status: 'done', duration: 340 },
      { t: '14:06:17', agent: 'enrich', tool: 'hr-mcp', action: 'Confirm temporary float assignment', detail: 'Active float record: 4C → 12W, 2026-04-18 through 2026-04-25. Legitimate scope for 12W printers.', status: 'done', duration: 220 },
      { t: '14:06:17', agent: 'memory', tool: 'knowledge-mcp', action: 'Past-resolution pattern', detail: 'Floated-staff printer access pattern · runbook RB-0089 matched (0.97)', status: 'done', duration: 220 },
      { t: '14:06:17', agent: 'plan', tool: null, action: 'Draft plan · confidence 0.96', detail: 'Step 1: Add prn-12w-wb to user print group (timeboxed to float end 04-25) · Step 2: Push driver via Intune · Step 3: Set as default while on 12W · Step 4: Notify user · Step 5: Verify print test', status: 'done', duration: 450, model: 'Sonnet 4.6' },
      { t: '14:06:18', agent: 'endpoint', tool: 'print-mcp', action: 'add_user_to_print_group(user=lchen, group=12W-wristband-users, expires=2026-04-25)', detail: 'Added. Time-boxed to float end.', status: 'done', duration: 280 },
      { t: '14:06:18', agent: 'endpoint', tool: 'intune-mcp', action: 'deploy_printer_driver(printer=prn-12w-wb, device=NYU-LT-334)', detail: 'Zebra ZD620 driver pushed. Port mapping confirmed.', status: 'done', duration: 680 },
      { t: '14:06:19', agent: 'verify', tool: 'print-mcp', action: 'Independent verification', detail: 'Queried user printer list with separate prompt. prn-12w-wb present, set as default.', status: 'done', duration: 420, model: 'Sonnet 4.6' },
      { t: '14:06:19', agent: 'respond', tool: 'comms-mcp', action: 'Reply in original Teams thread', detail: "Template: printer_mapping_float. Includes note about auto-removal on 04-25.", status: 'done', duration: 180 },
    ],
    notes: [
      { author: 'Violet', type: 'work', body: 'Float assignment 4C→12W confirmed in HR. Added Lisa to 12W-wristband-users print group (auto-expires 04-25 when float ends). Driver pushed, default set. Closing.', ts: ago(15) },
    ],
    userMessages: [
      { from: 'user', body: "The 12W nurses' station printer isn't showing up for me. I need to print wristbands. I can see other printers fine. Floated to 12W this week from 4C.", ts: ago(16) },
      { from: 'agent', body: "Hi Lisa — you're mapped. The 12W wristband printer (Zebra ZD620) is now your default while you're floating there. Access auto-removes on Apr 25 when your float ends; let me know if you stay longer. — Violet", ts: ago(15) },
      { from: 'user', body: "Perfect, got the test print. Thanks!", ts: ago(14) },
    ],
    kbas: [
      { id: 'RB-0089', title: 'Floated-staff printer access — timeboxed', score: 0.97 },
      { id: 'KBA-0556', title: 'Zebra ZD620 wristband driver notes', score: 0.74 },
    ],
    related: [{ id: 'INC-0040918', subject: 'Printer not showing on 8E', age: '6d' }],
  },

  {
    id: 'INC-0041302',
    subject: 'BitLocker recovery key — swapped drive',
    user: 'ktorres',
    device: 'd-661',
    source: 'phone',
    category: 'Endpoint',
    subcategory: 'BitLocker retrieval',
    urgency: 'high',
    status: 'in-progress',
    disposition: 'agent-working',
    confidence: 0.91,
    createdAt: ago(1),
    slaDueAt: inFuture(59),
    assignedTo: 'Violet',
    ttr: null,
    humanBaseline: '14m',
    phi: false,
    verifierModel: 'Claude Sonnet 4.6',
    plannerModel: 'Claude Sonnet 4.6',
    classifierModel: 'Claude Haiku 4.6',
    originalMessage: "Help line transcript — 14:21 — Kevin Torres, Facilities. 'I swapped the SSD on my laptop this morning per the hardware team's instructions and now it's asking for a BitLocker recovery key. I don't have it. Can you look it up?'",
    trace: [
      { t: '14:21:04', agent: 'ingest', tool: null, action: 'Normalized phone transcript → ticket', detail: 'Source: PHONE via Genesys · Transcribed by phone-mcp', status: 'done', duration: 140 },
      { t: '14:21:05', agent: 'classify', tool: null, action: 'Intent · Category · Urgency', detail: 'Intent: bitlocker_recovery_key_retrieval (0.91) · Urgency: High — device unbootable', status: 'done', duration: 310, model: 'Haiku 4.6' },
      { t: '14:21:05', agent: 'enrich', tool: 'cmdb-mcp', action: 'Resolve user + device', detail: 'Kevin Torres · Facilities · NYU-LT-661 · Dell Latitude 7440', status: 'done', duration: 190 },
      { t: '14:21:06', agent: 'enrich', tool: 'cmdb-mcp', action: 'Check recent change records on device', detail: 'CHG-0019442 opened by hardware team 09:14 — "SSD swap per refresh program". Legitimate change ticket matches user claim.', status: 'done', duration: 280 },
      { t: '14:21:06', agent: 'enrich', tool: 'intune-mcp', action: 'Check device encryption escrow', detail: 'BitLocker recovery key ESCROWED to Intune on 2025-09-03. Key material present.', status: 'done', duration: 360 },
      { t: '14:21:06', agent: 'memory', tool: 'knowledge-mcp', action: 'Past-resolution retrieval', detail: 'Runbook RB-0127 matched (0.94) · "Post-hardware-swap BitLocker retrieval"', status: 'done', duration: 240 },
      { t: '14:21:07', agent: 'plan', tool: null, action: 'Draft plan · confidence 0.91', detail: 'Step 1: Verify caller identity via voice-bound MFA challenge · Step 2: Retrieve escrowed key · Step 3: Deliver via one-time-view channel · Step 4: Monitor boot success · Step 5: Rotate key post-boot', status: 'done', duration: 520, model: 'Sonnet 4.6' },
      { t: '14:21:08', agent: 'gate', tool: null, action: 'Sensitive-data gate — identity required', detail: 'BitLocker key release is sensitive. Voice-bound MFA (DUO push + callback) required before key surfaces. Not HITL — policy allows agent to release IF MFA passes.', status: 'done', duration: 30 },
      { t: '14:21:08', agent: 'account', tool: 'mfa-mcp', action: 'trigger_voice_bound_mfa(upn=ktorres)', detail: 'DUO push + callback challenge sent. Awaiting confirmation.', status: 'done', duration: 180 },
      { t: '14:21:31', agent: 'account', tool: 'mfa-mcp', action: 'MFA result', detail: 'DUO push ACCEPTED · Callback answered · identity confirmed.', status: 'done', duration: 22800 },
      { t: '14:21:32', agent: 'endpoint', tool: 'intune-mcp', action: 'retrieve_bitlocker_key(device=NYU-LT-661)', detail: 'Key retrieved. NEVER logged to trace — surfaced only to caller via one-time-view link.', status: 'running', duration: null },
      { t: null, agent: 'endpoint', tool: 'comms-mcp', action: 'Deliver key via one-time-view SMS', detail: 'Queued — pending retrieval ack.', status: 'queued', duration: null },
      { t: null, agent: 'verify', tool: 'intune-mcp', action: 'Monitor device boot success', detail: 'Queued.', status: 'queued', duration: null },
      { t: null, agent: 'endpoint', tool: 'intune-mcp', action: 'Rotate BitLocker key post-boot', detail: 'Queued — runs automatically 5 min after successful boot.', status: 'queued', duration: null },
    ],
    notes: [
      { author: 'Violet', type: 'work', body: 'Change ticket CHG-0019442 corroborates SSD swap story. Voice-bound MFA passed. Retrieving key now. Key material NEVER written to ticket trace — delivered only via one-time-view SMS link. Will rotate 5 min after successful boot.', ts: ago(1) },
    ],
    userMessages: [
      { from: 'user', body: "(phone) I swapped the SSD on my laptop this morning per hardware team instructions and now it's asking for a BitLocker recovery key. Can you look it up?", ts: ago(1) },
      { from: 'agent', body: "Hi Kevin — your identity is confirmed via DUO. I'm sending the recovery key to your mobile now as a one-time-view link; open it, type the 48-digit key at the BitLocker prompt, and you should boot normally. I'll rotate the key automatically once you're back up. — Violet", ts: ago(1) },
    ],
    kbas: [
      { id: 'RB-0127', title: 'Post-hardware-swap BitLocker retrieval', score: 0.94 },
      { id: 'POL-0011', title: 'Sensitive-data release — voice-bound MFA required', score: 0.92 },
      { id: 'KBA-0712', title: 'BitLocker recovery key escrow', score: 0.83 },
    ],
    related: [{ id: 'INC-0040774', subject: 'BitLocker after mobo swap', age: '19d' }, { id: 'CHG-0019442', subject: 'SSD swap · Facilities refresh', age: '5h' }],
  },

  {
    id: 'INC-0041275',
    subject: 'VPN prompts for MFA in a loop',
    user: 'dcarr',
    device: 'd-334',
    source: 'email',
    category: 'Connectivity',
    subcategory: 'VPN re-enrollment',
    urgency: 'medium',
    status: 'hitl-review',
    disposition: 'awaiting-human',
    confidence: 0.74,
    createdAt: ago(28),
    slaDueAt: inFuture(92),
    assignedTo: 'HITL queue',
    ttr: null,
    humanBaseline: '19m',
    phi: false,
    verifierModel: 'Claude Sonnet 4.6',
    plannerModel: 'Claude Sonnet 4.6',
    classifierModel: 'Claude Haiku 4.6',
    originalMessage: "VPN keeps prompting me for MFA in a loop. I approve the push, it connects for maybe 10 seconds, drops, and asks again. Been happening since last night. I'm remote (oncology) and can't get to Epic to do my cohort updates. Tried restarting, reinstalled the VPN client once.",
    trace: [
      { t: '13:54:00', agent: 'ingest', tool: null, action: 'Normalized email → ticket', detail: 'Source: EMAIL · helpdesk@nyulangone.org', status: 'done', duration: 110 },
      { t: '13:54:01', agent: 'classify', tool: null, action: 'Intent · Category · Urgency', detail: 'Intent: vpn_mfa_loop (0.82) · Urgency: Medium · remote clinical-adjacent user', status: 'done', duration: 290, model: 'Haiku 4.6' },
      { t: '13:54:01', agent: 'enrich', tool: 'cmdb-mcp', action: 'Resolve user + device', detail: 'Daniel Carr · Oncology · NYU-LT-334 · remote', status: 'done', duration: 200 },
      { t: '13:54:02', agent: 'enrich', tool: 'intune-mcp', action: 'Device compliance + VPN client version', detail: 'Compliant · Cisco AnyConnect 5.1.2.42 · certificate valid through 2026-09', status: 'done', duration: 380 },
      { t: '13:54:02', agent: 'enrich', tool: 'netflow-mcp', action: 'Recent VPN session pattern', detail: '14 session attempts in last 2h · median connect 9.8s · all terminated by IKE re-key · pattern consistent with GPO-pushed session timeout regression', status: 'done', duration: 540 },
      { t: '13:54:03', agent: 'memory', tool: 'knowledge-mcp', action: 'Past-resolution retrieval', detail: '2 similar tickets in last 48h (remote users). Suspected cause: GPO "VPN-IKE-Timeout" changed by change ticket CHG-0019301 on 2026-04-19 22:04. No runbook exists yet.', status: 'done', duration: 420 },
      { t: '13:54:04', agent: 'plan', tool: null, action: 'Candidate plans · confidence 0.74', detail: 'Plan A: Re-enroll device VPN profile (benign, may not fix) · Plan B: Roll back CHG-0019301 GPO (fleet-wide, out of scope) · Plan C: Apply user-scoped GPO exception (novel, no runbook)', status: 'done', duration: 680, model: 'Sonnet 4.6' },
      { t: '13:54:05', agent: 'gate', tool: null, action: 'Confidence gate', detail: 'Confidence 0.74 < threshold 0.85. Ambiguous between benign re-enrollment and fleet-wide rollback. Escalating to HITL review for disposition choice.', status: 'done', duration: 20 },
      { t: '13:54:05', agent: 'prepare', tool: null, action: 'Build HITL packet', detail: 'Triage · 3 candidate plans with tradeoffs · evidence pack (netflow trace + CHG-0019301 diff) · 2 related tickets flagged as likely same root cause · suggested approver: Network Ops', status: 'done', duration: 460 },
      { t: '13:54:06', agent: 'escalate', tool: null, action: 'Queue to HITL review', detail: 'Assigned to HITL queue · Network-on-call surfaced · SLA 2h', status: 'done', duration: 80 },
      { t: '14:22:00', agent: 'wait', tool: null, action: 'Awaiting HITL decision', detail: 'Reviewer can: (a) approve Plan A, (b) escalate to Network Ops for GPO rollback, (c) request more data. 1h 32m SLA remaining.', status: 'running', duration: null },
    ],
    notes: [
      { author: 'Violet', type: 'work', body: 'Pattern suggests CHG-0019301 GPO regression, not user-specific. Re-enrolling Daniel (Plan A) would get him online but leaves the fleet broken. Two other remote users have the same symptom in the last 48h — listed in related. Recommend HITL decide between user-scoped fix vs. rolling the GPO back.', ts: ago(28) },
    ],
    userMessages: [
      { from: 'user', body: "VPN keeps prompting me for MFA in a loop. I approve the push, it connects for maybe 10 seconds, drops, and asks again. Been happening since last night. I'm remote (oncology) and can't get to Epic to do my cohort updates. Tried restarting, reinstalled the VPN client once.", ts: ago(28) },
      { from: 'agent', body: "Hi Daniel — this looks like a fleet-level regression rather than anything on your laptop, so I'm routing it to a Network lead who can decide between patching you individually and rolling back the change. Expected within 2h. I'll update this thread as soon as there's a decision. — Violet", ts: ago(27) },
    ],
    kbas: [
      { id: 'POL-0007', title: 'GPO rollback authority — Network Ops', score: 0.88 },
      { id: 'KBA-0492', title: 'Cisco AnyConnect IKE re-key troubleshooting', score: 0.81 },
    ],
    related: [{ id: 'INC-0041244', subject: 'VPN drops every 10s', age: '42m' }, { id: 'INC-0041218', subject: 'AnyConnect MFA loop from home', age: '1h' }, { id: 'CHG-0019301', subject: 'GPO: VPN-IKE-Timeout update', age: '16h' }],
  },
];

// Ops metrics time-series
const OPS_METRICS = {
  coverage: { now: 0.912, target: 0.90, delta7d: +0.018, delta30d: +0.041 },
  resolution_narrow: { now: 0.993, target: 0.99, delta7d: +0.002, delta30d: +0.007 },
  resolution_broad: { now: 0.962, target: 0.95, delta7d: +0.004, delta30d: +0.011 },
  speed_median_s: { agent: 87, human: 684, multiplier: 7.9 },
  volume24h: 847,
  hitl_queue: 11,
  reopens72h: 0.022,
  csat: 4.7,
  cost_per_ticket: { agent: 0.018, human: 14.22 },
};

// Hourly volume (last 24h)
const HOURLY_VOLUME = [28, 19, 14, 8, 6, 9, 22, 48, 72, 61, 54, 58, 67, 71, 54, 48, 44, 52, 47, 39, 31, 26, 22, 47];

// Category breakdown
const BY_CATEGORY = [
  { label: 'Account & access', count: 287, auto: 0.97, res: 0.996 },
  { label: 'Endpoint', count: 241, auto: 0.89, res: 0.974 },
  { label: 'Connectivity', count: 96, auto: 0.81, res: 0.947 },
  { label: 'Device', count: 58, auto: 0.72, res: 0.955 },
  { label: 'Info requests', count: 165, auto: 0.98, res: 0.999 },
];

// Why the agent escalated — top reasons (the fix-it list)
const ESCALATION_REASONS = [
  { reason: 'EPIC entitlement grant requires HITL', count: 19, trend: '+4' },
  { reason: 'Destructive action — Intune wipe', count: 12, trend: '+1' },
  { reason: 'Confidence below 0.85 — ambiguous intent', count: 9, trend: '−3' },
  { reason: 'Missing runbook — new app catalog entry', count: 7, trend: '+7' },
  { reason: 'VPN loop — suspected GPO regression', count: 6, trend: '+2' },
  { reason: 'Shared-mailbox owner unclear', count: 4, trend: '0' },
  { reason: 'Clinical-app certificate push — policy gate', count: 3, trend: '−1' },
];

// KBA sources
const TOP_KBAS_USED = [
  { id: 'RB-0042', title: 'AD account unlock — post-absence pattern', used: 84 },
  { id: 'RB-0218', title: 'Teams 24.073 WebView2 repair', used: 71 },
  { id: 'RB-0101', title: 'Lost/stolen device — 5-step remediation', used: 12 },
  { id: 'KBA-1109', title: 'When to require fresh MFA before unlock', used: 58 },
];

Object.assign(window, { USERS, DEVICES, TICKETS, OPS_METRICS, HOURLY_VOLUME, BY_CATEGORY, ESCALATION_REASONS, TOP_KBAS_USED });
