Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions core/agents/aidlc-design-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ You are a senior UX/UI designer specializing in wireframing, interaction design,
- Optimize flow length and minimize steps to task completion
- Design onboarding flows for first-time users

### Visual Direction
- State the design read (product kind, audience, visual language, design system or aesthetic family) before designing any screen, derived from existing brand assets, the audience, and any overriding constraints
- Define the foundation token table in the design system mapping: type scale, semantic colour tokens with contrast pairs and both themes, spacing, radius, elevation, motion, and iconography
- Map every visual value in the mockups to a named token; propose new tokens by name rather than embedding raw values
- Reach past generated-design defaults deliberately (see `{{HARNESS_DIR}}/knowledge/aidlc-design-agent/visual-design-foundations.md`)

## Collaboration

- **Receives from**: product-agent (user stories, personas, intent), architect-agent (component design constraints)
Expand All @@ -64,3 +70,4 @@ You are a senior UX/UI designer specializing in wireframing, interaction design,
4. **Accessibility is not optional** — WCAG compliance is a baseline, not a stretch goal. Every user-facing specification must address accessibility.
5. **Show, do not tell** — Describe interactions in terms of concrete screen states and transitions, not abstract concepts.
6. **Design for the worst case** — Empty states, error states, long text, slow connections. The design must work gracefully under adverse conditions.
7. **Read the audience before choosing a look** — Existing assets, the audience, and regulatory or accessibility constraints decide the visual direction. A look that arrives by default rather than by that reading is a finding, not a style.
3 changes: 2 additions & 1 deletion core/aidlc-common/stages/inception/refined-mockups.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ Create `<record>/inception/refined-mockups/refined-mockups-questions.md` with qu
- What interaction patterns are needed (modals, inline edits, wizards, progressive disclosure)?
- What states must each screen handle (loading, empty, error, success, partial)?
- Does the design align with the existing design system / component library?
- What brand assets, design system, or aesthetic references already exist, and who is the audience (the inputs to the design read)?
- What accessibility requirements apply (WCAG level)?
- What responsive breakpoints are needed?
- For APIs: what does the developer experience look like?
Expand All @@ -75,7 +76,7 @@ Validate design decisions against user stories and requirements for consistency.

### Step 4: Generate Artifacts

Create mid-to-high fidelity mockups (per user story/screen), interaction specification document (use `{{HARNESS_DIR}}/knowledge/aidlc-design-agent/component-spec-template.md` as the format for component-level specifications), design system mapping, responsive behavior specification, and accessibility compliance checklist.
Create mid-to-high fidelity mockups (per user story/screen), interaction specification document (use `{{HARNESS_DIR}}/knowledge/aidlc-design-agent/component-spec-template.md` as the format for component-level specifications), design system mapping (opening with the design read and carrying the foundation token table from `{{HARNESS_DIR}}/knowledge/aidlc-design-agent/visual-design-foundations.md`), responsive behavior specification, and accessibility compliance checklist.

For non-UI: create API developer experience specification.

Expand Down
126 changes: 126 additions & 0 deletions core/knowledge/aidlc-design-agent/visual-design-foundations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Visual Design Foundations

The wireframing and UX guides settle structure: screens, states, flows, and
accessibility. This guide settles the visual layer the developer builds from.
Its output is two things: a stated visual direction, and a foundation token
table inside `design-system-mapping.md`. Without both, every visual decision is
made silently at code generation, outside the mockup approval gate.

## The Design Read

State the visual direction in one line before designing any screen, and put
that line at the top of `design-system-mapping.md`:

> Reading this as: `<product kind>` for `<audience>`, with a `<visual language>`
> language, built on `<existing design system | aesthetic family>`.

Derive it from evidence, in this order:

1. **Existing assets win.** A logo, palette, type choice, or component library
already in use is the starting material, not an option. Map to it; do not
restyle it.
2. **The audience picks the look, not the designer.** A procurement panel, a
clinician, a consumer on a phone, and an operator on a wall display want
different densities, contrasts, and tones.
3. **Quiet constraints override preference.** Public-sector, regulated,
safety-critical, accessibility-first, and children's products constrain
colour, motion, density, and tone before any aesthetic choice is made.
4. **References from the stories and Q&A.** Products the stakeholders named,
competitors mentioned, screenshots attached.

If the read cannot be settled from evidence, it is a clarifying question for
the stage's question file, not a guess.

## Defaults to Reach Past

When nothing constrains the look, generated designs converge on the same
choices. Treat each as a signal that the design read was skipped:

- A gradient hero over a dark background with a single centred headline
- Three equal feature cards in a row, each with an icon, title, and sentence
- Translucent blur applied as decoration rather than to indicate a dismissable layer
- One generic sans-serif at one weight for every role
- Purple or violet as the primary colour with no brand reason
- Looping motion on elements that carry no state change
- Emoji used as icons

Any of these may still be the right call for a specific product. The
requirement is that it follows from the design read, not from its absence.

## Foundation Token Table

`design-system-mapping.md` carries a token table for every group below. When
an existing design system supplies a group, map to its names; when none exists,
define the group here so the developer never invents a value.

### Type

- **Scale**: a fixed set of sizes (for example 12, 14, 16, 18, 24, 32) named by
role (caption, body, lead, title, headline, display), never ad-hoc pixels
- **Line height**: 1.5-1.75 for body text; tighter only for display sizes
- **Measure**: 45-75 characters per line for reading text
- **Weight hierarchy**: headings 600-700, body 400, labels 500; weight and
size together carry hierarchy, colour alone never does
- **Pairing**: at most two families, one for headings and one for body, chosen
for the same personality; confirm the families cover every script the
product's locales require (diacritics, CJK, RTL)
- **Numbers**: tabular figures wherever digits align in columns, prices, or
timers, so values do not shift width as they change

### Colour

- **Semantic tokens, not raw values**: `primary`, `on-primary`, `surface`,
`on-surface`, `surface-variant`, `outline`, `error`, `on-error`, `success`,
`warning`, `info`; components reference tokens only
- **Contrast pairs**: every foreground/background pair in the table states its
ratio; 4.5:1 for body text, 3:1 for large text and UI boundaries
- **Light and dark together**: define both themes in the same table; dark
values are desaturated, lifted tonal variants, not inverted light values, and
their contrast is verified separately
- **Meaning is never colour-only**: an error, success, or warning token is
always paired with an icon or text

### Space, Shape, and Depth

- **Spacing scale**: one base unit and its multiples (for example 4, 8, 12, 16,
24, 32, 48, 64); every margin, padding, and gap resolves to a step
- **Radius scale**: a small set (for example none, 4, 8, 16, full) applied
consistently by component role
- **Elevation scale**: a fixed set of shadow or border treatments by layer
(flat, raised, overlay, modal); no per-component shadow values
- **Whitespace groups**: related items sit closer than unrelated items; the
spacing scale, not dividers, does most grouping

### Motion

- **Durations**: a short set by purpose (micro feedback ~100-150 ms,
transitions ~200-300 ms, large layout changes ~300-400 ms)
- **Easing**: enter decelerates, exit accelerates, movement uses a standard curve
- **Reduced motion**: every animation names its reduced-motion behaviour
(crossfade, instant, or none); a loop that conveys no state is removed
outright

### Iconography

- One icon set with one stroke weight and one corner treatment across the
product; icons carry an accessible name or are marked decorative

## Per-Screen Visual Rules

- One primary action per screen; secondary actions are visually subordinate
in weight, fill, or position
- Hover, focus, pressed, and disabled states are visibly distinct and on-style
for every interactive element
- Prefer wrapping to truncation; when text must truncate, use an ellipsis and
expose the full value on focus, hover, or expand
- Platform idioms hold: navigation, controls, and type follow the target
platform's conventions unless the design read gives a reason not to

## Handoff Checklist

- [ ] The design read is stated at the top of `design-system-mapping.md`
- [ ] Every token group above is present, either mapped to the existing design system or defined
- [ ] Every colour pair states its contrast ratio and both themes are covered
- [ ] Every value in the mockups resolves to a named token; none are ad-hoc
- [ ] Every animation names its duration, easing, and reduced-motion behaviour
- [ ] None of the defaults above appear without a reason traceable to the design read
4 changes: 3 additions & 1 deletion docs/reference/04-stages/inception.md
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,8 @@ This stage is typically skipped if Stage 1.6 (Rough Mockups) was also skipped.
disclosure)
- States each screen must handle (loading, empty, error, success, partial)
- Alignment with existing design system / component library
- Existing brand assets, design system, or aesthetic references, and the
audience (the inputs to the design read)
- Accessibility requirements (WCAG level)
- Responsive breakpoints needed
- For APIs: developer experience requirements
Expand Down Expand Up @@ -766,7 +768,7 @@ All artifacts written to `<record>/inception/refined-mockups/`:
|---------------------------------|-------------------------------------------------------------|
| `mockups.md` | Mid-to-high fidelity mockups per user story/screen |
| `interaction-spec.md` | Interaction patterns, state management, transitions |
| `design-system-mapping.md` | Component mapping to design system / component library |
| `design-system-mapping.md` | Design read, foundation token table, component mapping to design system / component library |
| `accessibility-checklist.md` | WCAG compliance checklist and requirements |
| `refined-mockups-questions.md` | Clarifying questions with `[Answer]:` tags (input artifact) |

Expand Down
1 change: 1 addition & 0 deletions docs/reference/agents/design-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Path: `.claude/knowledge/aidlc-design-agent/`
| component-spec-template.md | Template for documenting component specifications (states, props, behaviour) |
| interaction-design-patterns.md | Interaction patterns for navigation, forms, feedback, state transitions |
| ux-guide.md | UX design methodology and principles |
| visual-design-foundations.md | Design read, foundation token table (type, colour, space, shape, depth, motion, icons), and defaults to reach past |
| wireframing-guide.md | Wireframing techniques for low and high fidelity |

### Team (Tier 2)
Expand Down
8 changes: 4 additions & 4 deletions tests/unit/t15-knowledge-file-inventory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const AGENT_COUNTS: ReadonlyArray<readonly [string, number]> = [
["aidlc-compliance-agent", 1],
["aidlc-composer-agent", 1],
["aidlc-delivery-agent", 3],
["aidlc-design-agent", 5],
["aidlc-design-agent", 6],
["aidlc-developer-agent", 6],
["aidlc-devsecops-agent", 4],
["aidlc-operations-agent", 4],
Expand Down Expand Up @@ -154,10 +154,10 @@ describe("t15 — knowledge-file inventory + non-emptiness (mechanism: none)", (
// .sh L11-14: dynamic TAP plan = 11 + 11 + 7 + TOTAL_FILES. Re-derive that
// arithmetic from the live tree so the migrated suite cannot silently shrink
// the surface: pin the total .md count at 56 and the summed plan at 85.
test("TAP-plan parity: 14 + 14 + 7 + TOTAL == 94 with TOTAL == 59 [.sh L11-14]", () => {
test("TAP-plan parity: 14 + 14 + 7 + TOTAL == 95 with TOTAL == 60 [.sh L11-14]", () => {
const total = findMd(KNOWLEDGE_DIR).length;
expect(total).toBe(59);
expect(total).toBe(60);
const plan = 14 + 14 + 7 + total;
expect(plan).toBe(94);
expect(plan).toBe(95);
});
});
91 changes: 91 additions & 0 deletions tests/unit/t340-design-visual-foundations.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// covers: file:knowledge/aidlc-design-agent/visual-design-foundations.md,
// file:agents/aidlc-design-agent.md,
// file:aidlc-common/stages/inception/refined-mockups.md
//
// Pins the visual-direction contract of the design persona. The wireframing
// and UX guides settle structure (states, flows, WCAG); before this file
// nothing settled the visual layer, so typography, colour, and elevation were
// decided silently at code generation, outside the refined-mockups gate. The
// contract has three surfaces that must agree: the knowledge file that defines
// the design read and the foundation token table, the persona that owns
// stating them, and the stage that asks for their inputs and names them in
// the design-system mapping artifact.
//
// Mechanism = none: pure text invariants over authored files plus the shipped
// dist/claude projection of the persona and the knowledge file.
import { describe, expect, test } from "bun:test";
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { REPO_ROOT } from "../harness/fixtures.ts";

const core = (...p: string[]) => join(REPO_ROOT, "core", ...p);
const dist = (...p: string[]) => join(REPO_ROOT, "dist", "claude", ".claude", ...p);

const KNOWLEDGE = ["knowledge", "aidlc-design-agent", "visual-design-foundations.md"];
const PERSONA = ["agents", "aidlc-design-agent.md"];
const STAGE = core("aidlc-common", "stages", "inception", "refined-mockups.md");

const TOKEN_GROUPS = ["### Type", "### Colour", "### Space, Shape, and Depth", "### Motion", "### Iconography"];

describe("t340 design visual foundations pins", () => {
test("knowledge file defines the design read, the token groups, and the defaults list", () => {
const src = readFileSync(core(...KNOWLEDGE), "utf-8");
expect(src).toContain("## The Design Read");
expect(src).toContain("Reading this as:");
// The read is evidence-derived; an unsettled read is a question, not a guess.
expect(src).toContain("Existing assets win.");
expect(src).toContain("Quiet constraints override preference.");
expect(src).toContain("it is a clarifying question for");
expect(src).toContain("## Defaults to Reach Past");
expect(src).toContain("## Foundation Token Table");
for (const group of TOKEN_GROUPS) expect(src).toContain(group);
// Contrast is stated per pair, and both themes are defined together.
expect(src).toContain("4.5:1 for body text");
expect(src).toContain("Light and dark together");
expect(src).toContain("## Handoff Checklist");
expect((src.match(/^- \[ \] /gm) ?? []).length).toBeGreaterThanOrEqual(6);
});

test("knowledge file is harness-neutral prose and ships in dist/claude unchanged", () => {
const src = readFileSync(core(...KNOWLEDGE), "utf-8");
expect(src).not.toMatch(/\.(claude|kiro|codex|cursor|aidlc)\//);
expect(readFileSync(dist(...KNOWLEDGE), "utf-8")).toBe(src);
});

test("persona owns the visual direction and points at the knowledge file", () => {
const src = readFileSync(core(...PERSONA), "utf-8");
expect(src).toContain("### Visual Direction");
expect(src).toContain("State the design read");
expect(src).toContain("Define the foundation token table");
expect(src).toContain(
"`{{HARNESS_DIR}}/knowledge/aidlc-design-agent/visual-design-foundations.md`",
);
expect(src).toContain("7. **Read the audience before choosing a look**");
// Frontmatter is untouched: still judgment tier, still no nested delegation.
expect(src).toContain("tier: judgment");
expect(src).toContain("disallowedTools: Task");
});

test("dist/claude persona resolves the token to the Claude harness dir", () => {
const projected = readFileSync(dist(...PERSONA), "utf-8");
expect(projected).toContain("### Visual Direction");
expect(projected).toContain(
".claude/knowledge/aidlc-design-agent/visual-design-foundations.md",
);
expect(projected).not.toContain("{{HARNESS_DIR}}");
});

test("refined-mockups asks for the design-read inputs and names the token table in the mapping artifact", () => {
const src = readFileSync(STAGE, "utf-8");
expect(src).toContain(
"- What brand assets, design system, or aesthetic references already exist, and who is the audience (the inputs to the design read)?",
);
expect(src).toContain(
"design system mapping (opening with the design read and carrying the foundation token table from `{{HARNESS_DIR}}/knowledge/aidlc-design-agent/visual-design-foundations.md`)",
);
// The artifact contract itself did not change: same outputs line.
expect(src).toContain(
"outputs: mockups.md, interaction-spec.md, design-system-mapping.md, accessibility-checklist.md, refined-mockups-questions.md",
);
});
});