# Journey: Admin incident handling

`/incidents` is a real, action-capable Admin Cockpit workspace. It loads one BFF
snapshot and renders incident detail, guarded mitigation/postmortem actions,
blast-radius and customer-impact editors, communications, runbook launch,
postmortem transitions, and closure. The unified inbox is a separate composed
triage surface; this journey does not claim an unproved automatic ingestion or
request-id join between them.

| Incident control                            | Admin surface                            |
| ------------------------------------------- | ---------------------------------------- |
| Read status, impact, timeline, tasks, comms | Incident detail                          |
| Mark mitigated / publish postmortem         | Typed-confirmation action panel          |
| Blast radius / customer impact              | Impact and communications panel          |
| Draft / publish / rescind comms             | Impact and communications panel          |
| Launch runbook / advance postmortem         | Runbook and postmortem panel             |
| Resolve / cancel incident                   | Runbook and postmortem panel             |
| Acknowledge / assign queue items            | Separate inbox or operator incident APIs |

## Personas

- **Incident operator** — has the incident workspace scope and performs
  mitigations, impact updates, communications, runbook, and closure actions.
- **Communications approver** — supplies approval identity when a seeded
  communication requires sign-off.
- **Postmortem author/reviewer** — schedules, drafts, reviews, and publishes the
  incident record.
- **Read-only or out-of-scope admin** — can enter the shell but does not receive
  the four incident panels.

## Pre-conditions

- An admin session exists; otherwise `/incidents` redirects to the unauthorized
  route with a return target.
- `loadWorkspaceDetail('incidents', session)` can read the BFF-backed workspace.
- The session has the incident action scope for the interactive panels.
- The seeded workspace includes open and resolved incidents spanning severity,
  communications, runbook, and postmortem states.
- Actions run sequentially against the current incident snapshot; the browser
  reloads or refreshes after mutations where required.

## Steps

### 1. Open the incident cockpit

- [x] The server page loads workspace detail and operator view, then renders
      `WorkspaceEntryPoint`.
- [x] An accessible workspace renders four panels: `IncidentDetailPanel`,
      `IncidentActionsPanel`, `IncidentImpactCommsPanel`, and
      `IncidentRunbookPostmortemPanel`.
- [x] Detail cards expose id, title, severity, status, impact scope, affected
      services/workspaces, update cadence, timeline, mitigation tasks,
      communications, and postmortem/action-item state.
- [x] Header counts summarize open incidents, severity, comms, overdue updates
      and postmortems, and action items.

### 2. Use the guarded primary actions

- [x] Each eligible incident offers **Mitigate…** and **Close postmortem…**.
- [x] The modal requires the incident id verbatim before Confirm becomes
      available.
- [x] Escape or Cancel closes the modal without a request.
- [x] Mitigate posts to `/api/admin/incidents/:id/mitigate` and records the
      mitigation in the incident timeline.
- [x] Close postmortem posts to the postmortem publish route and becomes
      unavailable after publication.
- [ ] This panel does not expose Acknowledge, Assign to me, or Escalate. Those
      actions belong to separate inbox/operator incident contracts.

### 3. Maintain blast radius and customer impact

- [x] The impact panel edits scope, affected workspaces, affected services, and
      rationale through the blast-radius route.
- [x] Client and server validation reject a short rationale.
- [x] The customer-impact editor records affected users and requests, error and
      traffic-loss percentages, revenue estimate, and summary.
- [x] Successful updates are visible in the incident detail and appear as
      distinct timeline evidence.

### 4. Draft, approve, publish, and rescind communications

- [x] The panel lists communication audience, channel, state, content, approval
      requirement, author, publisher, and approver.
- [x] An operator can draft a new update and publish it through its state
      transition.
- [x] Approval-required communication refuses publication until an approver is
      supplied.
- [x] A published update can be rescinded only with a valid rationale.
- [x] The focused lifecycle covers draft → publish and published → rescinded.
- [ ] This proves incident communication records, not delivery to every external
      status-page or notification adapter.

### 5. Launch a runbook

- [x] An open incident can launch a runbook and receive a new in-progress task.
- [x] A resolved incident returns 409 rather than creating work.
- [x] Runbook activity is reflected in the snapshot counts and timeline.
- [ ] The UI records operator workflow state; it does not automatically verify
      that an off-system remediation succeeded.

### 6. Advance the postmortem

- [x] The panel enforces the explicit state machine:
      `not_scheduled → scheduled → drafted → in_review → published`.
- [x] Forms collect the fields required by the selected transition, including
      author, document reference, root cause, contributing factors, lessons, or
      waiver reason where applicable.
- [x] Invalid and already-published transitions surface named errors.
- [x] The orchestration spec proves scheduled and drafted state stamps in the
      audit timeline.

### 7. Resolve or cancel the incident

- [x] Closure supports `resolved` and `cancelled` outcomes with the required
      rationale/data.
- [x] Sev0/sev1 resolution is blocked until at least a scheduled postmortem
      exists.
- [x] A sev1 incident with a scheduled postmortem resolves successfully.
- [x] A cancelled incident records its rationale.
- [x] Resolved cards hide mutation forms that no longer apply.

### 8. Use the unified inbox as a separate entry surface

- [x] `/inbox` composes rows from incident and other workspaces, supports
      workspace/SLA filters and sorting, and links each row to a relative
      workspace detail route.
- [x] Its inline drawer, URL-hash round trip, selection toolbar, and bulk
      acknowledge behavior are independently tested.
- [ ] The current evidence does not prove which live detector created a seeded
      incident, that inbox and incident mutations share one `x-request-id`, or
      that closing an incident automatically removes an inbox row.

## Post-conditions

- Incident detail, impact, communications, runbook, postmortem, and closure
  state are represented in the refreshed workspace snapshot.
- High-severity incidents cannot close without the required postmortem
  scheduling gate.
- Approval-required communication cannot publish without an approver.
- Mutations expose their resulting audit/timeline entries in the incident model.
- Acknowledge/assign behavior, external communication delivery, global audit
  export, and automatic inbox ingestion are not implied by this cockpit.

## Failure modes

- **Missing session** — the page redirects before workspace data renders.
- **Missing incident scope** — interactive incident panels are absent.
- **Workspace unavailable** — `WorkspaceEntryPoint` renders the backend error
  rather than stale action controls.
- **Wrong confirmation token** — destructive action Confirm remains disabled.
- **Short rationale or invalid impact values** — client/server validation
  rejects the mutation.
- **Approver missing** — approval-required comms stay unpublished.
- **Resolved incident runbook launch** — BFF returns 409.
- **Invalid postmortem transition** — no state advance occurs.
- **High-severity premature closure** — Sev0/Sev1 resolution returns the
  scheduled-postmortem gate error.
- **Stale concurrent view** — the next write may be rejected by current state;
  the UI has no general optimistic-concurrency version documented here.
- **External delivery inferred** — a published communication record is not proof
  that every external channel delivered it.

## E2E coverage

- [apps/oshun/admin/e2e/redesign-incident-signoff.spec.ts](../../apps/oshun/admin/e2e/redesign-incident-signoff.spec.ts)
  covers guarded mitigate/postmortem actions and modal safety.
- [apps/oshun/admin/e2e/incident-impact-comms-flows.spec.ts](../../apps/oshun/admin/e2e/incident-impact-comms-flows.spec.ts)
  covers blast radius, impact, draft/publish/rescind, and approver gates.
- [apps/oshun/admin/e2e/incident-runbook-postmortem-flows.spec.ts](../../apps/oshun/admin/e2e/incident-runbook-postmortem-flows.spec.ts)
  covers runbook, postmortem, resolve/cancel, severity gates, and access scope.
- [apps/oshun/admin/e2e/incident-orchestration-flows.spec.ts](../../apps/oshun/admin/e2e/incident-orchestration-flows.spec.ts)
  composes communication, runbook, closure, impact, and timeline assertions.
- [apps/oshun/admin/e2e/unified-inbox-flows.spec.ts](../../apps/oshun/admin/e2e/unified-inbox-flows.spec.ts),
  [apps/oshun/admin/e2e/inbox-bulk-action-flows.spec.ts](../../apps/oshun/admin/e2e/inbox-bulk-action-flows.spec.ts),
  and
  [apps/oshun/admin/e2e/redesign-inbox-signoff.spec.ts](../../apps/oshun/admin/e2e/redesign-inbox-signoff.spec.ts)
  cover the adjacent inbox as its own composed surface.

Coverage is **deep for the dedicated incident cockpit**. It does not prove live
detector ingestion, cross-surface request-id correlation, external delivery,
automatic inbox cleanup, or the separate operator acknowledge/assign store.

## Per-view files touched by this journey

- [workspaces/safety/incidents.md](../workspaces/safety/incidents.md) —
  dedicated incident panels and states.
- [workspaces/governance/inbox.md](../workspaces/governance/inbox.md) — adjacent
  triage entry and bulk acknowledge.
- [shell/04-workspace-pattern.md](../shell/04-workspace-pattern.md) — workspace
  access and error shell.

## Cross-references

- [privileged-handoff.md](./privileged-handoff.md) — admin session entry and
  scope handoff.
- [../../WALKTHROUGH/journeys/incident-triage.md](../../WALKTHROUGH/journeys/incident-triage.md)
  — separate operator incident surface.
- `apps/oshun/admin/src/app/incidents/page.tsx` — server composition.
- `apps/oshun/admin/src/components/IncidentDetailPanel.tsx` — read model and
  timeline.
- `apps/oshun/admin/src/components/IncidentActionsPanel.tsx` —
  typed-confirmation actions.
- `apps/oshun/admin/src/components/IncidentImpactCommsPanel.tsx` — impact and
  communications.
- `apps/oshun/admin/src/components/IncidentRunbookPostmortemPanel.tsx` —
  runbook, postmortem, and closure.

## Open questions

- [ ] Which production detectors create the incident records composed here?
- [ ] How should inbox item lifecycle track incident resolution?
- [ ] Which idempotency or version token protects concurrent operator writes?
- [ ] Which communication channels expose authoritative delivery receipts?
- [ ] Should acknowledge, assign, and escalation be brought into this dedicated
      cockpit or remain separate operator/inbox actions?
- [ ] Which audit explorer owns cross-incident export and correlation?
