Skip to content

Supplier Communications prototype (oCFO experiment) - #1088

Draft
petervachon wants to merge 4 commits into
mainfrom
supplierCommunication
Draft

Supplier Communications prototype (oCFO experiment)#1088
petervachon wants to merge 4 commits into
mainfrom
supplierCommunication

Conversation

@petervachon

Copy link
Copy Markdown
Collaborator

A demo surface for showing an AP team how agentic supplier email handling works.
It lives under Experiment → Supplier Communication and opens full-screen in
its own tab. Illustrative data only: no backend, no network calls, no persistence.

What it is

An agent-operated mail client for accounts payable, in three panes:

  • Workflow rail — filters by kind of work, and collapses behind a filter button
  • Case list — glass cards grouped by when they arrived, with status tabs above
  • Case detail — an editorial read of what the agent did and why

A second tab shows the same threads from the supplier's side: an ordinary
inbox, no portal and no login. The point of that view is what's absent.

The ideas worth reviewing

One elevated block per case, and it's always the thing you can act on. For
most cases that's the drafted reply; for Atlas Precision it's the four-eyes
approval stepper; for Kestrel it's the compliance escalation. Never two, never
zero. Everything above it flattens to rules and eyebrows.

"Needs you" is not "the agent didn't finish". Harborview reads Awaiting
response
, but the PO already went out and reminders run on a schedule, so the
next move is the supplier's. The predicate is a named needsHuman function with
the reasoning in a comment, because the obvious guess is control !== "auto" and
that guess is wrong.

Confidence is a level, not a number. The ConfidenceSignal chip shows bars
rather than a percentage. Cases opened by a monitor or the PO workflow render no
chip at all — they never classified anything, so claiming any confidence about a
judgement that was never made would be worse than saying nothing.

The audit log distinguishes who did what. Agent steps carry the AI mark,
people appear as avatars, deterministic tool calls stay neutral. Classification
and drafting are the agent's; system-of-record reads are not.

AI expression follows /guidelines/ai-toolkit. The mark sits on the compose
card and the agent's audit steps, disclosure appears once per case, and the glow
is reserved for the single generated-content surface.

Notes for reviewers

  • The first commit is cherry-picked from feat(apollo-vertex): add ConfidenceSignal component #1034 (ConfidenceSignal, authored
    by Chloe Daly). It's here so this branch builds standalone. Once feat(apollo-vertex): add ConfidenceSignal component #1034 lands in
    main it should drop out on rebase; if you review this before then, skip that
    commit.
  • Dates are anchored to a fixed NOW, not the clock, so the demo doesn't
    drift into everything reading "Older" next month. It's a Wednesday on purpose,
    which is what makes "Earlier this week" literally true.
  • The prototype mounts in a separate React root attached to <body>. Nextra's
    interrupted hydration otherwise leaves a full-screen client app stuck
    display: none.
  • This has not been reviewed in a browser by its author — there's no Playwright
    in the repo and adding one would have broken the no-new-dependencies constraint.
    Typecheck, lint, format and build are clean, and layout maths was checked by
    calculation, but a human should look at both light and dark before this leaves
    draft.

Still open

  • Badge has no size variant; the list cards would suit a smaller one. Either a
    call-site override here or a real size variant on the shared component.
  • Percentages survive only in the activity log, which is a record of what
    happened. Worth confirming that's the line you'd draw too.

🤖 Generated with Claude Code

ChloeDalyUiPath and others added 4 commits August 26, 2026 11:38
Adds a signal-bar AI confidence chip (high/medium/low/unknown) with
min/med/max density variants, a tooltip on every chip, and a popover for
factor breakdowns and next-step CTAs, plus an opt-in one-time acquire
animation that respects prefers-reduced-motion.

The action CTA (nextStep) is required for medium/low confidence per team
decision, and optional for high/unknown, enforced via a discriminated
union type. Level labels and default explanations resolve through
react-i18next under the confidence_signal_* prefix.

Registered in registry.json with docs at /components/confidence-signal.
Experiment > Supplier Communication docs page links to a full-screen prototype
that opens in its own tab, mounted in a separate React root so it escapes the
Nextra docs layout, whose interrupted hydration leaves the subtree display:none.

The AP workspace is a three-pane, agent-operated mail client:
- shared pane rail, resizable case list, and an editorial case detail
- one elevated block per case: the drafted reply, the four-eyes approval
  stepper, or the compliance escalation. Never two, never zero.
- ConfidenceSignal chips, min in list rows and max in the detail. Triggered
  cases render no chip at all, since they never classified anything.
- audit steps tagged by who performed them, so deterministic system-of-record
  reads do not carry the AI mark

AI expression follows /guidelines/ai-toolkit: the mark sits on the compose card
and the agent's audit steps, disclosure appears once per case, and the glow
stays reserved for the single generated-content surface.

A Supplier tab shows the same threads from the supplier's side: an ordinary
inbox, no portal and no login.

Data is illustrative only. No backend, no network calls, no persistence.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Three axes, each in its own control, so none of them compete: the rail says what
kind of work, the tabs say what state it is in, the date groups say when it
arrived.

- status tabs (All / Needs you / In flight) above the list. The predicate is
  needsHuman, not `control !== "auto"`: Harborview reads "Awaiting response"
  but the PO already went out and reminders run on a schedule, so the next move
  is the supplier's and it belongs under In flight.
- date groups with sticky headers. This needed a real timestamp, so `time` as a
  display string becomes `receivedAt`, with both the relative label and the
  bucket derived from it. NOW is a fixed anchor rather than the clock, and it is
  a Wednesday so day offsets 0-3 land in that calendar week and 4-5 outside it,
  which makes "Earlier this week" literally true.
- the workflow rail loses its Status section, now that the tabs cover it, and
  collapses behind a filter button in the list pane. Width animates while the
  inner nav stays pinned so labels do not reflow mid-slide, and it goes inert
  while hidden so it stays out of the tab order.

Styling: rows are glass cards on a muted ground, the rail and list share that
ground with no divider between them, and an INBOX label sits on the WORKFLOWS
baseline via a shared heading constant. KPI values move up to large bold.

The supplier tab gets the same cards, groups and timestamps. It gets no status
tabs: there are no control states on that side, and the point of the view is
that nothing is asked of the supplier.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…confidence chip

- centre the KPI run between the title and the tab group, with an explicit gap:
  PageHeaderContent sets @3xl:gap-0, which is invisible under justify-between
  but butts the blocks together once they are centred
- "Updated 1 minute ago" plus a Refresh link under the title, using the
  PageHeaderDescription slot. The text is static like NOW: a live counter would
  drift away from the fixed timestamps the rest of the demo is anchored to
- remove the ConfidenceSignal chip from the list cards. It survives in the case
  detail at variant="max", so the level thresholds and the no-chip-for-triggered
  -cases rule are untouched

The card's overlay click target stays, but its comment no longer claims the
chip's nested button as the reason, since that reason left with the chip.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 26, 2026 20:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Supplier Communication experimental prototype surface to Apollo Vertex (full-screen in a separate tab/root) and brings in the ConfidenceSignal UI component (from the referenced PR) to communicate AI confidence as levels rather than raw scores.

Changes:

  • Introduces the Supplier Communication prototype under Experiment → Supplier Communication, including the AP view (workflow rail + case list + case detail) and a supplier-side inbox view.
  • Adds demo-only, fixed-time anchored data (NOW, cases, threads) plus supporting UI components (filters, rails, activity log, action blocks).
  • Adds the confidence-signal registry component + docs and wires translations/registry metadata.

Reviewed changes

Copilot reviewed 32 out of 32 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
apps/apollo-vertex/templates/supplier-communication/SupplierCommunicationShell.tsx New shell-scoped router/query provider wrapper for the prototype.
apps/apollo-vertex/templates/supplier-communication/data/supplier-cases.ts Demo dataset (fixed NOW, cases, workflows, KPIs, supplier threads).
apps/apollo-vertex/templates/supplier-communication/components/workflow-rail.tsx Workflow rail configuration + adapter over shared rail component.
apps/apollo-vertex/templates/supplier-communication/components/supplier-inbox.tsx Supplier-side inbox tab UI (folders, grouped threads, reading pane).
apps/apollo-vertex/templates/supplier-communication/components/scroll-pane.ts Tailwind selector helper intended to fix ScrollArea truncation behavior.
apps/apollo-vertex/templates/supplier-communication/components/pane-rail.tsx Shared collapsible rail implementation used by AP and supplier tabs.
apps/apollo-vertex/templates/supplier-communication/components/pane-rail-types.ts Strongly typed rail section/item models.
apps/apollo-vertex/templates/supplier-communication/components/pane-grid.ts Shared layout constants for the case detail “gutter” and headings.
apps/apollo-vertex/templates/supplier-communication/components/control-tone.ts Central mapping for control-state UI tone + confidence threshold mapping.
apps/apollo-vertex/templates/supplier-communication/components/compose-card.tsx AI-drafted compose action block + disclosure (AiCaveat/AiMark).
apps/apollo-vertex/templates/supplier-communication/components/case-time.ts Fixed-NOW relative time + date grouping utilities for list grouping.
apps/apollo-vertex/templates/supplier-communication/components/case-list.tsx AP case list UI (status tabs, grouping, selection, preview cards).
apps/apollo-vertex/templates/supplier-communication/components/case-filters.ts Workflow/status filtering + needsHuman predicate used by tabs/counts.
apps/apollo-vertex/templates/supplier-communication/components/case-detail.tsx AP case detail pane, including ConfidenceSignal usage and action blocks.
apps/apollo-vertex/templates/supplier-communication/components/approval-steps.tsx Approval workflow stepper component for “four eyes” cases.
apps/apollo-vertex/templates/supplier-communication/components/agent-found-panel.tsx “What the agent found” SoR panel with AI-marked header.
apps/apollo-vertex/templates/supplier-communication/components/activity-log.tsx Provenance/activity log UI with actor markers (agent/person/system).
apps/apollo-vertex/templates/supplier-communication/components/action-block.tsx Single elevated action surface wrapper (AI vs non-AI treatments).
apps/apollo-vertex/templates/supplier-communication/communications/CommunicationsPage.tsx Prototype main page layout (header KPIs + AP/Supplier tabs + resizable panes).
apps/apollo-vertex/registry/confidence-signal/confidence-signal.tsx New ConfidenceSignal component (tooltip + optional popover details/CTAs).
apps/apollo-vertex/registry/confidence-signal/confidence-signal-levels.ts Level config + CTA typing + factor typing + status class map.
apps/apollo-vertex/registry/confidence-signal/confidence-signal-factors.tsx Factor breakdown rows for the popover.
apps/apollo-vertex/registry/confidence-signal/confidence-signal-cta.tsx CTA renderer (button vs anchor via asChild).
apps/apollo-vertex/registry/confidence-signal/confidence-signal-chip.tsx Chip button renderer (bars + label).
apps/apollo-vertex/registry/confidence-signal/confidence-signal-bars.tsx Signal-bars icon (optionally animated acquire sequence).
apps/apollo-vertex/registry.json Registers confidence-signal as a registry UI component.
apps/apollo-vertex/locales/en.json Adds translations/keys for ConfidenceSignal (labels/explanations).
apps/apollo-vertex/app/supplier-communication/page.tsx Mounts the prototype into a separate React root attached to <body>.
apps/apollo-vertex/app/experiment/supplier-communication/page.mdx Adds Experiment landing page + “Open the prototype” link.
apps/apollo-vertex/app/experiment/_meta.ts Adds Experiment nav entry for Supplier Communication.
apps/apollo-vertex/app/components/confidence-signal/page.mdx Adds docs page describing ConfidenceSignal usage and behavior.
apps/apollo-vertex/app/components/_meta.ts Adds Components nav entry for Confidence Signal docs.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

* border instead of ellipsing. Forcing that wrapper back to `block` restores
* the constraint. The `!` is required because Radix sets display inline.
*/
export const SCROLL_PANE = "[&_[data-slot=scroll-area-viewport]>div]:block!";
Comment on lines +22 to +26
function ConfidenceSignalChip({
level,
label,
accessibleLabel,
animateIn = false,
Comment on lines +73 to +77
<nav
aria-label={label}
className={cn(RAIL_WIDTH, "py-4")}
inert={collapsed}
>
Comment on lines +35 to +38
// Date groups say when a case arrived, not whether it needs you, so the dot
// is carrying its own information again.
const needsAction = c.control !== "auto";

Comment on lines +7 to +12
<a
href="/supplier-communication"
target="_blank"
rel="noreferrer"
className="not-prose inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground no-underline transition-colors hover:bg-primary/90"
>
Comment on lines +131 to +136
<ResizablePanel
defaultSize="22rem"
minSize="17rem"
maxSize="34rem"
groupResizeBehavior="preserve-pixel-size"
className="h-full"
Comment on lines +73 to +78
<ResizablePanel
defaultSize="20rem"
minSize="17rem"
maxSize="34rem"
groupResizeBehavior="preserve-pixel-size"
className="h-full"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants