Skip to content
Merged
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ next-env.d.ts

# os
.DS_Store

# vendored skills (local-machine symlink, not portable)
.claude/skills
.agents/skills
32 changes: 12 additions & 20 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,31 @@
# AGENTS.md

Guidance for AI coding agents working in this repository: Kindred (working name), a compatibility app where a member fills out a self-questionnaire, connects friends, and reveals how compatible they are with each. Interaction patterns are modeled on [222.place](https://222.place); the product direction and design are our own. What the app is lives in [README.md](README.md); the rules and requirements live in `docs/`.
Guidance for AI coding agents working in this repository: Kindred (working name), a compatibility app where a member fills out a self-questionnaire, connects friends, and reveals how compatible they are with each. Interaction patterns are modeled on [222.place](https://222.place); the product direction and design are our own. What the app is lives in [README.md](README.md); house standards are vendored as skills (`.claude/skills/`, `.agents/skills/`); the rules and requirements live in `docs/`.

## Read first, in order

@README.md
@docs/01-standards/process.md
@docs/01-standards/writing.md
@docs/01-standards/nextjs.md
@docs/01-standards/components.md
@docs/01-standards/data.md
@docs/02-prd/01-brief.md
@docs/02-prd/02-design-system.md
@docs/02-prd/06-matching.md
@docs/02-prd/07-architecture.md

The remaining standards ([testing](docs/01-standards/testing.md), [performance](docs/01-standards/performance.md), [accessibility](docs/01-standards/accessibility.md), [seo](docs/01-standards/seo.md), [git](docs/01-standards/git.md)) and the per-surface PRD docs ([profile](docs/02-prd/03-profile.md), [compatibility](docs/02-prd/04-compatibility.md), [add-friends](docs/02-prd/05-add-friends.md)) are read just in time.
@docs/prd/01-brief.md
@docs/prd/02-design-system.md
@docs/prd/06-matching.md
@docs/prd/07-architecture.md

The per-surface PRD docs ([profile](docs/prd/03-profile.md), [compatibility](docs/prd/04-compatibility.md), [add-friends](docs/prd/05-add-friends.md)) are read just in time.

## Decision framework

When a choice is not settled by this repo's own code, README, or an obvious default, apply [harness-engineering](https://github.com/tkodev/harness-engineering) as the decision maker: read the target's local truth first, name the one unresolved decision, route to the single relevant thesis, and let this repo's contracts govern over any imported guidance. Do not preload the corpus; follow its links just in time.
See the `decisions` skill for when and how to consult harness-engineering.

## Stack

pnpm 11 (never npm or yarn), Node >= 24, TypeScript strict, Next.js 16 App Router, Tailwind v4 (CSS-first `@theme`, no `tailwind.config`), CVA with `cn()` = `twMerge(clsx(...))`, shadcn/Radix primitives, `lucide-react`, `date-fns`, Vitest. The data layer is **oRPC**: user-specific data (profile, friends, compatibility reveals) flows through typed procedures in `src/server/`, validated with zod; seed data lives in `constants/`. Persistence targets Postgres via `docker compose` ([docs/02-prd/07-architecture.md](docs/02-prd/07-architecture.md)); procedures read seed constants until it lands, and the seed is the data contract.
pnpm 11 (never npm or yarn), Node >= 24, TypeScript strict, Next.js 16 App Router, Tailwind v4 (CSS-first `@theme`, no `tailwind.config`), CVA with `cn()` = `twMerge(clsx(...))`, shadcn/Radix primitives, `lucide-react`, `date-fns`, Vitest. The data layer is **oRPC**: user-specific data (profile, friends, compatibility reveals) flows through typed procedures in `src/server/`, validated with zod; seed data lives in `constants/`. Persistence targets Postgres via `docker compose` ([docs/prd/07-architecture.md](docs/prd/07-architecture.md)); procedures read seed constants until it lands, and the seed is the data contract.

## House rules

These come from `docs/01-standards/` (the tkodev standards); the load-bearing ones:
Component shape, CVA/styling, atomic-design layout, and server-components-by-default are covered by the vendored `components` and `nextjs` skills. Project-specific data-layer rules that aren't generic:

1. **Component shape.** Every component is a single `styles` object of `cva()` calls on top, then `XxxRef` / `XxxProps` types, then the component; named exports only, no default exports. Props destructure, then hooks, then render vars, then jsx composed with `cn()`.
2. **Styling.** CVA for all visual variants, never ad-hoc className conditionals. Semantic tokens only: no raw hex, no palette utilities (`text-zinc-400`), no arbitrary sizes. Layout utilities (`w-full`, margins, grid placement) live at the call site; color, radius, type, borders live in the CVA.
3. **Atomic design.** Components live under `components/` as `atoms/` (buttons, badges), `molecules/` (cards, forms), `organisms/` (dialogs, menus), `templates/` (header, footer, layout, section). shadcn CLI imports land in `atoms/` and are reformatted to the house shape on arrival.
4. **Data discipline.** Dynamic, user-specific data goes through oRPC procedures, typed by `types/`. Static content lives in `constants/`, never inline in components. Keep client state local (`useState`, URL params); no speculative global state. Dates zone through `date-fns-tz`, never bare `new Date()`.
5. **Server components by default.** `'use client'` only where state or browser APIs demand it, and as low in the tree as possible.
1. **oRPC boundary.** Dynamic, user-specific data (profile, friends, compatibility reveals) goes through typed oRPC procedures in `src/server/`, validated with zod, typed by `types/`. Static content lives in `constants/`, never inline in components; the seed data in `constants/` is the data contract until Postgres lands.
2. **Matching model status.** Compatibility scores are still authored seed data — the matching model is designed, not yet computed (see [docs/prd/06-matching.md](docs/prd/06-matching.md)).

## Working discipline

Expand Down
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A compatibility app for the people already in your life. You fill out a questionnaire about yourself, connect your friends, and reveal how compatible you are with each of them across the dimensions that actually predict a good relationship. Built for adults in their 30s and 40s who want depth over volume: close friendships first, dating where it fits.

**Status: working prototype.** Every surface renders end to end over a typed oRPC layer. Username-only sign-in and profile editing persist to Postgres, with an in-memory fallback so the app runs without Docker. Compatibility scores are still authored seed data (the matching model in [docs/02-prd/06-matching.md](docs/02-prd/06-matching.md) is designed, not yet computed). `Kindred` is a working name.
**Status: working prototype.** Every surface renders end to end over a typed oRPC layer. Username-only sign-in and profile editing persist to Postgres, with an in-memory fallback so the app runs without Docker. Compatibility scores are still authored seed data (the matching model in [docs/prd/06-matching.md](docs/prd/06-matching.md) is designed, not yet computed). `Kindred` is a working name.

> The compatibility and questionnaire interaction patterns are modeled on [222.place](https://222.place); the color language and product direction are our own.

Expand All @@ -28,7 +28,7 @@ A compatibility app for the people already in your life. You fill out a question
| Styling | Tailwind v4 (`@theme`), CVA with `cn()`, an editorial serif over Geist |
| Testing | Vitest |

The authoritative stack, data-layer, and seed-to-Postgres notes are [docs/02-prd/07-architecture.md](docs/02-prd/07-architecture.md).
The authoritative stack, data-layer, and seed-to-Postgres notes are [docs/prd/07-architecture.md](docs/prd/07-architecture.md).

## Getting started

Expand All @@ -51,9 +51,10 @@ Without `DATABASE_URL` set (or if the database is unreachable) the app runs agai
.
├── AGENTS.md # agent orientation (CLAUDE.md symlinks here)
├── docker-compose.yml # Postgres 16 for the persistence target
├── .claude/skills/ # vendored house-standard skills (symlink)
├── .agents/skills/ # same skills, agent-agnostic path (symlink)
├── docs/
│ ├── 01-standards/ # house rules by topic (from boilerplate-web)
│ └── 02-prd/ # the numbered product docs, read in order
│ └── prd/ # the numbered product docs, read in order
└── src/
├── app/ # routes: /, /profile, /friends, /friends/[id], /friends/add, /rpc
├── components/ # atoms · molecules · organisms · templates
Expand All @@ -66,16 +67,16 @@ Without `DATABASE_URL` set (or if the database is unreachable) the app runs agai

## Docs

Docs drive the implementation, read in order. The rules ([docs/01-standards/](docs/01-standards/)) are the house standards; the PRD ([docs/02-prd/](docs/02-prd/)) is the product pipeline.
House standards (component shape, data discipline, Next.js conventions, accessibility, performance, testing, seo, git, writing, process) are vendored as skills, symlinked at `.claude/skills/` and `.agents/skills/`. The PRD ([docs/prd/](docs/prd/)) is the product pipeline:

| Doc | Owns |
| --- | --- |
| [01-brief](docs/02-prd/01-brief.md) | What Kindred is, the audience, the aesthetic |
| [02-design-system](docs/02-prd/02-design-system.md) | Color, type, and the component inventory |
| [03-profile](docs/02-prd/03-profile.md) | The self-questionnaire surface |
| [04-compatibility](docs/02-prd/04-compatibility.md) | The friends list and reveal |
| [05-add-friends](docs/02-prd/05-add-friends.md) | The add-friends surface (our own, not in the source) |
| [06-matching](docs/02-prd/06-matching.md) | Preliminary compatibility-scoring model |
| [07-architecture](docs/02-prd/07-architecture.md) | Stack, oRPC data layer, seed-to-Postgres path |
| [01-brief](docs/prd/01-brief.md) | What Kindred is, the audience, the aesthetic |
| [02-design-system](docs/prd/02-design-system.md) | Color, type, and the component inventory |
| [03-profile](docs/prd/03-profile.md) | The self-questionnaire surface |
| [04-compatibility](docs/prd/04-compatibility.md) | The friends list and reveal |
| [05-add-friends](docs/prd/05-add-friends.md) | The add-friends surface (our own, not in the source) |
| [06-matching](docs/prd/06-matching.md) | Preliminary compatibility-scoring model |
| [07-architecture](docs/prd/07-architecture.md) | Stack, oRPC data layer, seed-to-Postgres path |

For AI-agent orientation see [AGENTS.md](AGENTS.md); `CLAUDE.md` symlinks to it.
9 changes: 0 additions & 9 deletions docs/01-standards/accessibility.md

This file was deleted.

81 changes: 0 additions & 81 deletions docs/01-standards/components.md

This file was deleted.

10 changes: 0 additions & 10 deletions docs/01-standards/data.md

This file was deleted.

42 changes: 0 additions & 42 deletions docs/01-standards/git.md

This file was deleted.

Loading
Loading