Skip to main content

h.work Platform — User Operations Manual

Platform: h.work (Humanity Protocol internal AI + Expert managed-service platform)
Last updated: 2026-06-26 (additions: AM cross-client rollups — Experts / SLA / Billing — §6.7, #1300; Gmail API + DWD email channel shipped #1722; Tavus integration DB/security/API series #2052/#2054/#2055; clarified /ops/personas/* route retention) Source references: frontend/src/contexts/AuthContext.tsx, all page.tsx and layout.tsx under /client/*, /workspace/*, /ops/*, e2e/ specs, CLAUDE.md, ADR-007, ADR-018, ADR-024 through ADR-028.

What changed this quarter

If you're returning to this manual after a few weeks away, these are the operator-visible shifts you need to internalize. Each links to the section that covers it.

AreaWhat changedWhere to read
RAG runtimeRAGflow retired; Haystack 2.x + Hayhooks + pgvector + OpenRouter is the new stack. Per-env cost ~$2k → $440. No RAGflow operations remain.§9: ADR-024, ADR-025, ADR-026
Billing railOrb retired; Lago self-hosted is canonical. Dev on Railway; staging + prod on AWS. /ops/billing is the platform-wide view (AM + SuperAdmin since PR #1155).§7.3 /ops/billing
AM cross-client rollupsAMs get portfolio-wide rollups across their assigned clients: Experts (/ops/experts), SLA breaches (/ops/sla), Billing (/ops/billing). Per-AM org scoping via AmOrgScopeGuard; SuperAdmin sees all orgs. Shipped #1300 (closes #1244).§6.7 + docs/features/am-rollups.md
Agent runtimerailway_per_org runtime kind retired; supported kinds are shared_railway (default) and ecs_per_org (premium). ECS prod cutover #701 closed 2026-06-15 — staging+prod are canonically AWS ECS Fargate.§9: ADR-028, ADR-038
Schema migrationsTypeORM-only. Raw SQL under api/src/database/migrations/ is CI-blocked. Set RUN_MIGRATIONS_ON_BOOT=true for deploy-time migrations.§9: ADR-027
Expert workspace productivityCustomer history timeline and KB search panel landed inside /workspace/queue (2026-06-03). Response templates were trialled in the same cluster and removed on 2026-06-05 — the agent draft is the primary surface; see §5.3 Productivity primitives.§5.3 Productivity primitives
Expert application + Tavus interviews/ops/expert-applications gained a Tavus video-interview track: send-to-interview, retry-invite, hard-delete, post-interview Approve. Recordings mirrored to R2 with 7-year retention.§7.3 /ops/expert-applications
Specialist emailGmail API inbound polling + DWD-impersonated outbound shipped 2026-06-05 (PR #1722). ONE Google Workspace service account with domain-wide delegation impersonates each Specialist's mailbox (bob@h.work); no per-Specialist OAuth tokens. Cloudflare Worker stays as fallback during a 2-week prod soak (#1440/#1441 still open). Resend is reserved for invites/onboarding/transactional.docs/features/channels.md
Tavus integrationTavus DB schema (tavus_personas + video_calls) landed via #2052; security guardrails via #2054; on-demand video call API via #2055. The Persona Manager API module was renamed to Tavus integration (PR #1345, 2026-06-02); the frontend /ops/personas/* routes were deliberately retained (rename PRs closed without merge).§7.3 /ops/personas/* + docs/decisions/tavus/

If a procedure in this manual contradicts the changes above, the table above wins — and please file a doc-correction issue with type:feature, area:backend, role:pm so the procedure gets updated.


Table of Contents

  1. Platform Overview & Terminology
  2. Authentication & JWT Model
  3. Role: org_admin — Client Organisation Administrator
  4. Role: org_member — Client Organisation Member
  5. Role: expert — Humanity Protocol Expert
  6. Role: account_manager — Account Manager (AM)
  7. Role: superadmin — SuperAdmin
  8. Cross-Role Reference: Route Ownership
  9. ADR Cross-References

1. Platform Overview & Terminology

h.work is not a helpdesk. It is a managed AI + Expert service layer used internally by Humanity Protocol (HP) staff to deliver responses to client companies.

ConceptCorrect termNever say
AI persona assigned to a clientSpecialistagent, bot, assistant
HP human reviewerExpertspecialist (for humans)
The company using the platformclient (UI) / org (code)workspace, account, tenant
HP person managing clientsAM / Account Manageraccount rep
Platform-wide administratorSuperAdminadmin (too ambiguous)

Request flow summary:

  1. A client employee sends a message to their assigned Specialist persona.
  2. The AI agent drafts a reply (confidence + risk scored).
  3. If confidence < threshold or risk_level >= HIGH → an ExpertQueueItem is created.
  4. An Expert reviews, edits, and sends the reply as the Specialist.
  5. Default threshold is 101 — meaning all replies go to Expert review unless an AM explicitly lowers it.

2. Authentication & JWT Model

Login URL: /login
Token storage: localStorage key hw_token (JWT, persisted until explicit logout)
Session model: No client-side expiry. The server validates the token on every API call. Logout is always explicit.

Role detection (AuthContext.tsxgetRoleRedirect())

platformRole = JWT payload.platformRole ?? payload.role ?? orgMemberships[0].orgRole
platformRolePost-login redirect
superadmin/ops/clients
account_manager/ops/clients
expert/workspace/queue
org_admin, org_member, owner, admin, member, billing/client/chat

Multi-tab sync: A StorageEvent listener on hw_token keeps all open tabs in sync — logging in or out from one tab propagates immediately.

Logout: Disconnects the WebSocket, clears the token, and redirects to /login.


3. Role: org_admin — Client Organisation Administrator

3.1 Login + Redirect Target

  • Login page: /login
  • Post-login redirect: /client/chat
  • JWT field: orgMemberships[0].orgRole = "admin" (or "owner")

3.2 Route Table

RouteDescriptionAccessible to org_admin?
/client/chatMain chat interface with Specialist
/client/chat?id=<convId>Direct link to a specific conversation
/client/chat/:idServer-side 307 redirect → /client/chat?id=:id✅ (redirect only)
/client/approvalsRuntime approval & input requests from Specialist
/client/specialistSpecialist profile/info page
/client/settings/profileEdit display name, avatar, email notification prefs
/client/settings/teamManage team members and invites
/client/settings/channelsConnect/manage communication channels✅ (admin-only access)
/client/settings/billingView plan, usage, billing history✅ (admin/owner/billing)
/client/settings/billing/upgradeUpgrade plan flow
/client/settings/billing/upgrade/successUpgrade success confirmation
/client/settings/whatsappWhatsApp-specific settings
/client/admin/knowledge-baseUpload & manage KB documents for the Specialist
/client/admin/channels/newAdd a new channel integration
/client/admin/channels/[id]Manage a specific channel integration
/client/admin/integrationsRedirects → channels
/client/admin/integrations/newRedirects → channels/new
/client/admin/integrations/[id]Redirects → channels/[id]
/client/admin/teamRedirects → /client/settings/team
/client/admin/billingRedirects → /client/settings/billing
/client/admin/analyticsRedirects → /client/admin/billing
/client/admin/ticketsTicket view (legacy redirect path)
/client/specialists/[id]/onboardingSpecialist onboarding wizard
/client/specialists/[id]/meetingsSpecialist meeting management
/client/specialists/[id]/meetings/[meetingId]Specific meeting detail
/client/reconsentRe-consent page (banner-triggered)
/client/pageRoot /client page (redirect to /client/chat)

3.3 Per-Page Operations

/client/chat

  • Displays: Full-width two-panel chat interface. Left: thread list with conversation subjects and timestamps. Right: selected conversation thread with message history.
  • Actions:
    • Start new conversation (send first message to Specialist)
    • Type and send a message in the compose area
    • Switch between existing conversations by clicking thread rows
    • Navigate to /client/approvals via page link
  • Forms: Message compose text area + Send button
  • Role gates: None within the chat itself — all authenticated org members see the same surface

/client/approvals

  • Displays: List of runtime approval and input requests from the Specialist that require a client response.
  • Actions:
    • Review pending requests
    • Submit required approval or input (nothing executes until the request is resolved)
    • "Back to chat" button → navigates to /client/chat
  • Forms: Per-request approval/input submission forms
  • Note: Nothing is sent or executed on your behalf until the required approval or input is submitted.

/client/admin/knowledge-base

  • Displays: Document table with columns for filename, parse status (pending / parsed / failed), chunk count, upload date. Live WebSocket updates on parse status.
  • Actions:
    • Search bar (KbSearchBar) — full-text search across uploaded KB documents
    • Upload area (KbUploadArea) — drag-and-drop or file-picker upload (up to 50 docs per page, paginated)
    • Filter by parse status — All / Pending / Parsed / Failed
    • Open document detail modal — click a row to open KbDocumentDetailModal
    • Delete document — from within the detail modal
    • Pagination< / > controls (50 docs per page)
  • Forms: File upload form, search input

/client/settings/profile

  • Displays: Two-column card layout: Profile card + Email Notifications card.
  • Actions:
    • Upload or change avatar photo (camera icon click → AvatarUpload widget)
    • Edit Display name text field
    • Email field (read-only — cannot change email here)
    • Save changes button — saves display name and avatar URL
    • Email notification toggles (auto-save on toggle):
      • New reply from Specialist
      • Conversation resolved
      • Team member added
      • Invoice generated

/client/settings/team

  • Displays: Member table (Name + Email, Role badge, Last active, Actions column). Pending invites section below.
  • Actions (org_admin / owner only):
    • Invite member button → opens inline form with email + role selector (member / admin / billing)
    • Change role dropdown per member (cannot demote if only 1 admin/owner total)
    • Remove member (confirmation dialog) — cannot undo
    • Revoke invite (confirmation dialog)
    • Resend invite button per pending invite
    • Transfer Ownership button → modal to select a new owner (current user becomes admin)
    • Leave workspace button (for non-owner members)
  • Forms: Invite form (email + role), Transfer Ownership modal
  • Guards: Cannot demote the last admin or owner. Cannot remove yourself if owner.

/client/settings/channels

  • Displays: Channel grid (Email, WhatsApp, Telegram, Slack, Microsoft Teams, WeChat). Each card shows:
    • Channel icon and name
    • Status badge: Connected / Available / Coming Soon
    • Connected details (e.g., number of WhatsApp numbers linked, "Default — always on" for Email)
    • Test result (if tested)
  • Actions per card:
    • Set up → expands inline explainer or navigates to setup flow
    • Manage → navigates to /client/admin/channels/[id]
    • Test → sends a test ping and shows pass/fail result
    • Remove → confirmation dialog; stops messages on that channel (history preserved)
    • WhatsApp Manage → expands WhatsAppPairingPanel inline
  • Email routing section (below channel grid):
    • Add domains or specific email addresses to the routing whitelist (type → domain/email → Add)
    • Remove existing whitelist entries (× button)
    • Until a domain is added, only invited team member emails reach the Specialist

/client/settings/billing

  • Displays: Current plan badge (free / trial / starter / pro / enterprise), trial countdown if applicable, usage bars (conversations used vs. limit, messages used vs. limit), billing history chart (bar chart, monthly), plan details.
  • Actions:
    • Upgrade button → navigates to /client/settings/billing/upgrade
    • View billing history

3.4 Navigation Structure

The client area uses two separate side-navigation contexts depending on which sub-area is active:

Settings layout sidebar (/client/settings/*):

  • ← Back to Chat link
  • Settings heading
  • Section 1 (always visible): Profile · Team
  • Section 2 (admin/owner/billing only): Channels · Billing
  • Footer: Sign Out button + dark mode toggle

Admin layout sidebar (/client/admin/*):

  • ← Chat back link
  • Org name + "Admin" label
  • Team (→ /client/admin/team) — redirects to Settings/Team
  • Channels (→ /client/admin/channels)
  • Knowledge Base (→ /client/admin/knowledge-base)
  • Billing (→ /client/admin/billing) — redirects to Settings/Billing
  • Footer: Log out button

Main chat area (/client/chat):

  • The chat surface itself contains navigation to Approvals, Settings, and Admin via context menus/links embedded in the PortalChat component.

3.5 Permission Boundaries

org_admin cannot:

  • Access /workspace/* routes (Expert workspace) — redirected to /client/chat
  • Access /ops/* routes (Account Manager / SuperAdmin ops) — redirected to root
  • Create or edit Specialists — Specialist configuration is HP-side only
  • View other organisations' data (org-scoped RLS enforced at API layer)
  • Hard-delete the organisation (production-gated)
  • Access the queue of pending Expert review items
  • See Expert assignment details (which Expert is reviewing their conversations)

3.6 Golden-Path Flow: Upload a KB Document & Verify It Parsed

  1. Log in → land on /client/chat
  2. Navigate to AdminKnowledge Base (or go directly to /client/admin/knowledge-base)
  3. Drag-and-drop a PDF or click the upload area to select a file
  4. Watch the parse status badge update in real-time via WebSocket (kb.document.parsed event)
  5. Once status shows Parsed, click the row to open the detail modal and verify chunk count
  6. The Specialist will now reference this document in future conversations

4. Role: org_member — Client Organisation Member

4.1 Login + Redirect Target

  • Login page: /login
  • Post-login redirect: /client/chat
  • JWT field: orgMemberships[0].orgRole = "member"

4.2 Route Table

org_member has the same route access as org_admin with two exceptions — the admin-gated sub-sections of Settings are hidden in the nav but may be reachable by direct URL until the server-side guard fires.

RouteAccessible to org_member?
/client/chat
/client/approvals
/client/specialist
/client/settings/profile
/client/settings/team✅ (read-only view; no invite/remove/role-change)
/client/settings/channels❌ hidden in nav (admin/owner only)
/client/settings/billing❌ hidden in nav (admin/owner/billing only)
/client/admin/knowledge-base❌ redirected away
/client/admin/* (setup/team/billing)❌ redirected to /client/chat
/client/specialists/*
/workspace/*❌ redirected to /client/chat
/ops/*❌ redirected

4.3 Per-Page Operations

/client/chat — same as org_admin

/client/settings/team (member view)

  • Displays: Same member table but without the Actions column.
  • No actions available: Cannot invite, remove, change roles, or transfer ownership.
  • Pending invite count is shown but invites cannot be managed.

/client/settings/profile — identical to org_admin

/client/approvals — identical to org_admin

4.4 Navigation Structure

Settings layout sidebar (/client/settings/*):

  • ← Back to Chat link
  • Section 1 (always): Profile · Team
  • Section 2 (channels/billing): Not shown — these nav items are hidden based on orgRole
  • Footer: Sign Out + dark mode toggle

The admin sidebar (/client/admin/*) is not reachable — the admin/layout.tsx guard redirects non-admin roles back to /client/chat.

4.5 Permission Boundaries

org_member cannot:

  • Invite or remove team members
  • Change anyone's role (including their own)
  • Transfer workspace ownership
  • Access Channels settings (cannot connect/manage integrations)
  • Access Billing (cannot view plan details or upgrade)
  • Access the Knowledge Base admin page
  • Access any Admin section (/client/admin/*)
  • Access Expert workspace or Ops surfaces

4.6 Golden-Path Flow: Send a Message to the Specialist

  1. Log in → land on /client/chat
  2. If no active thread, type in the compose box and press Enter (or click Send)
  3. The AI agent drafts a reply — since the default threshold is 101, an Expert always reviews it before it appears
  4. The Expert sends the reply as the Specialist — the member sees it appear in the thread
  5. To approve a runtime request from the Specialist, navigate to /client/approvals via the chat UI

5. Role: expert — Humanity Protocol Expert

5.1 Login + Redirect Target

  • Login page: /login
  • Post-login redirect: /workspace/queue
  • JWT field: platformRole = "expert"

5.2 Route Table

RouteDescription
/workspace/queueMain queue — all Expert-review-pending conversations
/workspace/queue/[id]Individual ticket detail (full-screen, direct URL or mobile deep-link)
/workspace/tasksAgentic task review — approve/reject plan steps
/workspace/approvalsRuntime approval gates assigned to the Expert
/workspace/analyticsQueue performance + AI confidence metrics for the Expert's scope
/workspace/settingsExpert profile settings (name, avatar, title, bio, phone)
/workspace/poolsExpert pools (legacy page — pools removed 2026-05-03; page may be a stub)

5.3 Per-Page Operations

/workspace/queue (primary working surface)

  • Displays: Two-panel layout — thread list (left) + ticket detail (right). On mobile: single-panel with tab toggle (List / Detail).
  • Thread list features:
    • Status tabs: All · Pending · Awaiting Client · Resolved · Snoozed
    • Risk filter pills: All / Critical / High / Medium / Low
    • Assignee filter: All / Mine / Unassigned
    • Client filter dropdown (multi-client Experts only — "All Clients" or specific client)
    • Each row shows: customer name, relative time, message preview (2-line clamp), risk badge, confidence bar, assignee pill (You / Expert name / Unassigned), channel badge (email only)
    • Real-time updates via Socket.io; 8s polling fallback
    • Pending count badge on the sidebar Queue icon (updates every 10s when not on queue page)
  • Ticket detail panel (TicketDetail):
    • Full conversation thread display
    • AI-drafted reply with editable text area
    • Send button — sends the reply as the Specialist and marks the queue item resolved
    • Edit draft — modify the AI draft before sending
    • Assign to me button (if unassigned)
    • Snooze — snoozes the ticket
    • Resolve without reply — closes the ticket without sending
    • Escalate / flag options
    • Risk level indicator, confidence score, channel badge
    • Conversation history (all prior messages)
  • Keyboard shortcuts: ? opens the shortcuts modal; j/k navigate items; Enter opens detail; s sends

/workspace/queue/[id] (direct ticket URL)

  • Full-screen ticket detail with a ← Back to Queue header bar
  • Same operations as the detail panel in /workspace/queue
  • Used for mobile direct links and bookmark targets

/workspace/tasks (agentic task review)

  • Displays: List of active agentic tasks (Hermes-runtime tasks). Each task card shows:
    • Task ID (truncated), status pill, creation time, associated conversation ID
    • Progress bar + step-dot timeline (N steps, each with status dot)
    • Each step: step number, risk pill, action type, description, parameters JSON, result (expandable)
  • Actions per task step (when requires_approval + status = "pending_approval"):
    • Approve button — approves the step and allows execution to continue
    • Reject button — rejects the step
    • Optional feedback text area before rejecting
  • View result toggle per completed step (expands JSON result)
  • Refresh button to reload task list

/workspace/approvals

  • Displays: Runtime approval and input requests assigned to the Expert (Expert-targeted, not client-targeted).
  • Title: "Runtime approvals"
  • Actions: Review and resolve pending Expert-targeted approval gates
  • Note: Client approvals stay on the client surface (/client/approvals) unless Ops resolves them

/workspace/analytics

  • Displays: Analytics dashboard for the Expert's scoped queue.
  • Period selector: 7d / 30d / 90d toggle
  • Stat cards: Total conversations, resolved, pending, avg. resolution time
  • Queue status bars: Pending vs. Resolved horizontal bar comparison
  • Top request types: Horizontal bar list of most common request types
  • AI confidence distribution: Low / Med / High column chart + percentage score
  • Response latency: Avg ms and P95 ms
  • Bar chart: Daily conversation volume over the selected period

/workspace/settings

  • Displays: Expert profile form.
  • Fields: Full name, Display name, Email (read-only), Title/Role, Bio (textarea), Phone
  • Actions:
    • Upload avatar (camera icon on avatar widget → AvatarUpload)
    • Save changes button
    • Appearance toggle: Light / Dark mode
    • Sign out button (LogOut icon)

Productivity primitives inside /workspace/queue (shipped 2026-06-03)

A cluster of workspace-productivity features shipped together on 2026-06-03 to compress per-ticket Expert review time. They appear inside the /workspace/queue ticket detail panel rather than as separate routes.

  • Customer history timeline — Side panel that surfaces the customer's prior conversations within the same Org × Specialist scope, rendered alongside the active ticket. Read-only — clicking a prior thread opens it in a new tab. PRs: #1530, #1533.
  • KB search panel — Org-scoped Haystack search with citation insertion. The Expert searches the team's documented answers; clicking a result inserts a citation block into the editable draft. Backed by ADR-024 (Haystack/Hayhooks) + ADR-025 (pgvector) + ADR-026 (OpenRouter).

Removed 2026-06-05 — response templates. A third primitive (Org-scoped reusable reply snippets with {{var}} interpolation, PRs #1532/#1535/#1536/#1618) was deprecated and removed end-to-end the day after it landed in dev. The agent already generates a draft for every queue item and learns from Expert corrections over time; a parallel template system created two competing draft sources and a UX surface to keep in sync with model improvements. Issue #1518 closed as not-planned. See docs/features/expert-workspace.mdDeprecated for the removal note.

See also docs/features/expert-workspace.md for the full feature treatment including future-state plans.

Notifications drawer (client portal, not Expert): A dedicated notifications drawer also shipped 2026-06-03 (#1474, #1549) but lives in /client/*, not /workspace/*. The same notification primitive will plug into the Expert workspace in a follow-up; for now the Expert sees pending work only via the queue-list pending-count badge.

5.4 Navigation Structure

Workspace sidebar layout (collapsible icon-rail):

  • Header: h.work logo (links to /workspace/queue); collapse/expand trigger
  • Nav items:
    • Queue (Inbox icon) — with live pending-count badge (red pill in expanded mode, red dot in collapsed)
    • To review (ListChecks icon) → /workspace/tasks
    • Approvals (ClipboardCheck icon) → /workspace/approvals
    • Analytics (LineChart icon) → /workspace/analytics
  • Footer: Avatar + name + "Expert" role label → /workspace/settings; Settings icon; Dark/light mode toggle; Keyboard shortcuts (?)

5.5 Permission Boundaries

expert cannot:

  • Access /client/* routes — no layout guard enforces this; any authenticated user can navigate directly to /client/* routes (redirect on login is via getRoleRedirect() only, not a persistent layout guard)
  • Access /ops/* routes — the Ops layout redirects non-AM/non-superadmin to /
  • View conversations outside their expert_access grants (ADR-007: dual-scope — per-Specialist or per-Org)
  • Create, edit, or delete Specialists (SuperAdmin only)
  • Create or manage client organisations
  • Access the Ops queue (/ops/queue) — that is the SuperAdmin-only queue view
  • See other Experts' queue items (scoped by expert_access)
  • Access /workspace/pools as a functional feature (pools removed 2026-05-03; stub page only)

ADR-007 Expert access scopes:

  • scope='specialist': Expert sees only conversations for a specific (Org × Specialist) pair
  • scope='org': Expert sees all conversations for the entire Org
  • Both are managed by an AM or SuperAdmin via the client detail page's Experts tab (SuperAdmin only)

5.6 Golden-Path Flow: Review and Send a Draft Reply

  1. Log in → land on /workspace/queue
  2. Pending-count badge shows the number of items awaiting review
  3. Click the Pending tab to filter to items needing action
  4. Click a ticket row to open the detail panel (or use j/k + Enter keyboard shortcuts)
  5. Read the client's message and the AI-drafted reply
  6. Edit the draft if needed (risk or accuracy issues)
  7. Click Send — the reply is sent as the Specialist, the queue item moves to Resolved
  8. Next item auto-focuses (or press j to advance)

6. Role: account_manager — Account Manager (AM)

6.1 Login + Redirect Target

  • Login page: /login
  • Post-login redirect: /ops/clients
  • JWT field: platformRole = "account_manager"getRoleRedirect() in AuthContext.tsx only redirects this exact value to /ops/clients; a token with "am" will redirect to /client/chat on login. However, ops/layout.tsx treats "am" as equivalent to "account_manager" for Ops portal access (isAm = platformRole === "account_manager" || platformRole === "am"), so an "am" token that manually navigates to /ops/* will function as a full AM.

6.2 Route Table

account_manager has access to a subset of the /ops/* routes. Routes marked saOnly in the sidebar are blocked — the Ops layout redirects AMs away from those paths to /ops/clients.

RouteAM access?Notes
/ops/clientsAM sees only their assigned clients
/ops/clients/[id]Client detail (tabs: Overview, Conversations, Specialists, Team, Tools — no Experts/Integrations/Audit/Agreements tabs)
/ops/clients/newCreate a new client org (onboarding wizard)
/ops/clients/[id]/setup/step-1Setup step 1: basic org info
/ops/clients/[id]/setup/step-2Setup step 2: Specialist assignment
/ops/clients/[id]/setup/step-3Setup step 3: Expert assignment / review
/ops/clients/[id]/setup/step-4Setup step 4: send client invite
/ops/clients/[id]/editEdit client org details
/ops/clients/[id]/specialists/[assignmentId]/editEdit Specialist assignment config
/ops/clients/[id]/specialists/[assignmentId]/kbManage KB for a Specialist assignment
/ops/inboxAM conversation inbox (cross-client thread view)
/ops/agent-runsRuntime agent run monitor
/ops/agent-runs/[id]Specific agent run detail
/ops/approvalsPlatform-wide approval requests
/ops/settingsAM profile settings
/ops/queue❌ SuperAdmin onlyRedirected to /ops/clients
/ops/experts✅ Accessible (AM + SuperAdmin since #1300, closes #1244)Cross-client Expert↔org rollup, scoped to the AM's portfolio. See §6.7.
/ops/sla✅ Accessible (AM + SuperAdmin since #1300)Cross-client SLA-breach rollup. Role-gated page reached by direct URL (not currently in the sidebar). See §6.7.
/ops/specialists❌ SuperAdmin onlyRedirected to /ops/clients
/ops/team❌ SuperAdmin onlyRedirected to /ops/clients
/ops/users❌ SuperAdmin onlyRedirected to /ops/clients
/ops/leads❌ SuperAdmin onlyRedirected to /ops/clients
/ops/expert-applications❌ SuperAdmin onlyRedirected to /ops/clients
/ops/analytics❌ SuperAdmin onlyRedirected to /ops/clients (platform-wide analytics; distinct from the AM cross-client rollups in §6.7)
/ops/billing✅ Accessible (AM + SuperAdmin since #1155 (#1165 was closed-unmerged and superseded by #1155))Lago billing overview
/ops/health❌ SuperAdmin onlyRedirected to /ops/clients
/ops/personas/*❌ SuperAdmin onlySpecialist persona / Tavus integration management (function-calls, replicas, templates). The planned rename to /ops/tavus/* via #1031 was closed without merge; the /ops/personas/* prefix was deliberately retained. AM users land on /ops/clients.
/ops/pools❌ SuperAdmin onlyRedirected to /ops/clients

6.3 Per-Page Operations

/ops/clients (AM view)

  • Displays: Data table of the AM's assigned clients. Columns: Client name + slug.domain, Admin Email, Status badge + CTA, Specialist name, Trial End Date, Actions dropdown.
  • Status CTAs (inline buttons per row):
    • pending_am_setupContinue/ops/clients/[id]/setup/step-1
    • pending_specialist_assignmentAssign/ops/clients/[id]/setup/step-2
    • pending_client_confirmationResend invite (API call)
  • Actions dropdown per row:
    • Continue setup (if pending setup)
    • Resend invite (if awaiting client)
    • View conversations → /ops/inbox?orgId=[id]
    • Edit client → /ops/clients/[id]/edit
    • Deactivate (if active; irreversible — confirmation dialog)
  • Header actions: Search input (client name filter) + Set up new client button → /ops/clients/new
  • Row click: Navigates to /ops/clients/[id]

/ops/clients/new (new client onboarding wizard)

  • Step 1 (this page): Creates the org record and advances to setup flow.
  • Required fields:
    • Company name (min 2 chars)
    • Slug (URL-safe, availability-checked in real-time via SlugAvailabilityInput)
    • Industry (dropdown: E-Commerce, Financial Services, Legal, Healthcare, …)
    • Primary domains (tag input: corporate domains only, no personal email providers)
    • Admin email (must match a primary or secondary domain)
    • Timezone (common + full IANA list)
  • Optional fields (expandable section):
    • Billing email
    • Secondary domains
  • Submit: Creates the org asynchronously (createAmOrgAsync) with 2s-interval polling (max 30 attempts). On success → /ops/clients/[id]/setup/step-2.
  • Retry logic: On timeout shows "Retry" button (re-polls); on failure shows "Resubmit" button.

/ops/clients/[id] (client detail, AM view)

  • Displays: Client name, status badge, subdomain. Tabs visible to AM: Overview · Conversations · Specialists · Team · Tools
  • Overview tab:
    • Editable org fields: display name, website, industry, timezone, notes
    • Auto-reply config card (AutoReplyConfigCard) — set confidence threshold (default 101 = always HITL)
    • Save button
  • Conversations tab:
    • Paginated conversation list with subject, status, channel, last activity
    • Click conversation → opens in context (likely /ops/inbox?convId=...)
  • Specialists tab:
    • List of assigned Specialists with assignment config
    • Add Specialist button (select from existing Specialists)
    • Per-assignment: Edit/ops/clients/[id]/specialists/[assignmentId]/edit
    • Per-assignment: KB/ops/clients/[id]/specialists/[assignmentId]/kb
    • Per-assignment: Remove (confirmation)
  • Team tab:
    • List of client org members with roles
    • AM can view but cannot manage roles (role management is client-side or SuperAdmin)
  • Tools tab:
    • View enabled agent tools for this client
    • AM can view but cannot edit tool permissions (SuperAdmin canEdit only)

/ops/inbox (AM conversation inbox)

  • Displays: Two-panel layout. Left: conversation list (all assigned orgs or filtered by org). Right: message thread.
  • Filters: Org dropdown (All / specific client), Status filter (all / open / resolved / etc.)
  • Actions:
    • Select a conversation (click row)
    • Draft message text area + Send button — sends a message as the AM (not as the Specialist)
    • Update conversation status (resolve/reopen)
    • Pagination within conversation list
  • Auto-selects first conversation on load

/ops/clients/[id]/setup/step-1

  • Displays: Step progress bar (step 1 of N). Org info form pre-populated from existing record.
  • Fields: Company name, slug (with availability check), industry, primary/secondary domains, timezone, admin email
  • Actions: Next → (saves and advances to step 2)

/ops/clients/[id]/edit

  • Inline org edit form (same fields as setup step 1)
  • Save / Cancel buttons

/ops/agent-runs

  • Displays: DataTable of recent agent runtime runs. Columns: Run ID, Kind (conversation_draft / expert_side_chat / agentic_task / tool_action / validation / browser_automation / ops_manual), Status badge, Created, Organisation.
  • Filters: Status dropdown (All / Active / Waiting approval / Waiting input / Failed / Completed / Cancelled), Kind dropdown
  • Refresh button
  • Row click/ops/agent-runs/[id]

/ops/agent-runs/[id]

  • Detail view of a single agent run (steps, inputs, outputs, status timeline)

/ops/approvals

  • Displays: DataTable of approval requests platform-wide (visible to AM for their orgs).
  • Filters: Status (pending / all / approved / rejected / cancelled / expired), Kind (expert_send_approval / expert_tool_approval / client_approval / integration_write_approval / high_risk_response_approval / sandbox_capability_approval / missing_context), Risk level
  • Actions per row:
    • Approve button
    • Reject button
    • Cancel button
  • Refresh button

/ops/settings

  • Fields: Full name, Display name, Email (read-only), Title/Role, Bio (textarea), Phone
  • Actions: Upload avatar, Save changes, Light/Dark mode toggle, Sign out button

6.4 Navigation Structure

Ops sidebar layout (collapsible icon-rail):

  • Header: h.work logo + "Ops" sub-label (links to /ops/clients); collapse/expand trigger
  • Nav items visible to AM (the flat NAV_ITEMS list in ops/layout.tsx — distinct from the SuperAdmin grouped NAV_GROUPS):
    • Clients (Briefcase icon) — /ops/clients
    • Inbox (Inbox icon) — /ops/inbox with conversation count badge
    • Experts (UserCheck icon) — /ops/experts (cross-client rollup, §6.7)
    • Billing (CreditCard icon) — /ops/billing (cross-client rollup, §6.7)
    • Approvals (ClipboardCheck icon) — /ops/approvals
    • Runtime runs (Activity icon) — /ops/agent-runs
  • Not in the AM sidebar: Queue, Specialists, Team, Users, Leads, Applications, Analytics, Health (SuperAdmin-only). /ops/sla is AM-accessible but is also not a sidebar item — it is reached by direct URL / SLA-breach escalation (§6.7).
  • Footer: Avatar + name + "account manager" role label → /ops/settings; Settings icon; Dark/light mode toggle; Keyboard shortcuts (?)

6.5 Permission Boundaries

account_manager cannot:

  • Access /client/* routes (login redirect goes to /ops/clients; no persistent layout guard blocks navigation)
  • Access saOnly ops routes — the Ops layout redirects AMs to /ops/clients for any saOnly page
  • View all clients platform-wide — only their assigned clients appear via listAmOrgs()
  • Access the platform-wide queue (/ops/queue) — SuperAdmin only
  • Create, edit, or delete Specialists (/ops/specialists) — SuperAdmin only
  • Manage internal HP team members (/ops/team) — SuperAdmin only
  • View or manage all platform users (/ops/users) — SuperAdmin only
  • View leads (/ops/leads) — SuperAdmin only
  • Review Expert applications (/ops/expert-applications) — SuperAdmin only
  • View platform-wide analytics (/ops/analytics) — SuperAdmin only (distinct from the AM-accessible cross-client rollups in §6.7)
  • Perform billing mutations (sync-customer, retry-sync, customer detail, expert-workload, llm-cost, payment-failures) — SuperAdmin only; the AM /ops/billing view is read-only and portfolio-scoped (see §6.7)
  • View system health (/ops/health) — SuperAdmin only
  • Manage Tavus function-calls/templates/replicas (/ops/personas/*; the planned rename to /ops/tavus/* via #1031 was closed without merge) — SuperAdmin only
  • Impersonate client users (SuperAdmin-only action in client detail page)
  • Edit tool permissions on client detail (read-only; SuperAdmin canEdit)
  • View the Experts / Integrations / Audit / Agreements tabs on the client-detail page (/ops/clients/[id]) — these per-client tabs are SuperAdmin-only and are separate from the AM-accessible cross-client Experts rollup at /ops/experts (§6.7)

6.6 Golden-Path Flow: Onboard a New Client

  1. Log in → land on /ops/clients
  2. Click Set up new client
  3. New client form: Enter company name, verify slug availability, select industry, add corporate domain(s), enter admin email, set timezone → click Create
  4. System creates the org asynchronously; on completion → redirected to Setup step 2
  5. Step 2: Assign a Specialist from the existing catalog. Set confidence threshold (default 101 = always HITL)
  6. Step 3: (if applicable) Review Expert access grants
  7. Step 4: Send the client invitation email to the admin
  8. Org status moves to pending_client_confirmation — appear on the Clients list with "Resend invite" CTA
  9. Once the client accepts → status becomes active

6.7 Cross-Client Rollups (Experts / SLA / Billing)

Shipped in #1300 (closes #1244). These are portfolio-wide read surfaces: each aggregates across all the AM's assigned clients (organizations.assigned_am_id = me) in one table, with a per-client filter for drill-down. SuperAdmin sees the same surfaces unscoped (every active org). Full engineering reference: docs/features/am-rollups.md.

SurfaceRouteRolls upIn sidebar?
Experts/ops/expertsEvery Expert↔org assignment in the portfolio (one row per org-scoped expert_access grant)
SLA breaches/ops/slaOpen expert-queue items past their SLA deadline, across the portfolio❌ — direct URL / post-escalation landing
Billing/ops/billingPer-Specialist Lago subscription state across the portfolio

Tenant scoping (the safety contract): every rollup goes through AmOrgScopeGuard + OrganizationAccessService. An AM sees only orgs assigned to them; supplying a ?orgIds= for a client outside the portfolio returns 403, and an AM with zero assigned orgs gets an empty table (fail-closed, never unscoped). Verified by api/test/am-cross-org-isolation.e2e-spec.ts.

/ops/experts (Experts rollup)

  • Displays: One row per (Expert, client) — Expert name/email/status, the org, assignment id, assigned-at.
  • Filter: Client dropdown writes ?org=<id>; the selected client is preserved when switching to /ops/billing (and back).
  • Data: GET /am/expertslistAmExpertsRollup (org-scoped, non-revoked expert_access, suspended Experts excluded).

/ops/sla (SLA-breach rollup)

  • Displays: Breached queue items oldest-first — Client (links to /ops/clients/{orgId}), Expert (or "Unassigned"), Breached timestamp, Age since breach, and an Open drill-down link.
  • Filters: Client dropdown (?org=) plus From/To date filters (?from=/?to=, applied to the breach time).
  • Drill-down: Open/ops/clients/{orgId}?tab=experts&queueItemId={id} — lands on that client's Experts/queue tab pointed at the breached item, where the AM/Expert can act on it.
  • What counts as a breach: an open (non-resolved) queue item whose sla_breach_at deadline has passed. The deadline is set at item creation from the org's SLA config (metadata.sla_threshold_hours, default 4h; metadata.sla_timezone, default UTC; metadata.sla_business_hours_enabled, default on → counts only Mon–Fri 09:00–18:00 in the org tz). A sla-breach-monitor cron runs every 2 minutes and escalates each breach once to the org's assigned AM (Slack DM → email fallback).
  • Data: GET /expert-queue?slaBreached=truelistSlaBreaches.

/ops/billing (Billing rollup)

  • Displays: Per-Specialist subscription rows across the portfolio (org, Specialist, status, current rate, currency) plus totals (active, sync_failed).
  • AM vs SuperAdmin: the AM gets a read of their portfolio. Billing mutations (sync-customer, retry-sync, customer detail, expert-workload, llm-cost, payment-failures) stay SuperAdmin-only.
  • Data: GET /ops/billingOpsBillingOverviewQuery (Lago-mirrored state — see §Billing).

Refresh: the rollup pages fetch on load and re-fetch when the client filter changes; there is no background polling on these surfaces, so reload (or change the filter) to refresh.


7. Role: superadmin — SuperAdmin

7.1 Login + Redirect Target

  • Login page: /login
  • Post-login redirect: /ops/clients
  • JWT field: platformRole = "superadmin"

7.2 Route Table

SuperAdmin has access to all /ops/* routes — everything the AM sees plus all saOnly routes.

RouteDescription
/ops/clientsAll clients platform-wide (SuperAdmin view shows full OrgOverview table)
/ops/clients/[id]Full client detail with SA-only tabs: Experts, Integrations, Agreements, Audit + SA action bar
/ops/clients/newCreate new client (same form as AM)
/ops/clients/[id]/setup/step-1 through /step-4Setup wizard
/ops/clients/[id]/editEdit client
/ops/clients/[id]/specialists/[assignmentId]/editEdit Specialist assignment
/ops/clients/[id]/specialists/[assignmentId]/kbManage Specialist KB
/ops/inboxPlatform-wide conversation inbox
/ops/queuePlatform-wide Expert review queue (read + triage)
/ops/expertsExpert roster — assign/remove Experts from client orgs
/ops/specialistsSpecialist catalog — create, edit, delete Specialists
/ops/teamInternal HP team — invite/remove AMs, Experts, AI operators; impersonate
/ops/usersAll platform users — full user table with role filter + impersonate
/ops/leadsCompany leads from sign-up form
/ops/expert-applicationsExpert application review
/ops/analyticsPlatform-wide analytics dashboard
/ops/billingLago subscription management across all orgs (AM + SuperAdmin — #1155; #1165 was closed-unmerged, superseded by #1155)
/ops/healthSystem health dashboard
/ops/agent-runsRuntime agent run monitor (all orgs)
/ops/agent-runs/[id]Agent run detail
/ops/approvalsAll approval requests (full platform)
/ops/personas/templatesSpecialist prompt templates management (the planned rename to /ops/tavus/* via #1031 was closed without merge; /ops/personas/* routes were deliberately retained)
/ops/personas/replicasTavus video replica management
/ops/personas/function-callsFunction call catalog management
/ops/auditPlatform-wide SuperAdmin audit log — actor / action / target / timestamp / diff across all orgs (#1238 / #1298)
/ops/feature-flagsKill-switch / feature-flag admin — toggle platform capabilities at runtime (#1273, closes #1242)
/ops/dlqDead-letter queue admin — inspect / requeue / discard failed background jobs (#1239 / #1251)
/ops/slaAM cross-client SLA rollup — Expert response-time breaches across all orgs (#1244 / #1300)
/ops/impersonationImpersonation audit trail — who shadowed whom, when, and what they did
/ops/poolsExpert pools (legacy — pools removed 2026-05-03)
/ops/settingsSuperAdmin profile settings

7.3 Per-Page Operations

All AM operations apply. The following are SuperAdmin-exclusive additions:

/ops/clients (SuperAdmin view)

  • SuperAdmin-specific columns: Plan badge (free/starter/pro/enterprise), Conversations count, Members count, Created date
  • Row click/ops/clients/[id] (full SA view with extra tabs)
  • Same search + filter as AM view

/ops/clients/[id] (SuperAdmin view)

  • All AM tabs PLUS:
    • SA action bar: Impersonate button → opens member picker dropdown → opens new tab logged in as selected client user (every action audited)
    • Experts tab: Assign/remove Expert access grants for this org (ADR-007 dual-scope — per-Specialist or per-Org). Add Expert → select from Expert list → select scope
    • Integrations tab: View all integration records for this org (Slack, Email, WhatsApp, Telegram, etc.)
    • Agreements tab: View agreement acceptance records + missing agreement alerts
    • Audit tab: Append-only audit trail for this org (entries with actor, action, timestamp, diff)
    • Tools tab (editable): Toggle tool permissions on/off (SuperAdmin canEdit=true)

/ops/queue (SuperAdmin queue)

  • Displays: Two-panel queue view (reuses TicketDetail from workspace). All expert-review items platform-wide.
  • Filters: Status (All / Pending / Resolved), Risk (All / Critical / High / Medium / Low)
  • Auto-refresh: every 15 seconds
  • Actions: Same ticket review actions as Expert workspace (view conversation, edit draft, resolve)
  • Pending count badge in sidebar — updates every 10s

/ops/experts

  • Displays: DataTable of all HP Experts. Columns: Name, Email, Status badge, Assigned Orgs (clickable tags).
  • Actions per row:
    • Assign to org — opens org picker popover → assigns Expert to a client org
    • Remove from org — removes an Expert-Org assignment (per org tag in the cell)
    • Impersonate → opens new tab as that Expert
    • Actions dropdown with all of the above
  • Superadmin-only: listAllUsers() API call with expert role filter; not accessible to AM

/ops/specialists

  • Displays: DataTable of all Specialists in the catalog. Columns: Avatar, First/Last name, Email ({firstname}@{HWORK_DOMAIN}), Category, Skill tags, Confidence threshold.
  • Modes: list / create / edit / view
  • List actions:
    • New Specialist button → switches to create form
    • Row click → opens view modal
    • Edit (actions dropdown) → switches to edit form
    • Delete (actions dropdown) → confirmation then deletes
  • Create/Edit form fields: First name, Last name, Email (auto-composed as {first}@{HWORK_DOMAIN}), Avatar upload, Category (dropdown), Skill tags (tag input), Bio (textarea), System prompt (textarea), Specialty domains (tag input), Catalog slug, Tavus persona ID, Confidence threshold (default 101)
  • Save / Cancel buttons
  • SuperAdmin-only: No AM access to this page

/ops/team (internal HP team)

  • Displays: DataTable of all internal HP team members (AMs, Experts, AI operators). Columns: Name, Email, Role badge, Status badge, Joined.
  • Actions:
    • Invite team member button → form with email + role selector (account_manager / expert / ai_operator)
    • Impersonate (actions dropdown) → opens new tab as selected internal user
    • Remove (actions dropdown) → removes platform member (confirmation)
  • Search input (name/email filter)

/ops/users (all platform users)

  • Displays: DataTable of every user across all orgs and roles. Columns: Name, Email, Role badge, Status badge, Org.
  • Role filter dropdown (All roles / Org Members / Org Admins / Experts / Account Managers / AI Operators / Super Admins). The legacy client_member / client_admin values are dead (never assigned, per #2847) and intentionally omitted from the filter.
  • Search by name or email
  • Row → detail page (/ops/users/[id]): Identity, Lifecycle (incl. audit trail), Memberships, Recent Activity, plus an Actions dropdown:
    • Edit — edit-user form (#1299, closes #1240). Editable fields: Name, Email, Platform role, Status. Email collisions return 409; promoting to SuperAdmin requires re-typing the target email; you cannot demote/disable yourself or the last active SuperAdmin. Changing email/role/status-to-suspended-or-deactivated revokes the user's sessions (confirmation modal interposed).
    • Reset password (active/suspended rows) — emails a 6-digit OTP to the target; the actor never sees it. Active-only on the backend; rate-limited to 5/actor/hour.
    • Impersonate (non-SuperAdmin rows) → opens new tab as that user; reason required, fully audited.
  • Full reference: docs/features/ops-users-admin.md.

/ops/leads

  • Displays: DataTable of company sign-up leads. Columns: Company name, Industry, Contact name, Contact role, Work email, Company size, Headquarters, Selected roles, Created date.
  • Read-only: No actions beyond viewing

/ops/analytics (platform-wide)

  • Period selector: 7d / 30d / 90d
  • Stat cards: Total conversations, resolved %, pending, avg response latency
  • Charts: Daily conversation volume (bar chart), queue status, confidence distribution, top request types, response latency (avg + P95)
  • Scope: All organisations on the platform

/ops/billing

  • Displays: Lago-backed billing overview — stat cards (total / active / sync-failed subscriptions) and a DataTable of all Lago subscriptions across orgs. The legacy Stripe summary view was retired post-Phase-7 (#1016, 2026-05-28); the page was rebuilt on Lago in #1155 (#1165 was closed-unmerged and superseded by #1155) (2026-05-31).
  • Columns: Client, Specialist, Subscription status, Monthly rate, Last sync.
  • Actions per row:
    • Retry sync — re-pushes the subscription to Lago when the previous sync failed.
  • Access: AM + SuperAdmin (no longer saOnly — nav opened in #1155 (#1165 was closed-unmerged and superseded by #1155)). Direct Stripe lives only inside Lago's PSP config.

/ops/health

  • Displays: Service health status cards for: API, Agent, Database, Redis, WebSocket.
  • Each card: service name, status dot (ok=green, degraded=yellow, down=red, checking=grey), status badge label, optional detail message.
  • Refresh button — re-polls all services
  • Auto-refresh interval (best-effort)

/ops/expert-applications (Expert application review — incl. Tavus video interviews)

  • Displays: DataTable of all Expert applicants. Columns: Name, Email, Status badge (pending / reviewing / qualified / invited / interview_completed / waitlisted / approved / rejected), AI score, Tavus interview link + duration, Created date.
  • Tabs: All applicants | Pending review | Interviews (post-interview review queue) | Waitlisted | Approved | Rejected. The Interviews tab is the post-2026-06-03 surface for the Tavus integration (PR #1524).
  • Funnel summary (top of page): counts per status; live as applicants progress.
  • Per-row actions (varies by current status):
    • Send to interview — moves a qualified (or waitlisted) applicant into the Tavus video interview track; mints a personalized interview link via Tavus. PR #1565.
    • Retry interview invite — re-sends the invite email with the same link; useful if the original bounced or the applicant lost it.
    • Approve — promotes the applicant to a platform Expert (creates the user, sends application_approved + welcome emails). The Approve transition is wired to the post-interview status (PR #1565).
    • Decline — sends application_declined and moves to rejected.
    • Update threshold — adjusts the AI-screening threshold inline (no full edit form).
    • 🗑️ Hard delete — SuperAdmin-only destructive action to scrub spam / duplicate submissions. Confirmation required. PR #1519.
  • Tavus interview detail — clicking an interview_completed row opens a side panel with: Tavus conversation ID, recording playback link + duration, transcript link (R2-mirrored per PR #1596 — 7-year retention with signed URLs), AI summary, and reviewer notes textarea.
  • Email side-effects: All status transitions fire templated emails via EmailService (PR #1560): application_received, interview_scheduled, application_approved, application_declined, welcome.
  • Search by name / email / company.
  • Access: SuperAdmin only. AM sees a redirect.

See docs/features/expert-application.md for the full feature treatment including the Tavus webhook lifecycle. The public front of this funnel — the /experts/join landing page and /experts/apply form that feed applications into this queue — is documented in docs/features/expert-acquisition.md.

/ops/personas/templates (rename to /ops/tavus/* via #1031 was closed without merge)

  • Specialist prompt template management (list, create, edit, delete templates)

/ops/personas/replicas

  • Tavus video replica management (list, create, delete replicas linked to Specialists)

/ops/personas/function-calls

  • Function call / tool definition catalog management

/ops/approvals (SuperAdmin scope)

  • Same UI as AM but sees all approval requests across all orgs.
  • Full approve / reject / cancel actions on any request regardless of org.

/ops/feature-flags (kill-switch / feature-flag admin)

  • SuperAdmin-only runtime control plane for major Specialist capabilities. Flip a flag to turn a capability on/off without a deploy — the change propagates across the fleet within ~15 s (the resolve cache TTL). Shipped in #1273 (closes #1242). Full reference: docs/features/feature-flags.md.

  • Layout: three tables — Global flags, Per-org overrides, Per-org-specialist overrides. Each row shows name / scope / state (On/Off badge) / reason / last change (who + when).

  • Flags:

    Flag (UI label)DefaultOFF behavior
    Specialist drafting (agentic_mode_enabled)OnAgentic task creation 403s; pipeline falls back to non-agentic drafting.
    KB retrieval (kb_retrieval_enabled)OnRetrieval returns no documents; Specialist drafts without KB context.
    Auto-reply (auto_reply_enabled)Off (built-in)No AI draft auto-delivered — everything queues for Expert review.
    Tool calling (tool_calling_enabled)OnTool calls blocked at the gateway (status=blocked); drafting continues without tools.
    telegram_self_serve_enabledOffClient self-serve Telegram setup returns 403. The current UI does not give this flag a friendly label, so its global row shows with a blank name and it is not selectable in the Add override dropdown.
  • Scope precedence: most-specific-wins — org_specialist override beats org override beats global beats the built-in default. There is no merge; a narrower row fully overrides broader ones (so an org = On row keeps one client live even while global = Off).

  • Actions:

    • Toggle (power icon) → confirm dialog; a reason (≥ 5 chars) is mandatory before the state flips. Toggle is optimistic and rolls back on API error.
    • Add override (org / org-specialist sections) → supply an Org ID or Org-specialist assignment (OSA) id + reason to create a scoped row.
    • History (clock icon) → per-flag audit trail (last 50 changes for that key + scope: previous → new, actor, timestamp, reason).
  • Auditing: every write is transactional and recorded in feature_flag_audit and the platform audit log (feature_flag.toggle).

  • Incident use: see docs/runbooks/incident-response.md § Feature Flags / Kill-Switches for "when to flip a flag during an incident."

/ops/audit (platform-wide audit log)

  • SuperAdmin-only read-only view of the append-only platform audit log — every significant action across all orgs plus platform-level events. Shipped in #1298 (closes #1238). Full reference: docs/features/audit-log.md.
  • What's recorded: auth/MFA, user admin, impersonation, conversations & messages, Expert queue, drafts, KB document changes, channel inbound, integrations/Haystack, org & OSA lifecycle, Expert-access grants, and feature-flag toggles. Each row captures actor, action, entity type/id, client (org), timestamp, IP, and a JSON payload diff.
  • Columns: Event (human-readable summary + raw action) · Client (org name, or "Platform" for null-org events) · Actor (resolved Name (email), or role for system events, plus a copyable user id) · Entity (type + copyable id) · When (relative, full timestamp on hover).
  • Filters: Client (dropdown), Actor ID, Action (e.g. message.send), Entity (e.g. conversation), From/To datetime range, Rows (25/50/100). Pagination is cursor-based with a total count.
  • CSV export: exports the filtered set up to a 10,000-row cap (warns and truncates beyond that — narrow filters to get the rest). Values are escaped against spreadsheet formula injection.
  • Scope note: actor identities are resolved only on this SA surface and the per-client Audit tab; the customer-facing feed never exposes internal Expert/AM identities.
  • Consistency note: audit writes are eventual/fire-and-forget (ADR-019) — a strong operational record, not a guaranteed-complete ledger. There is no automated retention/TTL — rows persist until manually pruned.
  • Incident use: the primary forensics surface — see docs/runbooks/incident-response.md § Forensics.

7.4 Navigation Structure

Ops sidebar layout — same collapsible structure as AM, but all nav items are visible:

Nav itemIconRoute
ClientsBriefcase/ops/clients
InboxInbox/ops/inbox ← with conversation count badge
QueueListChecks/ops/queue ← with pending-count badge (SA only)
ExpertsUserCheck/ops/experts
SpecialistsIdCard/ops/specialists
TeamUsers/ops/team
UsersUserSquare/ops/users
LeadsLayers/ops/leads
ApplicationsShieldCheck/ops/expert-applications
AnalyticsLineChart/ops/analytics
BillingCreditCard/ops/billing
HealthHeartPulse/ops/health
Runtime runsActivity/ops/agent-runs
ApprovalsClipboardCheck/ops/approvals

Footer: Avatar + name + "superadmin" label → /ops/settings; Settings icon; Dark/light mode toggle; Keyboard shortcuts (?)

7.5 Permission Boundaries

SuperAdmin has no functional restrictions within the platform. However, by design:

  • Hard-delete org is gated on IS_PRODUCTION === false — returns 403 in production. Use deactivate instead.
  • Impersonation is audited — every action taken while impersonating is recorded in the org audit trail.
  • Specialist create/update/delete — these endpoints are SuperAdmin-only at the API layer (PlatformRolesGuard).

7.6 Golden-Path Flow: Promote an Expert and Assign to a Client

  1. Log in → land on /ops/clients
  2. Navigate to Team (/ops/team) to confirm the Expert exists in the HP team; if not, Invite team member with role expert
  3. Navigate to Clients → click the target client → open Experts tab
  4. Click Add Expert → select the Expert from the dropdown → choose scope:
    • scope='specialist' → select which Specialist they cover (tightest, per ADR-007)
    • scope='org' → covers the entire client org
  5. Confirm — the Expert now sees this client's conversations in their /workspace/queue
  6. Optionally navigate to Specialists tab → click Edit on the assignment → adjust confidence threshold to allow auto-send for low-risk messages

8. Cross-Role Reference: Route Ownership

Route prefixorg_adminorg_memberexpertaccount_managersuperadmin
/client/chat
/client/approvals
/client/settings/profile
/client/settings/team✅ manage✅ read-only
/client/settings/channels
/client/settings/billing
/client/admin/knowledge-base
/workspace/queue
/workspace/tasks
/workspace/approvals
/workspace/analytics
/workspace/settings
/ops/clients✅ (own)✅ (all)
/ops/clients/new
/ops/inbox
/ops/queue
/ops/experts
/ops/specialists
/ops/team
/ops/users
/ops/leads
/ops/analytics
/ops/billing
/ops/health
/ops/agent-runs
/ops/approvals✅ (own orgs)✅ (all)
/ops/settings

9. ADR Cross-References

ADR-007: Expert Access Scope — Dual-Scope Grants

Date: 2026-05-22 | Status: Accepted

What it means for operators:

  • Expert visibility is controlled by the expert_access table — the canonical Expert ↔ data grant.
  • Two scopes are supported:
    • scope='specialist': Expert sees only one (Org × Specialist) pair — use for sensitive data separation (e.g., KYC Expert should not see Finance threads)
    • scope='org': Expert sees everything for the whole Org — use for senior reviewers or account leads
  • Deprecated: org_experts table (old direct Org assignment). Do not use in new code.
  • Where to manage: SuperAdmin → /ops/clients/[id]Experts tab → Add Expert + select scope
  • Cascades into: Queue scoping (/workspace/queue filters by access grants), Specialist config visibility, KB access (future)

ADR-018: Multi-Pod Safety Contract (Active-Active)

Date: 2026-05-28 | Status: Accepted

What it means for operators:

  • The platform runs as multi-instance active-active — N pods handle traffic simultaneously with no sticky sessions.
  • There is no "primary" pod — any pod can serve any user request.
  • All state is stored externally (PostgreSQL + Redis) — no in-process caches or counters that matter across requests.
  • Scheduled jobs (e.g., DLQ retry, trial-ending notifications) run exactly once globally via BullMQ with stable jobId — they do not fire N times per pod.
  • This means: if you see unexpected duplicate events or missing jobs, the cause is almost never "multi-pod" by design — it is a code violation of AA1–AA10. File a bug.
  • Rolling deploys are safe — old and new pod versions coexist for minutes during deployment. Schema migrations follow expand-contract (additive first, then remove old columns).

ADR-024: Haystack 2.x + Hayhooks as the RAG runtime (supersedes RAGflow)

Date: 2026-06-02 | Status: Accepted

What it means for operators:

  • KB search in the Expert workspace (and the agent's RAG retrieval path) runs against Haystack/Hayhooks, not the prior RAGflow service.
  • No RAGflow operations remain — provisioning runbooks under docs/_archive/ragflow-*.md are historical. The RAGFLOW_PROVISIONING_MODE env var is no longer used.
  • Per-environment cost moved from ~$2k/env-month → $440/env. If you see unexpected KB-search latency or auth errors, the runbook is docs/runbooks/haystack-deploy.md, not the archived RAGflow ones.
  • Supersedes the archived ADR-004 (per-org corrections dataset) and ADR-009 (RAGflow shared-instance vs per-tenant). Both archived under docs/_archive/.

ADR-025: pgvector on the existing humanwork Postgres

Date: 2026-06-02 | Status: Accepted

What it means for operators:

  • Document embeddings live in the existing humanwork Postgres via pgvector, not RAGflow's bundled search.
  • No separate vector-store ops surface. Operations on the document store happen via standard Postgres tools.
  • The CI postgres container already has pgvector (since b7417b1d, 2026-05-03). New deployments inherit this; no extra setup.

ADR-026: OpenRouter for embed, chat, and rerank

Date: 2026-06-02 | Status: Accepted

What it means for operators:

  • All embed / chat / rerank traffic routes through OpenRouter — one key, one billing line.
  • If an LLM-related cost row appears under "OpenAI direct" or "Anthropic direct" in billing, that is drift and should be filed as a bug. The correction_embeddings path (PR #1604) is currently the one known drift exception; migration tracked in #1614.
  • Single-vendor failure mode: if OpenRouter is down, all LLM features degrade together. Health check on /ops/health surfaces this.

ADR-027: TypeORM migrations only

Date: 2026-06-03 | Status: Accepted

What it means for operators:

  • Schema changes go through TypeORM migrations in api/migrations/. Raw SQL files under api/src/database/migrations/ are forbidden — CI blocks them.
  • Deployments must opt in to running migrations on boot via RUN_MIGRATIONS_ON_BOOT=true. Without that flag, schema changes are silently inert.
  • If a deploy looks successful but a column / table is missing in prod, check the RUN_MIGRATIONS_ON_BOOT env var first — it's the most common cause.

ADR-028: Retire per-org Railway agent runtime — ECS-only

Date: 2026-06-03 | Status: Accepted

What it means for operators:

  • The platform supports two agent runtimes: shared_railway (default) and ecs_per_org (premium).
  • railway_per_org no longer exists as an AgentRuntimeKind. Provisioner code removed in PR #1584.
  • If you see a Railway-per-org reference in an older doc, runbook, or PR description, treat it as historical. The current cutover playbook lives in docs/runbooks/ecs-prod-deployment-spec.md.
  • ADR-003 (Railway as canonical deployment) is fully superseded for staging/prod by ADR-038 — prod cutover #701 closed 2026-06-15. Railway remains canonical for dev only (#1233). Tracked in #1634.

End of USER_OPERATIONS_MANUAL.md