# Journey: Review decision cycle (admin app)

The Admin review cockpit has a deeply tested queue → detail → human decision
flow. Standard approval or rejection makes a review terminal; request-changes
does not. Delegation and escalation are separate non-terminal mutations, while
high-risk approval first stages a dual-confirmation record. The AI copilot can
prefill or record feedback but cannot move the stage machine. Author-side
package creation and downstream publication are outside the proved cycle.

| Control                                    | Can change review stage? | Proven behavior                                                         |
| ------------------------------------------ | ------------------------ | ----------------------------------------------------------------------- |
| Human decision actions                     | Yes                      | Approve/reject terminal; changes requested non-terminal                 |
| High-risk approval                         | Only after confirmation  | Initial approve returns 202 and stages pending confirmation             |
| Delegation / escalation                    | No terminal decision     | Records handoff or escalation in stage/history state                    |
| Copilot match / accept / override / ignore | No                       | Prefill or feedback only; human decision remains required               |
| Keyboard triage                            | Calls decision endpoint  | Navigation is announcement-only and response failures are not inspected |

## Personas

- **Review operator** — has the review workspace scope and owns the final human
  decision.
- **Delegating reviewer** — assigns the package to another seeded reviewer with
  a rationale.
- **Escalating reviewer** — raises a non-terminal SLA, policy, legal, safety, or
  evidence concern.
- **High-risk confirmer** — supplies the pending approval token under the BFF
  dual-confirmation rules.
- **AI copilot** — supplies disclosed, non-binding fixture evidence and
  rationale suggestions.

## Pre-conditions

- A valid admin session can enter `/review`.
- `loadWorkspaceDetail('review', session)` returns the seeded queue, detail
  records, stage history, audit events, suggestions, saved views, and related
  entities.
- The author-side submission that created the seeded package is not part of this
  journey.
- Focused browser runs use unique operator ids so one test's per-operator review
  mutations do not contaminate another.

## Steps

```mermaid
flowchart LR
    A[Review queue] --> B[Review detail]
    B --> C{Human action}
    C -->|request changes| B
    C -->|delegate or escalate| B
    C -->|approve/reject standard| D[Terminal review]
    C -->|approve high risk| E[Pending dual confirmation]
    E -->|cancel| B
    E -->|valid confirm| D
    F[AI suggestion] -->|prefill or feedback only| B
```

### 1. Enter the review queue

- [x] `/review` renders `ReviewPackageList`, `ReviewSavedViewsSurface`, and
      `KeyboardTriageReviewPanel` after the workspace entry point.
- [x] Seeded package rows link to `/review/:reviewId`.
- [x] The browser flow follows a high-priority row into the correct detail.
- [x] Saved-view and keyboard panels are present as auxiliary queue controls.
- [ ] The tests do not prove an upstream author submission or a live queue push.

### 2. Bound keyboard triage honestly

- [x] The component advertises `j/k` or arrows, `a` approve, `x` reject, `c`
      changes, `gg/G` jump, and `?` help.
- [x] Selection changes and action announcements are covered at the component
      layer.
- [ ] **Open selected** currently announces the review id but does not navigate.
- [ ] Its decision callback sends a request but does not inspect `response.ok`;
      a rejected server response can still be announced as submitted.
- [ ] There is no focused Playwright journey proving keyboard navigation and
      mutation against the real Admin route.

### 3. Inspect the detail workspace

- [x] The detail page selects the review id from the shared workspace snapshot
      and renders an honest not-found notice for an unknown id.
- [x] It composes package evidence, sticky action rail, consolidated audit
      timeline, templates, blockers, copilot, human decision actions,
      delegation, stage graph/history, audit log, related links/comments, and
      investigation bundle export.
- [x] The action rail remains sticky on the long desktop detail.
- [x] The consolidated timeline carries typed event-kind and severity
      attributes.
- [ ] Rendering an auxiliary template, comment, or export panel is not evidence
      that it participates in the final decision transaction.

### 4. Use the disclosed copilot without delegating authority

- [x] The panel labels the content **AI suggestion**, exposes generator,
      version, evidence, risk, confidence, rationale, and model disclosure.
- [x] **Match suggestion** only prefills the human decision form.
- [x] Accept, override with a 20-character rationale, and ignore record copilot
      feedback and visible audit evidence.
- [x] Escalate/defer suggestions hide decision-matching controls when there is
      no human-decision counterpart.
- [x] Feedback is idempotency-guarded after resolution.
- [x] Copilot actions never create decision or stage-transition events and
      cannot stage high-risk approval.
- [ ] The page displays a seeded suggestion; it does not invoke
      `evaluateAssistantInvocationGuard` or generate a new suggestion in this
      interaction.

### 5. Record a standard human decision

- [x] **Approve** may be submitted without a note.
- [x] **Reject** and **Request changes** require a rationale of at least ten
      characters; the character counter follows the textarea.
- [x] Approve or reject records decision and stage/audit history, locks decision
      and delegation controls, and remains locked after reload.
- [x] Request changes records history, clears the form, and remains
      non-terminal.
- [x] Human-final provenance remains structurally distinct from AI suggestion
      provenance.

### 6. Delegate or escalate instead

- [x] Delegation requires both a target reviewer and a ten-character rationale.
- [x] A valid delegation records a delegated stage-history entry.
- [x] Escalation requires a reason and rationale, then surfaces the
      already-escalated state and disables another escalation.
- [x] A seeded escalated review remains eligible for a later human decision.
- [ ] The focused flow does not prove that another operator's queue immediately
      receives or can reject the delegated package.

### 7. Stage a high-risk approval

- [x] Approving a seeded `release_gate` returns 202 and creates a pending
      dual-confirmation panel rather than a terminal decision.
- [x] The panel exposes its confirmation token plus Confirm and Cancel actions.
- [x] Cancelling removes the pending record and leaves the review non-terminal.
- [x] Contract tests cover the second-reviewer rule; BFF route tests cover
      confirmation after cooldown.
- [ ] Playwright does not complete the confirm-after-cooldown or second-reviewer
      path because of the per-operator test-state and deterministic clock
      boundaries documented in the spec.

### 8. Move through the queue

- [x] **Approve next** navigates to the next ordered review id.
- [x] The last item renders a disabled **Queue end** state.
- [ ] This shortcut advances navigation; it does not itself approve the current
      package.
- [ ] A terminal decision is not proven to publish a persona, model, media
      artifact, or customer-facing change.

## Post-conditions

- A standard approve/reject is visibly terminal and persists across refresh.
- Request changes, delegation, escalation, and a cancelled high-risk approval
  remain non-terminal with their own history evidence.
- Copilot feedback remains non-authoritative and separately attributed.
- High-risk approval cannot be described as complete while only the pending
  panel has been staged.
- Package creation, delegated-queue delivery, global audit export, and
  downstream publication remain outside this proved cycle.

## Failure modes

- **Missing session or review scope** — the protected workspace cannot expose
  review actions.
- **Unknown review id** — the shell remains but displays an honest not-found
  notice.
- **Short decision rationale** — reject/request-changes is blocked client-side.
- **Terminal re-entry** — decision and delegation controls remain locked after
  reload.
- **Short delegation/escalation rationale** — no mutation is sent.
- **Already escalated** — the escalation fieldset is disabled.
- **Copilot authority confusion** — match or feedback does not decide the
  review.
- **High-risk false terminal** — a 202 pending approval is not a final approval.
- **Keyboard false success** — the current callback does not validate the HTTP
  response before announcing completion.
- **Concurrent stale view** — per-state transition rules may reject the next
  write; no general optimistic UI merge is documented here.
- **Downstream inference** — a review decision is not proof of customer
  publication or removal.

## E2E coverage

- [apps/oshun/admin/e2e/review-decision-flows.spec.ts](../../apps/oshun/admin/e2e/review-decision-flows.spec.ts)
  covers queue/detail navigation, rationale gates, standard decisions,
  delegation, escalation, reload locking, and unknown ids.
- [apps/oshun/admin/e2e/high-risk-approval-flows.spec.ts](../../apps/oshun/admin/e2e/high-risk-approval-flows.spec.ts)
  covers pending dual confirmation, controls, cancellation, and non-terminal
  state.
- [apps/oshun/admin/e2e/redesign-review-detail-signoff.spec.ts](../../apps/oshun/admin/e2e/redesign-review-detail-signoff.spec.ts)
  covers sticky actions, consolidated audit timeline, Approve-next navigation,
  and queue end.
- [apps/oshun/admin/e2e/copilot-suggestion-flows.spec.ts](../../apps/oshun/admin/e2e/copilot-suggestion-flows.spec.ts),
  [apps/oshun/admin/e2e/copilot-feedback-override.spec.ts](../../apps/oshun/admin/e2e/copilot-feedback-override.spec.ts),
  and
  [apps/oshun/admin/e2e/copilot-audit-invariants.spec.ts](../../apps/oshun/admin/e2e/copilot-audit-invariants.spec.ts)
  prove disclosure, prefill/feedback, override rationale, and the
  no-stage-change invariant.
- [apps/oshun/admin/e2e/provenance-distinctions.spec.ts](../../apps/oshun/admin/e2e/provenance-distinctions.spec.ts)
  distinguishes AI suggestion, human review, and human-final provenance.
- [apps/oshun/admin/src/**tests**/KeyboardTriageReviewSurface.test.tsx](../../apps/oshun/admin/src/__tests__/KeyboardTriageReviewSurface.test.tsx)
  covers the keyboard surface at component level.

Coverage is **deep for standard decisions and copilot invariants, partial for
high-risk completion, and component-only for keyboard triage**.

## Per-view files touched by this journey

- [workspaces/governance/review.md](../workspaces/governance/review.md) — queue,
  saved views, and keyboard triage.
- [workspaces/governance/review-id.md](../workspaces/governance/review-id.md) —
  package evidence, decisions, delegation, high risk, copilot, stages, audit,
  and related entities.
- [shell/04-workspace-pattern.md](../shell/04-workspace-pattern.md) — session,
  scope, and backend entry behavior.

## Cross-references

- [privileged-handoff.md](./privileged-handoff.md) — admin session entry.
- [persona-release-cycle.md](./persona-release-cycle.md) — separate persona
  evidence and lifecycle lanes; no automatic review submission is claimed.
- [../../WALKTHROUGH/journeys/editorial-review-approval.md](../../WALKTHROUGH/journeys/editorial-review-approval.md)
  — customer/PWA-side editorial context.
- `apps/oshun/admin/src/app/review/page.tsx` and
  `apps/oshun/admin/src/app/review/[reviewId]/page.tsx` — server composition.
- `apps/oshun/admin/src/components/ReviewDecisionCopilot.tsx` — explicit
  non-authority boundary.

## Open questions

- [ ] Which authoring endpoint creates the review packages rendered here?
- [ ] Should keyboard **Open selected** navigate, and should every keyboard
      mutation inspect and announce the server result?
- [ ] How is a delegated package projected into the target operator's queue?
- [ ] Which browser strategy can prove high-risk confirmation after cooldown and
      across reviewers?
- [ ] Which version or idempotency token governs concurrent decision writes?
- [ ] Which downstream service consumes a terminal decision and proves
      publication, rejection, or removal?
- [ ] Which export surface owns a cross-review, authoritative audit bundle?
