Skip to main content

PRD: UX Debt Remediation — Client Portal

Status: Draft — Awaiting Approval Version: 1.0 Author: Product Manager Agent Date: 2026-04-22 Repo Scope: upsquad-ai/upsquad-client (UI surfaces only) Audit Source: /tmp/ux-audit-client-portal.md (2026-04-22 — Director-of-Ops persona walk) Pilot Stage: Slots between pilot acceptance and paid-MVP cutover


Changelog

  • v1.0 (2026-04-22) — Initial draft. Translates the 2026-04-22 client-portal UX audit (1 P0 already remediated in part, 7 P1, 13 P2, 7 P3) into a structural remediation programme of five waves (U1–U5). Defines persona target, top-10 cross-cutting fixes, severity rubric, success metrics, and explicit boundaries against PRDs #553, #573, and #552.

1. Problem Statement

The UpsQuad client portal exposes backend primitives directly to end-users. Forms ask Directors and Team Leads for UUIDs, raw RBAC permission slugs, proto enum values, and JSON. Page copy uses internal jargon ("cascade", "sticky-deny", "org_unit", "Quad", "Pillar") with no glossary. RPC names leak through <ComingSoon> placeholders. Permission gates show integers (L3) instead of human labels.

The 2026-04-22 audit, conducted in the role of a Director of Operations, surfaced:

  • 1 P0/admin/guardrails is unusable by non-engineers (raw policy form with UUID input, JSON conditions, integer clearance, RPC names in copy). The OnboardingOverlay dev-identity leak (a separate P0) has already been remediated via client#117/#123. The guardrails P0 itself is the anchor case for this PRD's Wave U1.
  • 7 P1 — sidebar, /agents/[id], /approvals, /keys, /admin/roles, /admin/conflicts, /admin/org-units/[id], onboarding flow, /chat mock-data leak.
  • 13 P2 — dashboard, agents list, teams list, billing usage, audit, /admin/import, /quad, /teams/structure, /settings/users, all <ComingSoon> admin pages (8 total), dev-tools exposure.
  • 7 P3 — minor polish on already-good pages (/agents/deploy, /teams/[id]/budget, /billing/*, /workflows, /chat/[agent_id]).

The problem: the portal works for engineers who know the codebase. It does not work for the persona who will pay for it. This blocks paid-MVP cutover after pilot.

A handful of one-off bugs surfaced by the same audit have been filed and closed individually as client#118-122. This PRD is for the structural / cross-cutting remediation — translating backend primitives into domain language with sensible defaults, templates, wizards, pickers, and labels. It is not for one-off bug fixes, which continue to flow through the normal bug pipeline.


2. Goals & Success Metrics

Goals

  1. A non-engineer end-user can complete the top-10 portal flows without ever seeing a UUID, an enum slug, an integer clearance, an RPC name, or raw JSON.
  2. The portal's user-facing language matches the persona's mental model (teams, departments, rules, approvals — not org_units, pillars, policies, action_types).
  3. Every concept-heavy field has a tooltip or first-run explainer; the user does not have to leave the product to understand it.
  4. The portal is keyboard-navigable and screen-reader-accessible on the top-10 most-used pages.
  5. The portal renders cleanly on a narrow viewport (>= 375px) for the same top-10 pages.

Success Metrics (binary, measurable, post-Wave-U5)

MetricTargetHow verified
UUIDs visible to non-engineers in any form field0Static lint: placeholder="UUID" count = 0; manual walk
Raw enum strings (action_type, scope=org_unit, requires_approval literal) shown to user0Manual walk + grep for known enum literals in JSX
RPC / service names in user-facing copy (e.g. TenantService, GovernanceService.ConfigureApprovalPolicy)0Grep <ComingSoon service="..."> and any Service\b in JSX text
Time to create first guardrail rule (cold-start, non-engineer persona)< 2 minStopwatch run on persona script
Top-10 user flows pass keyboard-only navigation100%Playwright keyboard-only suite
Top-10 user flows pass screen-reader smoke (axe-core: 0 critical, 0 serious)100%axe-core in Playwright
Top-10 user flows render correctly at 375px viewport100%Playwright responsive snapshot
clearance-labels.ts adoption coverage (% of clearance display sites)100%grep audit

Non-Goals

  • No backend behavioural changes. This PRD only translates existing RPCs into better UI. If a backend RPC requires a UUID input, the UI takes a picker and resolves it to UUID before calling.
  • No new product features. Debt only.
  • No security-model changes. Clearance levels, RBAC permissions, scope hierarchy stay as-is. Only their presentation changes.
  • No admin portal scope. upsquad-admin (admin#2) has its own PRD.
  • No pricing / billing UX changes. PRD #552 owns billing scope.
  • No dashboard intelligence redesign. PRD #553 owns dashboard scope; this PRD only handles the id-resolution and clearance-label hygiene leaking into the dashboard today.
  • No Quad chat infrastructure changes. PRD #573 (HLD #915) owns Quad. This PRD coordinates the rename "Quad → Copilot" with W8 of that HLD.

3. Persona Target

Primary persona: Non-engineer end-user. Examples: Director of Operations, Team Lead, Head of People, Finance Manager. Same persona that gated PRD #950 walks.

Persona profile:

  • Comfortable with computers and SaaS dashboards (Notion, Linear, Workday, Salesforce).
  • Has never read a backend service spec.
  • Does not know what a UUID, JSON, RBAC, RPC, or proto enum is. May know "JSON" exists but cannot author it.
  • Mental model is in domain language: my team, my department, my approvers, my rules, my agents.
  • Will close the tab if the form asks them to type a UUID or paste JSON.

Persona quote (from audit):

"As a Director of Operations, when I opened Guardrails to tell my agents they can't send customer emails without my approval, I was shown a form that asked me for a UUID, an action_type slug, a number between 1 and 5 with no scale key, and a JSON object. I closed the tab, opened Linear, and filed a ticket asking 'can we just not give any of my team AI agents yet?'."

Secondary persona: Tech-literate admin (DevOps engineer, IT lead). They are happy with raw forms but should not be the only audience that can use the product. They retain access to JSON / advanced views via "Advanced" disclosures, so power-user workflow is preserved.


4. Top-10 Cross-Cutting Fixes (Canonical)

The audit surfaced ten cross-cutting fixes that, taken together, resolve roughly 80% of the friction. Each fix has at least one anchor finding in the audit.

#FixTouchesWave
F1Replace /admin/guardrails raw policy form with a plain-English wizard ("Block what / for which team / do what / with approval from whom / when"). Hide raw JSON / Advanced fields behind disclosure. Template gallery for first-use./admin/guardrails, DryRunPanelU1
F2Eliminate UUIDs from every form field a non-engineer touches. Replace with member, team, unit, and tool pickers./admin/guardrails, /agents/[id], /admin/conflicts, /admin/import, /approvals filter, agent dry-runU3
F3Adopt clearance-labels.ts (L1..L5 → Standard / Internal / Sensitive / Privileged / Executive) at every clearance display site. Module exists; partially used./admin/guardrails, /admin/import, /teams/[id]/tools, /dashboard approvals listU2
F4Rename user-facing jargon: "Quad" → Copilot (coordinated with PRD #573 W8); "Cascade" / "sticky-deny" → remove; "action_type / target / effect" → plain English; "Org Unit" → Team / Department; "Pillar" → Division / Department; "Conflicts" → Rule Conflicts; "tokens" → add "≈ X pages" co-label.Sidebar, /quad, /admin/conflicts, /admin/guardrails, /admin/org-units/[id], /teams, /billing/usageU2
F5Add global ⌘K spotlight search across the portal (cmdk library). 40+ pages, no global jump today.src/components/layout/*, all routesU4
F6Hide raw JSON fields behind "Advanced" disclosure. Default render is structured / human./admin/guardrails (conditions), /admin/conflicts (suggested merge), /admin/import (field mapping)U1, U3
F7Resolve every id.slice(0, N) label to a real name. Fall back to "Unnamed agent" / "Pending approval" — never a UUID prefix./dashboard approvals, /agents list, /teams list, /admin/conflicts/[id], notified-parties listU3
F8Audit and kill every remaining <ComingSoon> page that leaks an RPC name. (client#124 cleaned 9 call sites; verify residue and finish.)/admin/org, /admin/users, /admin/teams, /admin/approvals, /admin/metrics, /workflows, /settings, /settings/organization, plus any introduced sinceU2
F9Tooltip / first-run explainer layer on every concept-heavy field (clearance, scope, target, conditions, status, autonomy). User shouldn't have to Google. Standard tooltip primitive + ? icon convention.All pages with concept-heavy fieldsU4
F10Mobile / narrow-viewport rendering pass on the top-10 most-used pages. >= 375px viewport, no horizontal scroll, tap targets >= 44px.Top-10 pages by usageU5

Top-10 most-used pages (for F10 scope): /dashboard, /agents, /agents/[id], /approvals, /quad (or renamed Copilot), /chat, /teams, /teams/[id]/tools, /billing/usage, /audit. Final list confirmed against analytics during U5 kickoff.


5. Audit Residue (P1 / P2 / P3 carried into LLD tasks)

Every P1/P2/P3 finding in the audit not directly resolved by the top-10 fixes becomes an LLD task under the appropriate wave. Non-exhaustive list — the architect's HLD will enumerate fully:

P1 (must close before paid-MVP)

  • Sidebar: rename sections to user mental models, hide ComingSoon items, fix hardcoded badge: 3, replace BE/FE/QA/AR agent monograms with tenant-data, add cmd-K. (U2 + U4)
  • /agents/[id]: replace UUID inputs for Supervisor + Org Unit with pickers; rewrite ErrorState.detail to plain English; drop "Agent ID: {uuid}" from chat header. (U3)
  • /approvals: move "Session ID" filter behind Advanced; tooltip every status; add "My queue" tab. (U2 + U4)
  • /keys: rewrite "programmatic access" copy; empty-state guidance; show example cURL after creation. (U2)
  • /admin/roles: auto-generate slug; show permission categories not slug list; describe each built-in role; rename agents.register → "Hire new agents" style. (U2)
  • /admin/conflicts: rename "Conflicts" → "Rule Conflicts"; replace winning/losing layer with English narrative; hide JSON; replace UUID filters with pickers; simplify action buttons to a 2-option radio. (U2 + U3)
  • /admin/org-units/[id]: rename "Org unit" to actual type; hide UUID from subtitle; rename "Effective tools"; rename "Numeric ceiling". (U2)
  • Onboarding flow: surface org-creation errors with retry CTA; "Skip" should actually skip; add progress indicator. (U2)
  • /chat: replace hardcoded MOCK_AGENTS (UpsQuad internal team names) with useAgents(); drop "Agent ID" UUID; replace slash-command approvals with buttons. (U2 + U3)

P2 (close before paid GA)

  • /dashboard: id-to-name resolution for approvals + agent grid; clearance label adoption; first-time onboarding tile. (U3 + U2)
  • /agents: resolve teamId → team name; add Status / Last active / Owner columns; filters bar; first-use empty state. (U3)
  • /teams: rename "Pillar" → "Department"; resolve ID → name; clickable rows; "Create team" CTA. (U2 + U3)
  • /teams/[id]/tools: risk labels need icons not just colour; swap L{n} for clearanceLabel(); pretty-print approver_role slugs. (U2)
  • /audit: subhead rewrite; actionType filter as human dropdown; export-to-CSV. (U2)
  • /billing/usage: tokens → "≈ X pages"; tooltips on every metric; hide mock breakdowns until real data lands. (U2)
  • /admin/import: rename "SCIM endpoint" → "Connect to your directory"; dropdown picker for field mapping in simple mode; remove TODO comments from JSX; clearance-label adoption. (U2)
  • /quad: first-visit tour ("Hi! I'm Copilot, your org assistant."); more suggestion chips with "See all" gallery; empty-workspace hint. (U2 + U4)
  • /teams/structure: rename sidebar item "Agent Structure" to "Org Chart"; align with page title. (U2)
  • /settings/users: add single-user invite dialog; tooltips on filter values; split Members vs Agents. (U2 + U4)
  • Dev-tools exposure hardening: Playwright assertion that test buttons / clearance switcher are absent without NEXT_PUBLIC_DEV_TOOLS. (U2)

P3 (nice-to-have)

  • /agents/deploy: surface deploy errors via toast; success celebration with "chat with new agent" CTA. (U2)
  • /teams/[id]/budget: hide UUID from breadcrumb when team name not yet loaded. (U3)
  • /billing + /billing/plans + /billing/invoices: minor copy polish (whitelist tier names). (U2)
  • /workflows + /workflows/[workflow_id]: resolves with the central ComingSoon refactor (F8). (U2)
  • /chat/[agent_id]: drop "Agent ID" header line. (U3)

6. Wave Plan

Each wave is independently shippable, ordered by user-facing impact. Each wave is gated by an architect HLD review and a PM product-acceptance review against the success metrics it targets.

Wave U1 — Guardrails Wizard (the largest single user-facing win)

Why first: the audit's only P0 page; the single most cited blocker for paid MVP. The current page is unusable by the target persona.

Scope:

  • Replace /admin/guardrails policy editor with a 5-step plain-English wizard: (1) what to control, (2) which team, (3) what should happen, (4) approval routing, (5) when it applies.
  • Tile-based step 1 with starter categories (Money / Billing, Customer data, Code & deployments, External tools, Everything high-risk).
  • Team picker (tree) replacing unitId UUID input.
  • Effect radio with English labels ("Always block", "Pause and ask a human", "Allow freely") replacing allow / deny / requires_approval enum.
  • Clearance label rendering (Standard / Internal / Sensitive / Privileged / Executive) replacing min_clearance integer.
  • Conditions: chip selector (Always, Outside business hours, Over a dollar threshold) with "Advanced (JSON)" disclosure.
  • DryRunPanel: default caller to "me", default action to a recent action from the user's audit log; show verdict as a sentence ("This rule would have blocked 3 actions in the last 7 days").
  • Cascade explanation replaced with a stacked-block visualisation.
  • Template gallery for first-use empty state (6 starter templates).
  • Remove all TODO comments and RPC names from page copy.

Estimate: ~3 weeks (architect HLD + frontend implementation + UX iterations). Depends on: picker primitives from U3 may be reused; for U1 we ship a guardrails-only inline picker and refactor in U3 if needed. Acceptance: non-engineer creates first rule in < 2 min; zero UUIDs / enum strings / RPC names visible.

Wave U2 — Jargon Rename + Clearance Labels + ComingSoon Cleanup

Why second: mostly mechanical, cross-cutting, visible on every page. Highest-leverage low-effort wave. Coordinates with PRD #573 W8 for "Quad → Copilot".

Scope:

  • F3: clearance-labels.ts adoption everywhere.
  • F4: jargon rename pass — "Quad" → "Copilot" (coordinate with PRD #573 W8), "Conflicts" → "Rule Conflicts", "Org Unit" → "Team" or "Department" by context, "Pillar" → "Division" or "Department", "Cascade" / "sticky-deny" removed from copy, "action_type / target / effect" mapped to English, tokens → "≈ X pages".
  • F8: finish the <ComingSoon> cleanup — refactor the component to drop the service prop from display; hide nav items pointing to non-functional pages.
  • Sidebar polish: section renames, hide ComingSoon items, fix hardcoded badge: 3, replace BE/FE/QA/AR agent monograms.
  • All P1/P2 copy fixes from the audit residue list.

Estimate: ~1.5 weeks. Depends on: PRD #573 W8 schedule for the rename. If #573 is in flight, coordinate naming strings; if not, U2 ships the rename first and #573 inherits. Acceptance: zero raw enum strings, zero RPC names, full clearance-label coverage, zero <ComingSoon service="..."> leaks.

Wave U3 — UUID → Picker Migration + ID-to-Name Resolution

Why third: the second-largest user-facing win. Each picker is a small reusable component; many call sites.

Scope:

  • F2: ship four reusable pickers — <MemberPicker>, <TeamPicker>, <UnitPicker>, <ToolPicker>. Tree / typeahead / category-grouped variants.
  • Migrate all UUID input fields to pickers: /agents/[id] (Supervisor + Org Unit), /admin/conflicts filters (member_id), /approvals (Session ID filter behind Advanced + replaced by member picker for primary use), /admin/import field-mapping pickers, dry-run caller picker.
  • F7: resolve every id.slice(0, N) label to a real name. Fallbacks are "Unnamed agent" / "Pending approval", never UUID prefix. Affected: /dashboard approvals + agent grid, /agents team column, /teams pillar column, /admin/conflicts/[id] policies, notified-parties.
  • Hide JSON conditions on /admin/conflicts/[id] "Suggested merge" behind "View technical details"; default render is before/after rule comparison.

Estimate: ~3 weeks. Depends on: U1 (picker primitives may originate in U1's guardrails wizard and graduate here). Acceptance: zero placeholder="UUID" in codebase; zero id.slice(0, N) in JSX text.

Wave U4 — ⌘K Spotlight + Tooltip Layer + First-Run Explainers

Why fourth: quality-of-life multiplier. Adds discoverability across the now-cleaned-up portal.

Scope:

  • F5: ⌘K spotlight via cmdk. Indexes pages, agents, teams, recent approvals, settings, help articles.
  • F9: tooltip primitive + ? icon convention. Apply to: clearance labels, scope, target, conditions, status, autonomy levels, every approval status, every risk label.
  • First-run explainers: /quad (renamed Copilot) tour card; sidebar tooltips on every nav item; "what this role lets someone do" descriptions on /admin/roles.
  • "My queue" tab on /approvals.

Estimate: ~2 weeks. Depends on: U2 (renames must land first so tooltip copy is consistent). Acceptance: every concept-heavy field has discoverable explanation; cmd-K reaches every page in the portal in <= 2 keystrokes after open.

Wave U5 — Mobile / Responsive Pass

Why last: lowest user-facing return for pre-paid-MVP, but required for trial-conversion personas using laptops with narrow split views and tablets.

Scope:

  • F10: top-10 most-used pages render correctly at 375px viewport. No horizontal scroll. Tap targets >= 44px. Tables collapse to card view at < 768px. Side-sheets become full-screen at < 768px.
  • Playwright responsive snapshot tests for the top-10 set.

Estimate: ~2 weeks. Depends on: U1–U4 (rendering pass is faster after the layout has stabilised). Acceptance: top-10 pages pass 375px Playwright snapshots; axe-core reports 0 critical / 0 serious accessibility issues; keyboard-only navigation reaches every actionable element.


7. Severity Rubric (for prioritisation)

SeverityDefinitionDisposition
P0Blocks pilot acceptance — user cannot complete the flow at all, or risk of data leak / fake admin metadata.Onboarding-overlay P0 already shipped (client#117/#123). The remaining audit P0 is the guardrails page itself, scoped into U1.
P1Blocks paid-MVP — non-engineer cannot complete a flow without help; trust-eroding.Must close before customer #2. Scoped into U1 + U2 + U3.
P2Degrades trial-conversion — flow is completable but feels broken / clunky / opaque.Close before paid GA. Scoped into U2 + U3 + U4.
P3Nice-to-have polish; does not block conversion.Scoped into U5 or deferred to v1.1 of this PRD.

8. Functional Requirements

Each requirement is a binary, testable condition. Mapped to a wave.

#RequirementWave
FR-1The /admin/guardrails page presents a wizard with steps {what, who, action, approval, when} as the default editing experience.U1
FR-2The guardrails wizard hides raw JSON conditions behind an explicit "Advanced" disclosure.U1
FR-3The guardrails wizard never displays a UUID, an action_type slug, an effect enum literal, an integer clearance, or the string guardrails.edit to a user with role < L4.U1
FR-4The guardrails dry-run defaults the caller to the current user and pre-fills a recent action from the user's audit log.U1
FR-5A guardrails template gallery offers >= 6 starter policies on first-use empty state.U1
FR-6The portal exposes reusable <MemberPicker>, <TeamPicker>, <UnitPicker>, and <ToolPicker> components.U3
FR-7Every form field that accepts a member, team, unit, or tool ID uses the corresponding picker; no placeholder="UUID" input remains.U3
FR-8Every clearance display site uses clearance-labels.ts (Standard / Internal / Sensitive / Privileged / Executive). No L{n} or bare integer rendering remains.U2
FR-9The <ComingSoon> component does not display the service prop. Pages with no functional backend are removed from sidebar nav.U2
FR-10The user-facing string "Quad" is renamed to "Copilot" across sidebar, page titles, and copy (coordinated with PRD #573 W8).U2
FR-11The user-facing string "Conflicts" (referring to policy cascade) is renamed to "Rule Conflicts" or "Policy Conflicts".U2
FR-12The user-facing strings "Org Unit", "Pillar", "Cascade", "sticky-deny" are removed from copy. Domain replacements are used contextually (Team / Department / Division).U2
FR-13Token-count metrics on /billing/usage carry an "≈ X pages" co-label.U2
FR-14No JSX text in the portal contains the substring id.slice(0, followed by a render. Fallback labels are "Unnamed agent" / "Pending approval" / "Unnamed team".U3
FR-15A global ⌘K command palette is reachable on every portal page. It indexes all pages, agents, teams, recent approvals.U4
FR-16Every clearance, scope, target, conditions, status, autonomy, and risk label has a discoverable tooltip on hover/focus.U4
FR-17First-time visitors to /quad (renamed Copilot) see a tour card explaining the surface.U4
FR-18The /approvals page has a "My queue" tab that filters to approvals awaiting the current user.U4
FR-19The top-10 most-used pages render correctly at 375px viewport with no horizontal scroll.U5
FR-20The top-10 most-used pages pass keyboard-only navigation (every actionable element reachable via Tab).U5
FR-21The top-10 most-used pages pass axe-core with 0 critical and 0 serious findings.U5
FR-22The sidebar's hardcoded badge: 3 is replaced with the live pending-approval count, or removed.U2
FR-23The sidebar's BE/FE/QA/AR agent monograms are replaced with tenant-supplied agent data, or removed.U2
FR-24The /chat index page renders agents from useAgents() rather than the hardcoded MOCK_AGENTS array.U2
FR-25Slash-command approval shortcuts (/approve, /reject) are replaced by structured action buttons in chat.U3
FR-26The <OnboardingOverlay> failure path surfaces an error toast with retry + support CTA; "Skip" defers org creation rather than triggering it.U2
FR-27Dev-tools surfaces (clearance switcher, "Test Onboarding" button) are absent from production builds; verified by Playwright.U2

9. Non-Functional Requirements

  • Performance. Picker components must support typeahead with <= 100ms p95 latency on a tenant with 5,000 members / 500 teams. Server-side filter required; full client-side load not acceptable.
  • Accessibility. All new components meet WCAG 2.1 AA. axe-core in CI for the top-10 pages.
  • Internationalisation readiness. All renamed strings flow through a single copy module so i18n can layer on later. (No translation in scope; only string-extraction discipline.)
  • Telemetry. Wave U1 ships an analytics event for "first guardrail created" with elapsed time from page load. Used to verify the < 2 min success metric.
  • Backwards compatibility. Power users who relied on raw forms retain access via "Advanced" disclosures. No flow becomes unreachable.
  • Build hygiene. Lint rule added to fail CI on placeholder="UUID" and on <ComingSoon service= literal usage.

10. Scope

In Scope

  • The upsquad-client Next.js portal under src/app/(portal)/**.
  • Reusable component primitives (pickers, tooltip, command palette, clearance label) under src/components/**.
  • Copy module for renamed strings.
  • Playwright responsive + accessibility test suite for top-10 pages.
  • Lint rules to prevent regressions.

Out of Scope (explicit)

  • Backend RPC redesign. The UI translates them; the contract stays.
  • New product features.
  • Admin portal (upsquad-admin) — owned by admin#2.
  • Pricing / billing UX changes — owned by PRD #552.
  • Dashboard intelligence overhaul — owned by PRD #553.
  • Quad chat infrastructure — owned by PRD #573 (HLD #915). Coordinate the "Quad → Copilot" rename only.
  • One-off bug fixes already filed and closed (client#118-122).

11. Dependencies

DependencyDirectionBoundary
PRD #553 — Dashboard Intelligence (awaiting approval)Overlap on /dashboard polishThis PRD owns id-resolution + clearance-label hygiene on the dashboard today. PRD #553 owns the broader dashboard redesign. If #553 ships first, this PRD's dashboard changes are absorbed; if this PRD ships first, #553 inherits the cleaner baseline.
PRD #573 — Quad / Copilot (approved, HLD #915)Coordinate the rename "Quad → Copilot"The rename string lives in W8 of HLD #915. This PRD's U2 wave coordinates with that schedule. Whoever ships first owns the rename; the other inherits. PjM to align.
client#124 — <ComingSoon> audit (already closed, 9 call sites cleaned)This PRD verifies residue and finishes the jobDoes not redo what client#124 did. Scopes only the remainder.
PRD #549 — Org Model v2.3 (HLD #556)Picker behaviour relies on the org modelPickers query the v2.3 org-tree shape. No v2.3 model changes from this PRD.
PRD #950 — Pre-Onboarding E2ESame persona targetSuccess metrics align: PRD #950 verifies behavioural correctness; this PRD verifies UX comprehensibility for the same persona.
PRD #552 — Pricing & PackagingBoundary on /billing/*This PRD only touches /billing/usage for token co-labelling. All other billing UX is #552's.

12. Edge Cases & Failure Modes

  • Picker fallback when org tree fails to load. Pickers must show an error state with retry, not a blank dropdown. Forms remain submittable only when picker resolves.
  • Locale: long names. Picker labels and clearance labels must truncate gracefully with tooltip showing full name.
  • Power user wants the JSON. "Advanced" disclosure must persist preference per-user (localStorage) so a returning power user defaults to JSON view.
  • First-run tour shown to returning users. Tour-shown flag stored per user × surface to avoid re-display.
  • MOCK_AGENTS removal on a tenant with 0 deployed agents. Empty state must point to /agents/deploy rather than show "No agents".
  • Mobile viewport on a flow that demands a wide table. Tables collapse to card view < 768px; column priority documented per page.
  • Screen reader announces clearance changes. When the Advanced disclosure expands JSON, it must announce; aria-expanded handled by tooltip primitive.
  • Migration period for renames. During the rename rollout, server-side links / emails referencing "Quad" may reach users post-rename. A redirect from /quad to /copilot (or a renamed route) handles existing bookmarks.

13. Pricing Tier Mapping

This PRD is debt remediation across the existing portal. All tiers benefit equally. No new tier-gated features are introduced. The wizard, pickers, ⌘K, and tooltip layer ship to every tier that has portal access (Starter / Business / Enterprise on Cloud; Standard / Premium / Critical on On-Premise).


14. Estimated Cost

WaveEffortPersonsCalendar
U1 — Guardrails wizardL1 frontend-sme + architect HLD + UX iterations~3 weeks
U2 — Jargon rename + clearance labels + ComingSoonM1 frontend-sme~1.5 weeks
U3 — Pickers + id-to-nameL1 frontend-sme~3 weeks
U4 — ⌘K + tooltips + first-runM1 frontend-sme~2 weeks
U5 — Mobile / responsiveM1 frontend-sme~2 weeks
Total~11.5 weeks for a single frontend-sme

Parallelisation: U1 and U2 can run in parallel if a second frontend-sme is available, compressing the calendar. U5 is strictly last.


15. Open Questions

  1. Rename target for "Quad". PRD #573 picked Copilot in W8; confirm that's the final choice before U2 ships, since the rename is hard to undo.
  2. Power-user preference persistence. Per-user (localStorage) or per-org (server)? Recommendation: per-user.
  3. Top-10 pages list for U5. Should be confirmed against analytics at U5 kickoff. Draft list above is the audit's proxy.
  4. Telemetry for "time to first guardrail". New event or reuse of existing analytics pipeline? PjM to confirm with analytics architect.
  5. Coordination with PRD #553. If both ship in the same release window, who absorbs whose dashboard changes? PjM to sequence.

16. Acceptance Criteria (PM Sign-off)

The PRD is considered fully delivered when:

  • All 27 functional requirements (FR-1 through FR-27) are verified shipped.
  • All 8 success metrics in §2 hit their targets.
  • A persona walk by a non-engineer (Director-of-Ops or equivalent) successfully completes the top-10 flows without external help, in a single session.
  • No regression on PRD #553 / #573 / #552 scope.
  • Lint rules to prevent regressions are active in CI.

17. References

  • Audit source: /tmp/ux-audit-client-portal.md (2026-04-22, frontend-sme, Director-of-Ops persona walk).
  • Already-shipped P0 fixes: client#117 (OnboardingOverlay dev-identity leak) merged via client#123.
  • Already-filed bug residue: client#118-122 (batched + closed).
  • Related PRDs: #553 (Dashboard Intelligence), #573 (Quad / Copilot), #549 (Org Model v2.3), #552 (Pricing & Packaging), #950 (Pre-Onboarding E2E).
  • Related cleanup issue: client#124 (<ComingSoon> initial audit, closed).

End of PRD v1.0.