---
path: /incidents
surface: admin
domain: safety
auth: signed-in (admin) + scope:admin:workspace:incident
source: apps/oshun/admin/src/app/incidents/page.tsx
status: drafted
last_walked: '—'
---

# Safety · Incidents and reliability

## Purpose

Declare, coordinate, mitigate, postmortem, and close incidents across
reliability, safety, and compliance domains. `operatorPromise`: "On-call has one
operator cockpit that escalates, tracks, and resolves incidents without losing
timeline context."

## Entry points

- Sidebar item **"Incidents"** (AdminSidebar — safety group)
- Inbox → incidents handoff (`inbox → incidents` per
  `OSHUN_ADMIN_WORKSPACE_RELATIONSHIPS`) — "Operator opens an incident from the
  unified inbox."

## Layout regions

Inside `AdminShell`:

- `<WorkspaceEntryPoint workspaceId="incidents" ...>`
- When `detail.accessible`, four panels — each receives the same
  `snapshot.incidentDetails`:
  - `<IncidentDetailPanel incidentDetails>` — incident detail (the selected /
    active incident's full view)
  - `<IncidentActionsPanel incidentDetails>` — coordination actions (declare,
    mitigate, escalate, close)
  - `<IncidentImpactCommsPanel incidentDetails>` — impact assessment
    - comms drafting
  - `<IncidentRunbookPostmortemPanel incidentDetails>` — runbook references +
    postmortem authoring

`snapshot` is built by `extractIncidentDetailSnapshot(detail.result.value)`.

## States

- [ ] Anonymous → middleware redirect to
      `/unauthorized?reason=missing-session&returnTo=/incidents`
- [ ] Signed-in (admin) without `admin:*`, `admin:studio`, or
      `admin:workspace:incident` → `WorkspaceEntryPoint` "Access not granted";
      the four panels hidden
- [ ] Scope ok + BFF ok → all four panels render
- [ ] Scope ok + BFF `workspace-unavailable` → entry-point "Workspace data
      unavailable"; panels hidden
- [ ] `snapshot.incidentDetails` empty → each panel renders its own empty state
      (handled per component)
- [ ] Note `bffWorkspaceId: 'incident'` (singular) — IA id is `incidents`; the
      BFF endpoint is `/v1/admin/workspaces/incident`

## Interactions

Top-level interactive elements live inside each child panel:

- [ ] **IncidentDetailPanel** — current incident header / timeline / severity
- [ ] **IncidentActionsPanel** — declare / mitigate / escalate / close actions
- [ ] **IncidentImpactCommsPanel** — impact tiles + comms drafting surface
      (likely with templated copy)
- [ ] **IncidentRunbookPostmortemPanel** — runbook navigation + postmortem
      editor

The page itself exposes no buttons / inputs.

## Data & contracts

- **Reads**: `loadWorkspaceDetail('incidents', session)` →
  `/v1/admin/workspaces/incident` (BFF id is singular); snapshot via
  `extractIncidentDetailSnapshot(detail.result.value)` provides
  `incidentDetails`
- **Writes**: per panel (declare / mitigate / postmortem author); endpoints
  owned by each component
- **Realtime**: _None at page level._ Incident workflows are expected to be
  real-time-heavy but the page renders a static snapshot per nav
- **Auth/role check**: middleware + page
  (`canEnterAdminWorkspace(scopes, 'incidents')` → required scopes
  `['admin:*', 'admin:studio', 'admin:workspace:incident']`)

## Cross-references

- Shell: `shell/01-app-shell.md`, `shell/04-workspace-pattern.md`
- Workspace definition: `libs/oshun/navigation/src/admin-ia.ts` (`incidents` —
  `kind: 'investigation'`, `operatorRelationship: 'respond'`,
  `bffWorkspaceId: 'incident'`)
- Handoff origin (`from → incidents`): `../governance/inbox.md`
- Handoff destinations (`incidents → …`): `../governance/policy.md`,
  `../operations/analytics.md`
- Library: `apps/oshun/admin/src/lib/incident-detail.ts`
- Component sources: `IncidentDetailPanel.tsx`, `IncidentActionsPanel.tsx`,
  `IncidentImpactCommsPanel.tsx`, `IncidentRunbookPostmortemPanel.tsx`

## Open questions / known gaps

- [ ] Confirm `bffWorkspaceId` mismatch (`incidents` vs `incident`) is
      intentional — pattern shows up in several workspaces
- [ ] Four panels share `snapshot.incidentDetails` — document whether they
      coordinate state via a provider or each operates on a copy
- [ ] Realtime requirement for incident timelines is implicit in the domain;
      verify whether the page is expected to add a subscription beyond per-nav
      SSR refresh
