From ad1ad4230e5693446f64ee74b93de8cd2292b982 Mon Sep 17 00:00:00 2001
From: Peter Vachon
Date: Thu, 9 Jul 2026 10:56:02 -0400
Subject: [PATCH 1/5] docs(apollo-vertex): AI Toolkit v1.1 guidance content
Add "Disclose in proportion" as second principle, add EU AI Act
transparency note to Mark and wordmark section, and correct badge and
button variant descriptors to frame variant choice as emphasis and
placement rather than meaning. Add caveat notes for both subsections.
Co-Authored-By: Claude Sonnet 4.6
---
.../app/guidelines/ai-toolkit/mark-usage.tsx | 27 ++++++++++++++-----
.../app/guidelines/ai-toolkit/page.mdx | 3 +++
2 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/apps/apollo-vertex/app/guidelines/ai-toolkit/mark-usage.tsx b/apps/apollo-vertex/app/guidelines/ai-toolkit/mark-usage.tsx
index 0b3501688..2afde3e34 100644
--- a/apps/apollo-vertex/app/guidelines/ai-toolkit/mark-usage.tsx
+++ b/apps/apollo-vertex/app/guidelines/ai-toolkit/mark-usage.tsx
@@ -87,7 +87,7 @@ export function MarkUsage() {
@@ -97,7 +97,7 @@ export function MarkUsage() {
+
+ The label is sample text. Any AI label can take any variant, so choose
+ the variant by screen density and where the badge sits, not by the label.
+ The caveat that AI can make mistakes is separate: it is not a badge
+ passenger in any variant. It belongs to the surface around the content,
+ shown once at the recommendation or action level.
+
+
-
+
-
+
-
+
+
+ The label is sample text. Any AI action can take any variant, so choose
+ the variant by how prominent the action should be and how dense the
+ surface is, not by the label. Keep one solid action per view so the
+ primary choice stays clear.
+
+
diff --git a/apps/apollo-vertex/app/guidelines/ai-toolkit/page.mdx b/apps/apollo-vertex/app/guidelines/ai-toolkit/page.mdx
index 03bab062c..6ee4ebac4 100644
--- a/apps/apollo-vertex/app/guidelines/ai-toolkit/page.mdx
+++ b/apps/apollo-vertex/app/guidelines/ai-toolkit/page.mdx
@@ -14,6 +14,7 @@ components like badges and cards.
## Principles
- **Match the expression to the moment.** A quiet tag marks provenance, a glow highlights a recommendation, the full mark signals a judgment call.
+- **Disclose in proportion.** The more the AI decides, the more you tell the user. A tag is enough to show where something came from, a recommendation should point out what to check, and an action should ask before it runs.
- **Mark the group once, not every control.** Set the AI context at the boundary so the mark keeps its meaning.
- **Pair a glow with a label.** The glow draws the eye and the label says why. Limit it to one best match per view.
- **Use it sparingly.** The expression only reads as special when most of the UI stays neutral.
@@ -40,6 +41,8 @@ The mark, the `Astroid` icon, paired with the wordmark, set bold with tight lett
Two fills: the AI gradient for expressive moments, and a solid fill for dense or
small contexts.
+The mark is not only brand. It is also the label that tells someone a feature is AI, the baseline transparency the EU AI Act calls for, so keep it visible wherever AI is at work rather than tucked behind a hover.
+
## In components
From 86c085c2cc3b4d3ecfefc816a8d9731555b28e1b Mon Sep 17 00:00:00 2001
From: Peter Vachon
Date: Thu, 9 Jul 2026 16:18:11 -0400
Subject: [PATCH 2/5] =?UTF-8?q?feat(apollo-vertex):=20AI=20Toolkit=20v1.1?=
=?UTF-8?q?=20=E2=80=94=20caveat=20disclosure=20pattern?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Adds the AiCaveat registry component and wires it across all AI surfaces
in the AI Toolkit guidance page.
- Add AiCaveat component (registry/ai-caveat/ai-caveat.tsx) with two variants:
standalone (info icon + text, mt-4 standard gap) and withMark (no icon, pl-5
indent to align under the identity mark label, for group boundary placement)
- Standardize content-to-caveat gap to 16px everywhere by making AiCaveat own
mt-4 and using gap-0 on host cards so flex gap does not compound
- Apply standalone caveat footer to: Card (Primary) three cards, Card (selectable)
AI insights card, Plan selection (above Continue), Product recommendation (group
level below three-card row)
- Apply withMark caveat to: Card (Group) and Recommended actions group boundaries
(tight under the mark heading, no icon, ~4px to mark)
- Add source attribution line to activity timeline Agent reviewed step and to the
inline marker in mark-usage
- Update mark-usage badge and button variant descriptors to emphasis/placement
language
Co-Authored-By: Claude Sonnet 4.6
---
.../ai-toolkit/activity-timeline.tsx | 20 ++++++
.../app/guidelines/ai-toolkit/mark-usage.tsx | 18 +++++
.../guidelines/ai-toolkit/plan-selector.tsx | 3 +
.../guidelines/ai-toolkit/product-grid.tsx | 32 +++++----
.../ai-toolkit/recommended-actions.tsx | 2 +
.../ai-toolkit/selectable-cards.tsx | 8 ++-
.../app/guidelines/ai-toolkit/surfaces.tsx | 20 +++++-
.../registry/ai-caveat/ai-caveat.tsx | 70 +++++++++++++++++++
8 files changed, 153 insertions(+), 20 deletions(-)
create mode 100644 apps/apollo-vertex/registry/ai-caveat/ai-caveat.tsx
diff --git a/apps/apollo-vertex/app/guidelines/ai-toolkit/activity-timeline.tsx b/apps/apollo-vertex/app/guidelines/ai-toolkit/activity-timeline.tsx
index ba0d706a1..a7f460713 100644
--- a/apps/apollo-vertex/app/guidelines/ai-toolkit/activity-timeline.tsx
+++ b/apps/apollo-vertex/app/guidelines/ai-toolkit/activity-timeline.tsx
@@ -1,3 +1,4 @@
+import { Link2 } from "lucide-react";
import { cn } from "@/lib/utils";
import { Avatar, AvatarFallback } from "@/registry/avatar/avatar";
import { AiIcon } from "./ai-icon";
@@ -12,6 +13,7 @@ type TimelineEvent = {
// ai-upcoming: queued. ai-progress: running. ai-complete: done. user: a person acted.
marker: "ai-upcoming" | "ai-progress" | "ai-complete" | "user";
initials?: string;
+ sources?: { label: string; href: string }[];
};
// A realistic invoice review trail, newest first, mixing agent and human steps.
@@ -39,6 +41,10 @@ const ACTIVITY: TimelineEvent[] = [
detail: "PO matched, terms verified",
time: "9:10 AM",
marker: "ai-complete",
+ sources: [
+ { label: "PO #8801", href: "#" },
+ { label: "vendor terms", href: "#" },
+ ],
},
{
title: "Data extracted",
@@ -147,6 +153,20 @@ export function ActivityTimeline() {
{event.detail}
+ Source line. When an AI step drew on retrieved data, name where it came
+ from so the result is explainable and the user can trace it back. The
+ names link to the source.
+
+
diff --git a/apps/apollo-vertex/app/guidelines/ai-toolkit/plan-selector.tsx b/apps/apollo-vertex/app/guidelines/ai-toolkit/plan-selector.tsx
index 30facfc32..a3a68855f 100644
--- a/apps/apollo-vertex/app/guidelines/ai-toolkit/plan-selector.tsx
+++ b/apps/apollo-vertex/app/guidelines/ai-toolkit/plan-selector.tsx
@@ -4,6 +4,7 @@ import { ArrowRight, Check } from "lucide-react";
import { useState } from "react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
+import { AiCaveat } from "@/registry/ai-caveat/ai-caveat";
import { Card } from "@/registry/card/card";
import { AiIcon } from "./ai-icon";
@@ -144,6 +145,8 @@ export function PlanSelector() {
})}
+
+
@@ -185,6 +198,7 @@ export function Surfaces() {
AI Identity
+
+ {children ?? "The output is AI generated. Please review."}
+
+ );
+ }
+
+ return (
+
+
+
+ {children ?? "The output is AI generated. Please review."}
+
+
+ );
+}
From 34eab006f5c6cc7dd33b451ce445f7b6af994970 Mon Sep 17 00:00:00 2001
From: Peter Vachon
Date: Fri, 10 Jul 2026 07:56:33 -0400
Subject: [PATCH 3/5] =?UTF-8?q?feat(apollo-vertex):=20AI=20Toolkit=20v1.1?=
=?UTF-8?q?=20=E2=80=94=20Legal=20index,=20nav,=20and=20content=20pass?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add Legal compliance index page with status badges, requirement coverage table, and
source attribution; restructure AI Toolkit nav with Visual Expression and Legal children
via _meta.ts; restructure Visual Expression title with metadata export and v1.1 AI badge;
add withMark variant to AiCaveat with full placement/spacing JSDoc; wire AiCaveat across
all AI surfaces (primary cards, selectable cards, plan selector, product grid, recommended
actions); replace placeholder copy with canonical labels and real example content.
Co-Authored-By: Claude Sonnet 4.6
---
.../app/guidelines/ai-toolkit/_meta.ts | 4 +
.../guidelines/ai-toolkit/ai-input-field.tsx | 4 +-
.../app/guidelines/ai-toolkit/input-field.tsx | 4 +-
.../app/guidelines/ai-toolkit/legal/page.mdx | 120 ++++++++++++++++++
.../app/guidelines/ai-toolkit/mark-usage.tsx | 21 +--
.../app/guidelines/ai-toolkit/page.mdx | 9 +-
.../ai-toolkit/selectable-cards.tsx | 4 +-
.../app/guidelines/ai-toolkit/surfaces.tsx | 33 ++---
.../registry/ai-caveat/ai-caveat.tsx | 69 ++++++----
9 files changed, 209 insertions(+), 59 deletions(-)
create mode 100644 apps/apollo-vertex/app/guidelines/ai-toolkit/_meta.ts
create mode 100644 apps/apollo-vertex/app/guidelines/ai-toolkit/legal/page.mdx
diff --git a/apps/apollo-vertex/app/guidelines/ai-toolkit/_meta.ts b/apps/apollo-vertex/app/guidelines/ai-toolkit/_meta.ts
new file mode 100644
index 000000000..542f025e8
--- /dev/null
+++ b/apps/apollo-vertex/app/guidelines/ai-toolkit/_meta.ts
@@ -0,0 +1,4 @@
+export default {
+ index: "Visual Expression",
+ legal: "Legal",
+};
diff --git a/apps/apollo-vertex/app/guidelines/ai-toolkit/ai-input-field.tsx b/apps/apollo-vertex/app/guidelines/ai-toolkit/ai-input-field.tsx
index d53569005..e78e05d80 100644
--- a/apps/apollo-vertex/app/guidelines/ai-toolkit/ai-input-field.tsx
+++ b/apps/apollo-vertex/app/guidelines/ai-toolkit/ai-input-field.tsx
@@ -16,7 +16,7 @@ import { AiIcon } from "./ai-icon";
export function AiInputField() {
return (
- Job responsibility
+ Cost center
{/* Gradient definition for the mark. */}
diff --git a/apps/apollo-vertex/registry/ai-caveat/ai-caveat.tsx b/apps/apollo-vertex/registry/ai-caveat/ai-caveat.tsx
index 42c248a82..411a19e40 100644
--- a/apps/apollo-vertex/registry/ai-caveat/ai-caveat.tsx
+++ b/apps/apollo-vertex/registry/ai-caveat/ai-caveat.tsx
@@ -4,40 +4,59 @@ import { cn } from "@/lib/utils";
interface AiCaveatProps {
/**
- * `standalone` (default): leading muted info-circle icon + text. Use wherever
- * the caveat is the first or only AI signal in that spot, so the icon marks
- * it as a notice.
+ * `standalone` (default): info-circle icon + text. Use wherever the caveat
+ * is the first or only AI signal in that spot, so the icon marks it as a
+ * notice. Default for single-card footers and below-grid disclosures.
*
- * `withMark`: text only, no leading icon. Use ONLY when the caveat sits
- * directly adjacent to the identity mark at a boundary, with nothing between
- * the mark and the caveat. The mark carries the AI signal; repeating the icon
- * would announce AI twice.
+ * `withMark`: text only, no icon. Use ONLY when locked directly under the
+ * identity mark at a group boundary, with nothing between the mark and the
+ * caveat. The mark carries the AI signal; the icon would be redundant. Text
+ * is indented (`pl-5`) to align under the mark label, not the mark icon.
*/
variant?: "standalone" | "withMark";
/**
- * Caveat copy. Defaults to the canonical fallibility disclosure. Override
- * only the action phrase ("continue", "finalize") when context genuinely
- * differs. The reminder that AI can make mistakes stays constant.
+ * Caveat copy. Defaults to the approved verbatim string. Override via
+ * children only with Legal-cleared copy; do not rephrase the default.
*/
children?: React.ReactNode;
className?: string;
}
/**
- * A quiet caveat for AI recommendation cards. Renders a muted weight-400 line,
- * optionally with a leading info-circle icon.
+ * A quiet fallibility disclosure for AI-generated content.
*
- * Tier rule: icon and text both stay `text-muted-foreground` (monochrome,
- * unfilled). If either takes a color, the component has drifted into the
- * warning tier and is wrong.
+ * ## When to show
+ * Wherever AI generates content the user reads or acts on: recommendations,
+ * actions, AI-generated insights, and summaries. Do NOT add it for identity
+ * or chrome alone (mark, badges, buttons, provenance markers). Disclose once
+ * per surface, never stacked on every element.
*
- * When to use: on cards that make a recommendation or offer an action, once
- * per card. Insight and observation cards do not need it — they are already
- * covered by the AI mark. For a group of cards, disclose once at the group
- * boundary, not on every card.
+ * ## Variants
+ * - `standalone` (default): info icon + text. Footer on a single card, or a
+ * standalone notice below a grid of equal-height cards.
+ * - `withMark`: no icon, indented text. Only at a group boundary directly
+ * under the identity mark, nothing between. ~4px below the mark.
*
- * Do NOT add the AI mark, a badge, or a gradient here. The card header already
- * marks the card as AI (mark once); this carries only the caveat.
+ * ## Placement rules
+ * - Single card: footer inside the card (`standalone`).
+ * - Group headed by a mark: once at the boundary under the mark (`withMark`),
+ * not per card.
+ * - Grid of equal-height cards: once below the grid (`standalone`), not per
+ * card, because a per-card footer fights the row's equal-height stretch.
+ *
+ * ## Spacing
+ * Content-to-caveat gap is 16px, owned by the component (`mt-4`). Host cards
+ * must use `gap-0` so the card's flex gap does not compound with `mt-4`. For
+ * `withMark`, callers use `className="-mt-2 mb-3"` to achieve the ~4px gap
+ * under the mark's `mb-3`.
+ *
+ * ## Tier rule
+ * Icon and text both stay `text-muted-foreground` (monochrome, unfilled). If
+ * either takes a color, the component has drifted into the warning tier.
+ *
+ * ## Copy
+ * Default is the approved verbatim string "The output is AI generated. Please
+ * review." Override via `children` only with Legal-cleared copy.
*/
export function AiCaveat({
variant = "standalone",
@@ -46,9 +65,7 @@ export function AiCaveat({
}: AiCaveatProps) {
if (variant === "withMark") {
return (
-
+
{children ?? "The output is AI generated. Please review."}
);
@@ -62,9 +79,7 @@ export function AiCaveat({
)}
>
-
- {children ?? "The output is AI generated. Please review."}
-
+ {children ?? "The output is AI generated. Please review."}
);
}
From ef2f976773d6830db8fec524bdc9253f0847a9b4 Mon Sep 17 00:00:00 2001
From: Peter Vachon
Date: Fri, 10 Jul 2026 08:02:45 -0400
Subject: [PATCH 4/5] =?UTF-8?q?docs(apollo-vertex):=20AI=20Toolkit=20v1.1?=
=?UTF-8?q?=20=E2=80=94=20public-safe=20cross-link=20and=20Legal=20page=20?=
=?UTF-8?q?cleanup?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Replace internal "For Legal: compliance index" footer with a plain public cross-link;
rename disclosure strings column "Source in the doc" to "Basis" and remove "in the doc"
phrasing from cell copy; fix source-line anchor targets to #in-components where the
timeline marker group actually lives.
Co-Authored-By: Claude Sonnet 4.6
---
.../ai-toolkit/activity-timeline.tsx | 9 +++++---
.../app/guidelines/ai-toolkit/legal/page.mdx | 8 +++----
.../app/guidelines/ai-toolkit/mark-usage.tsx | 22 ++++++++++++++-----
.../app/guidelines/ai-toolkit/page.mdx | 2 +-
4 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/apps/apollo-vertex/app/guidelines/ai-toolkit/activity-timeline.tsx b/apps/apollo-vertex/app/guidelines/ai-toolkit/activity-timeline.tsx
index a7f460713..7a7f5ae78 100644
--- a/apps/apollo-vertex/app/guidelines/ai-toolkit/activity-timeline.tsx
+++ b/apps/apollo-vertex/app/guidelines/ai-toolkit/activity-timeline.tsx
@@ -122,8 +122,8 @@ export function ActivityTimeline() {
- {ACTIVITY.map((event, i) => {
- const last = i === ACTIVITY.length - 1;
+ {ACTIVITY.map((event, idx) => {
+ const last = idx === ACTIVITY.length - 1;
return (
@@ -160,7 +160,10 @@ export function ActivityTimeline() {
{event.sources.map((s, i) => (
{i > 0 && " and "}
-
+
{s.label}
diff --git a/apps/apollo-vertex/app/guidelines/ai-toolkit/legal/page.mdx b/apps/apollo-vertex/app/guidelines/ai-toolkit/legal/page.mdx
index 5657c6d9a..92ca5005e 100644
--- a/apps/apollo-vertex/app/guidelines/ai-toolkit/legal/page.mdx
+++ b/apps/apollo-vertex/app/guidelines/ai-toolkit/legal/page.mdx
@@ -42,7 +42,7 @@ How the AI Toolkit meets in-product AI transparency and disclosure requirements.