The Build
4 min read
The Build
Your CLAUDE.md is set, ADRs locked, design system in place. The build is driven by three slash commands that read your acceptance checklist and do the work — you never manually key what to build next. The checklist is the state. The commands read it and act.
How the build actually works
Three commands handle the entire build. Run them from any Claude Code session in your project:
- /build-next — reads the acceptance checklist, finds the first unchecked user story, builds it completely (views, viewmodel, data, error states, empty states, tests), ticks the ACs, commits, and tells you what to test manually. Run this repeatedly.
- /build-status — shows a progress table: every US, how many ACs are done, what's next. Run this anytime to see where you are.
- /build-polish — runs after ALL ACs are checked. Applies Liquid Glass, spring animations, haptics, and accessibility labels. Won't run if any ACs are still unchecked.
The cycle is: /build-next → test on Simulator → /build-next → test → repeat → /build-polish → /build-verify.
The commands were created by the Project Kickoff scaffold. If your project predates this guide, create them manually — content is in the section below.
Before you start building
Confirm you have these in place — the commands depend on all of them:
- docs/prd/prd.md — approved, with US-001 through US-00N fully written
- docs/prd/acceptance-checklist.md — all ACs listed as - [ ] AC-00X.Y: description
- docs/design-system/DESIGN-SYSTEM.md — design system generated
- [AppName]/Resources/DesignSystem.swift — DS constants exist
- CLAUDE.md — full Genesis Prompt version (not the placeholder)
- Phase 1 complete: nav shell builds and runs on Simulator
- Phase 2 complete: data layer + mock data in place
If you haven't done Phase 1 and Phase 2 yet, run those prompts from the Architecture and ADRs doc first — the build commands assume the navigation skeleton and SwiftData schema exist.
Phase 1: Navigation shell
Run this once before using /build-next. It creates the navigation skeleton every subsequent feature slots into.
Read CLAUDE.md, docs/prd/prd.md, and docs/design-system/DESIGN-SYSTEM.md.
Build the navigation shell for [App Name].
Create:1. Navigation structure from ADR-006 (TabView or NavigationStack — use what CLAUDE.md specifies) - Tab items with SF Symbols, labels from PRD feature names2. Placeholder views for each major screen from PRD UI/UX Requirements - Screen name as text, primary action as a disabled button — no logic yet3. DS.Color.background on all screen backgrounds, DS.Color.primary on nav tints4. Typography: .font(.body), .font(.headline) — no hardcoded sizes
Every view: @Observable ViewModel (even if empty) + #Preview {} at the bottom.Must compile and run on Simulator with no errors.Phase 2: Data layer
Run once after Phase 1. Creates the SwiftData schema and mock data so features have real models to work against.
Read CLAUDE.md and docs/prd/prd.md (Data Model section).
Build the data layer.
1. @Model classes for every entity in the PRD Data Model section - Exact field names and types from PRD - @Relationship for all relationships2. ModelContainer configured in [AppName]App.swift3. PreviewData.swift with realistic mock data for every @Model - Enough variety to make all screens look real in #Preview4. Update placeholder views to use @Query — show real mock content
Must compile and run. Previews should look like a real product.Running the build — /build-next
Once Phase 1 and Phase 2 are done, every subsequent feature comes from /build-next. Here is exactly what it does:
- Reads CLAUDE.md, PRD, acceptance checklist, design system, ADRs
- Finds the first user story with any unchecked AC in docs/prd/acceptance-checklist.md
- Reads all ACs for that US from the PRD
- Builds the complete feature: View, ViewModel, data wiring, error states, empty states, loading states
- Applies DS.Color., DS.Spacing., DS.Radius.* — never hardcoded values
- Writes unit tests for ViewModel state transitions
- Runs xcodebuild build and xcodebuild test — fixes all errors before continuing
- Updates acceptance-checklist.md: marks implemented ACs with [x]
- Commits with message feat: [US-00X] [description]
- Reports what was built, what to test manually on Simulator, and what's next
Blocked ACs (e.g. require physical device, backend not yet available) are left unchecked with a <!-- blocked: reason --> comment. /build-next skips blocked ACs and moves to the next implementable one.
Checking progress — /build-status
Run /build-status anytime. It produces a table like:
| User Story | Description | ACs Total | ACs Done | Status ||------------|--------------------|-----------|----------|-------------|| US-001 | Add item | 11 | 11 | ✅ Complete || US-002 | View item list | 7 | 3 | 🔄 Building || US-003 | Delete item | 5 | 0 | ⏳ Queued |...
Total: 45 ACs | Complete: 14 (31%) | Remaining: 31Next: run /build-next → will continue US-002Polish — /build-polish
Run /build-polish only after /build-status shows 100% complete. It will refuse to run if any ACs are still unchecked.
It applies in one pass:
- Liquid Glass (iOS 26+ gated): .glassEffect() on surfaces from DESIGN-SYSTEM.md, .ultraThinMaterial fallback
- Spring animations: DS.Animation.standard on all list/grid item appearances, DS.Animation.snappy on button presses
- Haptics: UIImpactFeedbackGenerator on primary actions, UINotificationFeedbackGenerator on success/error
- Accessibility: .accessibilityLabel() on every interactive element and meaningful image
- Dark mode audit: switches Simulator to dark mode, checks for hardcoded colours
- Dynamic Type audit: sets Simulator to largest text size, checks for clipped/overflowed text
What to do after /build-polish
With polish complete, go to the Test and Verify doc. Run the full test suite on iPhone SE and iPhone 16 Pro Max Simulators, then test on a physical device before TestFlight.
Creating the commands manually (if scaffold not run)
If your project was set up before the scaffold included these commands, create them yourself. In Claude Code:
Create three files in .claude/commands/:
1. build-next.md — the build controller2. build-status.md — progress tracker3. build-polish.md — polish pass
Content for each file is in the Jiffi iOS guide at:https://jiffi-lead-gen-portal.vercel.app/docs/ios-the-buildOr paste the full content from the "Command file content" section that follows — each is designed to be pasted as a Claude Code file creation prompt.
Command file: build-next.md
---description: Build the next user story from the acceptance checklist — one US at a time, all ACsallowed-tools: Read, Write, Bash---
You are the build controller. Build exactly ONE user story, completely, then stop.
## Step 1: Read project contextRead ALL of these before doing anything:- CLAUDE.md- docs/prd/prd.md- docs/prd/acceptance-checklist.md- docs/design-system/DESIGN-SYSTEM.md- docs/adr/README.md
## Step 2: Find next user storyFind the FIRST user story in docs/prd/acceptance-checklist.md with any unchecked items (- [ ]).If ALL items are checked: print "All complete — run /build-polish" and stop.
## Step 3: Build the complete user storyRead all ACs for this US from docs/prd/prd.md.
For each AC:- Happy path: implement the exact behaviour described- Error state: DS.Color.error + user-facing message- Edge case: handle the specific edge case- Empty state: SF Symbol + descriptive text, never blank
Create:- Features/[Name]/[Name]View.swift — SwiftUI view, uses @Query where needed, #Preview {} at bottom- Features/[Name]/[Name]ViewModel.swift — @Observable, @MainActor, all state and actions- New @Model classes in Core/Storage/ if PRD data model requires them- Wire into navigation per CLAUDE.md
Design system (enforce strictly):- DS.Color.* for all colours- DS.Spacing.* for all padding and margins- DS.Radius.* for all corner radii- DS.Animation.* for all transitions
## Step 4: TestsWrite @Test functions in [AppName]Tests/ for ViewModel state transitions and business logic.
## Step 5: Build and testxcodebuild build → fix all errorsxcodebuild test → fix all failuresBoth must pass before continuing.
## Step 6: Update checklistIn docs/prd/acceptance-checklist.md, mark implemented ACs:- [ ] AC-00X.Y → - [x] AC-00X.YIf an AC is blocked: leave unchecked, add: <!-- blocked: reason -->
## Step 7: Commitgit add -A && git commit -m "feat: [US-00X] [user story name]"
## Step 8: Report- User story built: US-00X- ACs checked: N of M- Blocked ACs: [if any]- Test manually: [what needs Simulator or device — haptics, camera, animations]- Next: /build-next will build [next US]Command file: build-status.md
---description: Show build progress — user stories, AC counts, what is nextallowed-tools: Read---
Read docs/prd/acceptance-checklist.md and docs/prd/prd.md.
Generate a progress report:
Print a table of every user story:| User Story | Description | ACs Total | ACs Done | Status |
Status: Complete (all checked) / In progress (some checked) / Queued (none checked)
Print summary:- Total ACs, complete count and percentage, remaining count- Blocked ACs with reasons- What to run next: /build-next (if ACs remain) or /build-polish (if all done)Command file: build-polish.md
---description: Polish pass — Liquid Glass, animations, haptics, accessibility — run after all ACs checkedallowed-tools: Read, Write, Bash---
Read docs/prd/acceptance-checklist.md.Count unchecked items (- [ ]).If ANY exist: print "N ACs unchecked. Run /build-next first." and stop.
Read CLAUDE.md and docs/design-system/DESIGN-SYSTEM.md.
Apply in order:
1. Liquid Glass (surfaces from DESIGN-SYSTEM.md only) Each use: if #available(iOS 26, *) { .glassEffect() } else { .background(.ultraThinMaterial) }
2. Spring animations (DS.Animation.*) - List/grid items appearing: .animation(DS.Animation.standard, value: trigger) - Button press: .scaleEffect(pressed ? 0.96 : 1.0).animation(DS.Animation.snappy, value: pressed) - Modals/sheets: .animation(DS.Animation.expressive) on content inside
3. Haptics - Primary action taps: UIImpactFeedbackGenerator(.medium).impactOccurred() - Success: UINotificationFeedbackGenerator().notificationOccurred(.success) - Error: UINotificationFeedbackGenerator().notificationOccurred(.error) - Destructive action: UINotificationFeedbackGenerator().notificationOccurred(.warning)
4. Accessibility - Every Button: .accessibilityLabel("Verb + what") - Every meaningful image: .accessibilityLabel("description") - Every decorative image: .accessibilityHidden(true) - Every TextField: .accessibilityLabel + .accessibilityHint if not obvious
5. Dark mode audit (switch Simulator to dark mode) All colours use DS.Color.* — should adapt automatically. Report any hardcoded colours found.
6. Dynamic Type audit (set Simulator to largest accessibility text) All text uses .font(.body) etc — should scale automatically. Fix any .frame(height:) that clips text.
xcodebuild build → fix errorsxcodebuild test → fix failures
git add -A && git commit -m "feat: polish pass — glass, animations, haptics, accessibility"
Report: surfaces, animations, haptics, accessibility labels applied. Dark mode and Dynamic Type issues fixed.Ready for: Test and Verify doc.Sign up to read the full guide
Free access to all 12 workflow guides. No password needed.