Advice report on how to structure feature documentation so that any team member or AI agent can understand, contribute to, and implement features consistently.
Our current feature notes are a wall of mixed information — functional descriptions, technical details, file paths, and color codes all crammed into one paragraph. This makes it:
Stripe documents features as "strategy memos" that focus on the why before the what. Engineers, PMs, and partnerships all write documents. The emphasis is on getting to the right answer through writing.
Every feature starts with 5 ingredients: Problem, Appetite (how much time we're willing to spend), Solution, Rabbit Holes (risks to call out), and No-Gos (what we're explicitly not building). Problem and solution are always presented together.
Linear keeps documentation lean. The team collectively thinks about the product. Documentation exists to communicate, not to satisfy a process.
The best teams separate problem from solution, document what they're NOT building, and tailor information to the audience reading it.
Every feature in SynergyPlan gets a structured document with distinct layers. Each layer serves a different audience and can be filled independently by different agents or team members without overwriting each other.
┌─────────────────────────────────────┐
│ 1. CONTEXT (Everyone) │ Why does this feature exist?
├─────────────────────────────────────┤
│ 2. FUNCTIONAL (PM / User) │ What does it do? (ELI18)
├─────────────────────────────────────┤
│ 3. UX & DESIGN (Designer) │ What does it look/feel like?
├─────────────────────────────────────┤
│ 4. TECHNICAL (Developer) │ How is it built?
├─────────────────────────────────────┤
│ 5. STATUS (Everyone) │ Where are we now?
└─────────────────────────────────────┘
Answers: Why does this feature exist? What problem does it solve?
## Context
**Problem:** Users can't quickly find specific verses when searching, because results
are displayed as a flat list with no visual hierarchy.
**Solution:** Group search results by book with headers and counts, so users can
quickly scan which books contain matches and jump to the relevant section.
**Not included:** Full-text preview of surrounding verses. That's a separate feature.
Rules:
Answers: What does the user experience? Explain it like I'm 18.
## Functional
When you search for a word, the results appear grouped under book headers (e.g., "Genesis — 12 results", "Psalms — 8 results"). Each group can be collapsed or expanded. The total result count shows at the top.
**User flow:**
1. User types a search query
2. Results load, grouped by book in biblical order
3. Each book header shows the book name and match count
4. User clicks a header to collapse/expand that group
5. User clicks a result to navigate to that verse
**Edge cases:**
- If all results are in one book, the header still shows (no special case)
- Empty search shows nothing (no "search for something" prompt needed)
Rules:
Answers: What does it look and feel like?
## UX & Design
**Visual:**
- Book headers: bold, 14px, with result count in gray to the right
- Results indented under headers with left border (2px, --color-accent)
- Collapse/expand: chevron icon rotates 90°
**Colors:**
- Header text: var(--color-text-primary)
- Result count: var(--color-text-secondary)
- Left border: var(--color-accent) (#7dd3fc)
**Responsive:**
- Desktop: full-width results
- Mobile: same layout, touch-friendly headers (min-height 44px)
**Animations:**
- Collapse: 200ms ease-out height transition
- No animation on initial load
**Screenshots:**

Rules:
Answers: How is it built? What do I need to know to implement or modify this?
## Technical
**Data:**
- Query: `searchVerses()` in `apps/web/src/lib/server/queries/search.ts`
- Results include `book_id` — group by this field client-side
- Book names from `BOOK_NAMES` constant in `bible-constants.ts`
**Components:**
- `SearchResults.svelte` — main results container
- `SearchResultGroup.svelte` — collapsible book group (new component)
**API:**
- `GET /api/search?q=term&lang=en` — returns flat array, client groups
**Dependencies:**
- No new dependencies needed
- Reuses existing `ChevronIcon` component
**Files:**
- `apps/web/src/routes/(app)/search/+page.svelte` (modify)
- `apps/web/src/lib/components/search/SearchResultGroup.svelte` (create)
Rules:
Answers: Where are we right now?
## Status
**Current:** PLANNED
**Milestone:** v1
**Priority:** High — blocks search usability for launch
**History:**
- Existed in BibleGame desktop app (SearchView.cs — grouped results with book headers)
- Not yet ported to web
**Dependencies:**
- Requires: search API (DONE)
- Blocks: nothing
Rules:
Each feature's documentation lives in a single markdown file at:
projects/[project]/features/[feature-slug]/README.md
The file uses the 5 layers as ## headings. This means:
## section without touching othersAdditional files in the same folder:
projects/[project]/features/[feature-slug]/
├── README.md # The 5-layer documentation
├── screenshot.png # Current state (for DONE features)
├── mockup.png # Design concept (for PLANNED features)
├── before.png # What it looked like in BibleGame
└── notes.md # Freeform notes, meeting minutes, decisions
When an AI agent fills in feature documentation:
Never overwrite other layers. Each layer is independent. If you're filling in the Technical layer, don't touch Functional or UX.
Use the exact headings. ## Context, ## Functional, ## UX & Design, ## Technical, ## Status. Agents search for these headings to find their section.
One agent per layer. Don't have one agent fill everything. Let specialized agents handle their expertise:
Screenshots must match reality. If the feature is DONE, the screenshot must show the actual current UI in the correct language and theme. Never use generated/fake screenshots.
Don't invent information. If you don't know something, leave the section empty with a > TODO: [what's needed] note. Wrong information is worse than missing information.
Keep Context and Functional jargon-free. A non-technical team member must be able to read these layers and fully understand what the feature does and why it exists.
This standard draws from: