Skip to content

v4.8 — AI Workforce Ops Board

The admin can open one route, watch the whole AI workforce in motion, and act on any ticket from the keyboard — the agent-card grid and the standalone Review Queue are gone.

Summary

Before this milestone, the admin AI Workforce surface was a two-stop experience: an agent-card grid (AIWorkforceView.vue) for "what agents exist," and a separate Review Queue (ReviewQueueView.vue) for "what needs me." Neither answered the question an operator actually has — what is the workforce doing right now, and what is waiting on me — without assembling the picture by hand across two routes.

This milestone replaced both with a single Live Ops Board command center: four columns (Running, Needs review, Handed to you, Shipped today), a live stat cluster, and a right-hand activity rail, all polling every 30 seconds. Clicking any ticket opens a Focus Detail overlay — the artifact body, context panels, and stage-appropriate actions (approve, edit, hand off, reject, pause), fully keyboard-navigable. Both sit on a new work-item ("ticket") view-model layered over the existing AiEmployee → AiRun → AiArtifact domain — a single deriveStage() function now decides which column, chip, and footer actions a ticket gets, replacing what used to be scattered conditionals across two separate views.

Six phases shipped strictly in sequence: the design contract, the view-model, the board shell, the overlay, the actions layer (plus a new claimAiArtifact hand-off mutation), and finally the route cutover that retired the Review Queue for good. The cutover caused one unintended side effect in an unrelated, concurrently-shipping milestone (v4.9's Facebook review UI, built on the component this milestone deleted) — caught by that milestone's own close audit and resolved via a follow-up PR before this milestone closed. See Tech Debt below.

Goal

The admin can open a single route, see the whole workforce in motion, click any ticket, act on it from the keyboard, and never visit the old Review Queue again — rendered against the shared ui/ primitives and design tokens, matching the 2a prototype.

Scope — What Shipped

  • Live Ops Board (OpsBoardView.vue) — top bar with a Live status chip, a Board/Timeline segmented control (Timeline disabled, "coming soon"), and five stats (Need you, Agents active, Approval 7d, Spend MTD, Shipped 7d); four ticket columns; a reverse-chronological activity rail. /ai-workforce is now the landing route — /ops-board and the retired /review-queue both redirect there.
  • Focus Detail overlay (FocusDetailOverlay.vue) — agent identity, queue-position tracker, artifact body (code_patch artifacts render as a diff2html diff sanitized with DOMPurify), "Why it's here" / Run Trace context panels, and stage-appropriate footer actions. Full keyboard nav: J/K move, A approve, E edit, H hand off, R reject, Esc close — with a focus trap and background inert.
  • New work-item view-model (workItem.ts, useWorkforceBoard.ts) — deriveStage(runStatus, artifact) is the single function deciding a ticket's column/chip/actions from (run.status, artifact.approvalStatus, artifact.deliveredAt, artifact.claimedAt, artifact.kind). Greenfield — no equivalent existed before this milestone.
  • New claimAiArtifact mutation + AiArtifact.claimedAt column — backs "Take it myself," persisting the hand-off across the board's 30-second poll instead of a client-only flag a poll would silently overwrite.
  • Consolidated GraphQL query (GET_WORKFORCE_BOARD) replacing the Review Queue's two separately-polled queries.
  • New gold Chip variant ("needs a decision"), added to the existing success | warning | danger | coach | primary | muted set; the board and overlay are the first views beyond AIWorkforceView.vue to adopt the shared GlassPanel/Chip primitives.
  • Route cutover — the former agent-grid view (config, filters, trigger/pause) moved to a secondary /agents route; ReviewQueueView.vue and its spec/story were deleted; Employee Detail and Run Detail kept their existing paths and shape (explicitly out of scope for a reskin this milestone).
  • Playwright smoke coverage for the consolidated /ai-workforce route, wired into the staging CI deploy workflow.

Phases

PhaseNameStatusPlansHighlights
1UI-SPECShipped1 (PR #1610)Design contract + static mockup recreating prototype 2a; resolved icon/component/token deltas up front
2Work-item view-modelShipped1 (PR #1609)workItem.ts, deriveStage(), consolidated board query
3Live Ops Board shellShipped1 (PR #1612)Top bar, four columns, ticket cards, activity rail
4Focus Detail overlayShipped1 (PR #1625, + #1619/#1620)Diff rendering, context panels, keyboard nav, focus trap
5Actions, toasts, auto-advanceShipped2 (PRs #1626, #1627)Footer actions + claimAiArtifact hand-off mutation
6Route cutover + retirement + docs (final)Shipped3 tasks, 4 PRs (#1638, #1643, #1653, #1647)/ai-workforce becomes the landing route; Review Queue deleted; smoke + docs

Key Decisions

  • Stage derivation is one pure function, not scattered view conditionalsderiveStage(runStatus, artifact) reads (run.status, artifact.approvalStatus, artifact.deliveredAt, artifact.claimedAt, artifact.kind) and returns one of running | review | decision | mine | shipped. Every column, chip, and footer action traces back to this single function, replacing what used to be separate logic in the agent grid and the Review Queue.
  • progress/progressLabel dropped from the ticket view-model for V1 — no backing field exists on AiRun/AiArtifact for granular progress; the board shows an elapsed-time label for running tickets instead of a percentage bar.
  • "Take it myself" needed a real server-side hand-off (ACT-3) — a purely client-side claimed flag wouldn't survive the board's 30-second poll. The team added a thin ClaimAiArtifact mutation and AiArtifact.claimedAt column rather than reworking the poll/cache layer.
  • Pause reuses the existing employee-level PauseAiEmployee mutation — no new run-level pause was introduced; pausing an agent from a running ticket pauses the employee, same as the old grid view's pause control.
  • Board promoted to the primary AI Workforce landing route; the agent-config grid demoted to /agents — rather than folding agent configuration into the board or running two top-level routes side by side.
  • diff2html/DOMPurify retained — Focus Detail (Phase 4) built the same code-patch diff rendering the retiring Review Queue used, so deleting ReviewQueueView.vue didn't orphan the dependency.

Requirements Coverage

1 / 1 requirement satisfied (the parent issue's own Acceptance bar — this milestone has no standalone REQUIREMENTS.md, per the planning convention for Multica-issue-driven milestones).

Full detail: v4.8-ai-workforce-ops-board-MILESTONE-AUDIT.md on GitHub.

Outcomes

An admin managing the AI workforce now opens /ai-workforce and sees everything in motion — running agents, artifacts awaiting review, tickets handed to them, and what shipped today — in one place, with a live activity feed alongside. Opening any ticket drops them into a keyboard-driven review flow that auto-advances to the next actionable item. The old Review Queue route no longer exists; visiting it redirects to the board. Agent configuration (trigger, pause, budget, prompt editing) moved to a dedicated /agents route rather than disappearing.

Tech Debt

  • (Phase 4/5) components/ops/Toast.vue hardcodes a literal hsl(222 47% 11%) background instead of the hsl(var(--foreground)) token the UI-SPEC calls for, plus a literal box-shadow and easing-curve drift from spec — a light-mode-contrast risk, Josh-flagged, not yet fixed.
  • (Phase 6, resolved) The route cutover's deletion of ReviewQueueView.vue also removed Facebook-aware review rendering that a different, concurrently-shipping milestone (v4.9) had just added to that same component. Caught by v4.9's own close audit (OBJ-1576) and resolved via a follow-up PR that ported the rendering into FocusDetailOverlay.vue — noted here since this milestone's Phase 6 is what caused the gap.
  • (Out of scope, unaffected) EmployeeDetailView.vue and RunDetailView.vue keep their pre-milestone shape this cycle — the board links out to Run Detail rather than reskinning it.
  • edb485ffa — Phase 1: UI-SPEC + mockup (#1610)
  • 28a6746af — Phase 2: work-item view-model + consolidated board query (#1609)
  • da54ff3f8 — Phase 3: Live Ops Board shell (#1612)
  • d725f60bc — Phase 4: Focus Detail overlay (#1625)
  • 9a700ac9f — Phase 5: ClaimAiArtifact hand-off mutation (#1626)
  • 7fb51b85a — Phase 5: footer actions, toasts, optimistic auto-advance (#1627)
  • 61df5b269 — Task 6.1: route cutover, Review Queue retirement (#1638)
  • cdfdc4960 — Task 6.2: Ops Board Playwright smoke coverage (#1643)
  • 434d2a996 — Task 6.2: wire smoke suite into staging CI (#1653)
  • 171652988 — Task 6.3: docs + CHANGELOG (#1647)

Last updated: 2026-07-20

Loading…