Captures the design from the brainstorm session on agent-first development in this template. Architecture doc covers the four interlocking pillars: - Conformance engine (manifest + brands + ESLint + boot + CI gate) - Agent workflow (PRD -> Epic -> Story -> Task; manifest-first ordering; TDD per slice; in/out scope at every level) - Local task system at docs/work/ (filesystem markdown, derived committed _state.json, single-writer orchestrator rule) - Sandcastle orchestrator (implementer + reviewer loop, DAG-respecting, configurable retry cap) Work-shape guides extend the architecture doc with operational detail for frontend work (atomic design, Storybook-as-spec, component + Playwright screenshot test gates, Storybook MCP reviewer integration) and infrastructure work (ADR-first flow, dedicated ADR elicitation skill, optional core packages vs. new infrastructure layers). Phasing is conformance-first: build the enforcement system manually, then build the dispatch substrate, then migrate remaining features through it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.0 KiB
Frontend work shape
How frontend work — components, pages, media UI, anything visual — flows through the agent-first workflow. For the broader workflow context see docs/architecture/agent-first-workflow-and-conformance.md.
When this guide applies
You're working on:
- A new or existing component (atom / molecule / organism / template / page)
- A page in
apps/web-nextorapps/web-tanstack - A visual or interactive change in
@repo/core-uiorfeatures/<feature>/src/ui/ - Storybook stories or visual regression tests
If you're working on a backend use case (factory, repository, manifest entry, event handler, job, realtime channel), use the default backend shape documented in the architecture doc — not this guide.
Where frontend code lives
| Surface | Location | When to use |
|---|---|---|
| Atomic-design primitives | @repo/core-ui/src/{atoms,molecules,organisms,templates}/ |
Cross-feature reusables. Generated via pnpm turbo gen core-ui-component. |
| Feature-scoped UI | features/<feature>/src/ui/ |
Components and queries specific to a feature. Exported behind the feature's ./ui subpath, never the root barrel (see CLAUDE.md). |
| Pages | apps/<app>/src/... (Next.js: app/, TanStack: routes/) |
Page-level composition. Calls use cases via tRPC controllers; composes components. |
Atomic design conventions
Tier rules (enforced by the atomic-tier-import-direction ESLint rule):
| Tier | May import from | May NOT import from |
|---|---|---|
atoms |
nothing else in core-ui |
molecules / organisms / templates / pages / features |
molecules |
atoms | organisms / templates / pages / features |
organisms |
atoms, molecules | templates / pages / features |
templates |
atoms, molecules, organisms | pages / features |
pages |
all of the above | other pages |
Feature-scoped UI (features/<feature>/src/ui/) follows the same tier order internally, and may import from @repo/core-ui at any tier.
Storybook is the spec
Every component has a sibling .stories.tsx. The story file:
- Declares one story per AC bullet (or one variant per AC bullet)
- Uses Storybook's
playfunction for interaction tests where applicable - Becomes the shared visual contract between human, implementer agent, reviewer agent
Acceptance criteria for a frontend task map directly to story variants:
## Acceptance criteria
- [ ] Renders default variant
- [ ] Renders loading state
- [ ] Renders error state with `message` slot
- [ ] Renders disabled state
- [ ] Click handler fires with event payload
Each bullet becomes one Story export (or one play step on a story).
Test gates
| Gate | What it covers | Tool | Latency | When it runs |
|---|---|---|---|---|
| Component test | behavior, props, interactions | Vitest + Testing Library, or play on stories |
<5s | pre-commit, CI |
| Visual regression | rendered appearance vs. baseline | Playwright screenshot tests | 30–120s | CI only; blocks merge on unapproved diffs |
The visual regression infrastructure ships as part of the work-system-v1 epic. Until it's in place, frontend work relies on component tests + manual visual review.
Adapted four-step ordering
For a pure UI slice (no backend coupling):
- Story file — write or extend
.stories.tsx; declare the variant for this slice's AC bullet. This is the visual spec — analogous to the manifest entry for backend work. - Contracts — props interface in the component file (factory body / render body may still throw
not implemented) - Tests (red) — component test + the new story (the rendered output is asserted as part of the visual regression baseline, or via Testing Library)
- Implementation (green) — render JSX, wire interactions, satisfy AC
For a UI slice that consumes a backend use case (e.g. a form component calling auth.signUp), the use case lives in a separate story with its own four steps; the UI story depends-on the use-case story.
Reviewer integration
The reviewer agent for frontend tasks uses two extra inputs beyond the standard diff:
- Storybook MCP at
http://localhost:6006/mcp— query existing components, list variants, fetch the metadata for stories that already exist. The reviewer canlist-all-documentationto verify no duplicate component was created. - Playwright screenshot CI verdict — the visual diff status from CI. Unapproved diffs trigger
rejectregardless of code quality.
Reviewer checklist for frontend tasks:
- Every AC bullet has a matching story or
playstep - No accidental cross-tier imports (lint already catches this, but verify)
- Component test exercises each AC bullet
- Visual regression diff is either zero or human-approved
- No new component created without checking for an existing equivalent via Storybook MCP
Story split for page-level features
A user-facing feature like "sign up" decomposes into multiple stories under one epic:
Epic: auth-v1
├── Story (user-story): auth.signUp use case
├── Story (technical-story): SignUpForm component
│ depends-on: signUp use case
└── Story (technical-story): /sign-up page
depends-on: SignUpForm
Each story has its own AC checklist; the depends-on edges enforce sequential dispatch by the orchestrator. The page story typically includes the Playwright E2E test for the full flow.
Conformance for frontend
New ESLint rules added under the frontend work-shape:
component-must-have-story— every.tsxfile exporting a default OR named React component must have a sibling.stories.tsxcomponent-must-have-test— every component must have a sibling.test.tsx(or be covered by aplayfunction on its story)atomic-tier-import-direction— tier imports must respect the table abovestory-must-cover-all-prop-variants(advisory) — discriminated-union props should have a story per variant
Common pitfalls
- Stale stories. A component changes prop shape; stories don't get updated. The
component-must-have-storyrule catches missing stories but not stale ones. Reviewer should flag this; visual regression catches the rendered consequence. - Visual-only changes without story update. A CSS tweak that doesn't change behavior still needs the story to be re-snapshotted. Treat the visual regression diff approval as part of the slice.
- Cross-tier creep. Tempting to import an organism from inside an atom for "convenience". The lint rule blocks it; refactor the shared bit down to an atom or molecule.
- Duplicate components. An agent creates a
Buttonin a feature'sui/atoms/when one already exists incore-ui. Reviewer queries Storybook MCP forButtonbefore approval; if duplicated, rejects.
Open items (filled in as we ship)
- Playwright screenshot infrastructure — exact setup, baseline storage, approval flow
- Visual regression PR check — GitHub workflow + diff hosting
- Storybook test integration (
test:stories) — current status and what we extend