# Human Review & Approval Queue — Detailed Roadmap (2026-04-17)

> **Supersedes:** `platform_HUMAN_REVIEW_APPROVAL_QUEUE_ROADMAP.md` (scaffold).
> **Status:** Planned — critical safety rail for autonomous agents.
> **Primary surfaces:** `services/platform-service/src/modules/reviews/`, new `modules/approvals/`, new `modules/escalations/`, `dashboards/admin-web/`.
> **Estimated effort:** 2–3 weeks (1 engineer).
> **Priority:** **P1** — gates every write-capable agent action to avoid blast radius incidents.

---

## 1. Current State (as of 2026-04-17)

| Surface                            | State                                                                                                 | Evidence                                        |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| `platform-service/modules/reviews` | Module exists: `notifications.ts`, `repository`, `routes`, `types` — partial implementation           | 6 files in `reviews/`                           |
| MFA push-approval                  | Narrow auth flow only                                                                                 | `auth` module                                   |
| Cowork destructive-action guard    | `CoworkPermissionPrompter` emits `approval-required` Tauri event; resolves in-process                 | `crates/cowork-orchestrator/src/permissions.rs` |
| A2A pipeline pause-for-review      | Not implemented                                                                                       | —                                               |
| Product backend approval flows     | Ad-hoc per product (JarvisJr, NomGap have custom)                                                     | grep confirms duplication                       |
| Notifications                      | `notifications` module + delivery channels (Slack stub, email via Mailpit, push via `@bytelyst/push`) | `notifications/`                                |

**Net:** `reviews` module has skeleton but isn't the **generic human-in-the-loop system**. Every approval currently shipped is bespoke.

---

## 2. Success Criteria (V1)

1. Any agent run can emit `waiting_for_review` with a `reviewReason` and a decision contract; a reviewer's decision resumes or cancels the run.
2. Cowork destructive actions (file delete, shell `rm`, commit push) route through the platform reviews module when `remote_approval_enabled=true` — otherwise keep local prompter.
3. Reviewers see one inbox across products; can bulk-claim, add comments, and make decisions via admin UI or API.
4. SLA timers: unclaimed reviews escalate at T1, auto-reject at T2 (configurable per risk level).
5. Full audit trail: every decision captured with reviewer identity, timestamp, reason, supporting evidence pointers.
6. One real product backend (JarvisJr or NomGap) removes its custom approval flow in favor of this.

---

## 3. Non-Goals (V1)

- Full BPM suite or arbitrary approval-chain designer
- End-user case portals (reviewer-only UX in V1)
- Risk-score auto-decisions (deferred to V2 with policy engine)
- Legal-hold / eDiscovery extensions

---

## 4. Dependencies

- **Hard:** Durable Event Bus (C1) — for review events and notification fan-out
- **Hard:** Agent Runtime Orchestration (C3) — for `waiting_for_review` state integration
- **Soft:** Org & Workspace RBAC scaffolded roadmap — for reviewer assignment by role

---

## 5. Data Model

New Cosmos containers (PK in **bold**):

| Container            | PK            | Purpose                                                                                 |
| -------------------- | ------------- | --------------------------------------------------------------------------------------- |
| `reviews`            | **productId** | `ReviewDoc`: subjectType, subjectId, riskLevel, requiredDecision, assignees, state, sla |
| `review-decisions`   | **reviewId**  | `DecisionDoc`: decision, reviewerId, comment, decidedAt, attachments                    |
| `review-escalations` | **reviewId**  | `EscalationDoc`: level, triggeredAt, reassignedTo, reason                               |

Subject types: `agent_run_step`, `external_action`, `content_publication`, `prompt_change`, `low_confidence_output`, `tool_invocation`, `custom` (with `subjectPayload` JSON).

States: `pending → claimed → (approved | rejected | expired | superseded)`.

Risk levels: `low | medium | high | critical` → dictates SLA (24h / 8h / 2h / 30m default).

---

## 6. Phase Plan

### Phase 1 — Generic Review Object (week 1)

- [ ] **1.1** Extend `reviews/types.ts`: `ReviewDoc`, `DecisionDoc`, `EscalationDoc` zod schemas
- [ ] **1.2** Repository: `createReview`, `getReview`, `listReviews`, `claimReview`, `submitDecision`, `expireReview`, `reassign`
- [ ] **1.3** REST surface:
  - [ ] `POST /api/reviews` (service-to-service)
  - [ ] `GET /api/reviews/:id`
  - [ ] `GET /api/reviews` (filters: product, workspace, state, reviewer, risk, age)
  - [ ] `POST /api/reviews/:id/claim`
  - [ ] `POST /api/reviews/:id/decide { decision, comment }`
  - [ ] `POST /api/reviews/:id/reassign { reviewerIds }`
- [ ] **1.4** Reviewer authz: `canReview(productId, workspaceId, userId, riskLevel)` helper (reuse `@bytelyst/org-client`)
- [ ] **1.5** 20+ route tests covering ACL edges (cross-product, cross-workspace, expired claim)

**Exit:** create a review via curl → claim → decide → state machine enforced.

---

### Phase 2 — Workflow & Escalation (week 2)

- [ ] **2.1** SLA engine: background worker (on Durable Event Bus) scans pending reviews; escalates at T1, expires at T2
- [ ] **2.2** Emit events: `review.created`, `review.claimed`, `review.decided`, `review.escalated`, `review.expired`
- [ ] **2.3** Agent Runtime integration:
  - Agent run step can call `requestReview(subject, risk)` → step state `waiting_for_review` → run state `waiting_for_review`
  - `review.decided` event signals run; `approved` → continue, `rejected`/`expired` → fail step
- [ ] **2.4** Escalation policies: per-product JSON config in `reviews/policies.ts` (default + product overrides)
- [ ] **2.5** Supersession: if a new review for same subject arrives, the old one auto-`superseded` with audit link

**Exit:** integration test: agent run requests review → 5s later auto-escalates → reviewer decides → run resumes.

---

### Phase 3 — Reviewer Delivery + UI (week 2–3)

- [ ] **3.1** Notification fan-out on `review.created` + `review.escalated`:
  - Email via Mailpit / production SMTP
  - Slack channel webhook (reuse `notifications`)
  - Push via `@bytelyst/push` to assigned reviewer's devices
  - Telegram (optional adapter)
- [ ] **3.2** Admin UI `dashboards/admin-web/app/ops/reviews/`:
  - Queue view with filters
  - Bulk-claim
  - Decision form with evidence pane (renders `subjectPayload`)
  - Timeline per review (events + escalations + decision)
- [ ] **3.3** Reviewer mobile hook: `@bytelyst/react-native-platform-sdk` exposes `useReviewInbox()`
- [ ] **3.4** Keyboard shortcuts for reviewers: `j/k` navigate, `a` approve, `r` reject, `c` comment, `e` escalate

**Exit:** reviewer completes 20 real reviews end-to-end with <30s median decision time on low-risk items.

---

### Phase 4 — Cowork + First Product Migration (week 3)

- [ ] **4.1** Cowork integration:
  - New flag `remote_approval_enabled` on cowork-service
  - When true, `CoworkPermissionPrompter` calls `platform-service POST /api/reviews` instead of emitting local Tauri event
  - Polls / subscribes for decision; resumes tool call on approval
- [ ] **4.2** Rust-side adapter in `crates/cowork-orchestrator/src/permissions.rs` with HTTP fallback when platform unreachable → local prompt
- [ ] **4.3** Migrate one product backend (recommend JarvisJr) off custom approval flow:
  - Identify all `needsApproval`/`pendingConfirm` sites
  - Replace with `platformClient.reviews.create()`
  - Delete product-local approval tables after 30-day sunset
- [ ] **4.4** Document migration playbook for remaining products

**Exit:** JarvisJr custom approval code deleted; all approvals in admin queue.

---

## 7. Tech Stack Decision

| Option                                                                   | V1?    | Rationale                                      |
| ------------------------------------------------------------------------ | ------ | ---------------------------------------------- |
| **Platform module + Durable Event Bus + existing notification channels** | ✅ Yes | Aligned with repo; zero new infra              |
| External ticketing (Jira / Linear)                                       | No     | Control-plane fit poor; audit trail fragmented |
| Dedicated BPM (Camunda, Flowable)                                        | No     | Overkill; heavyweight                          |
| Policy engine (OpenFGA / Cedar)                                          | Later  | Add once policy-as-code becomes a need         |

---

## 8. Risks & Mitigations

| Risk                                   | Mitigation                                                                                                  |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| Review queue becomes dead-letter inbox | Mandatory SLA; auto-expire + escalate; dashboard surfaces queue age                                         |
| Inconsistent policy across products    | Single `reviews/policies.ts` module; per-product overrides validated in CI                                  |
| Reviewer fatigue                       | Risk-based routing: low-risk items batch-decide; ship bulk-claim UI on day 1                                |
| Unaudited decisions                    | Every decision doc encrypted via `@bytelyst/field-encrypt` for `comment` field; reviewer identity immutable |
| Cowork offline → blocks the agent      | HTTP timeout 5s → fall back to local `CoworkPermissionPrompter`; decision reconciled on next reconnect      |

---

## 9. Acceptance Checklist

- [ ] Phase 1 — generic review object + REST complete
- [ ] Phase 2 — SLA engine + agent-run integration live
- [ ] Phase 3 — admin UI + notifications across Slack/email/push
- [ ] Phase 4 — cowork remote-approval flag + 1 product migration shipped
- [ ] 30-day sunset plan documented for remaining product-local approval code
- [ ] `docs/ECOSYSTEM_ARCHITECTURE.md` + AGENTS.md updated
- [ ] Roadmap moved to `docs/roadmaps/completed/`
