diff --git a/.gitignore b/.gitignore index dd14ff8..9fea69a 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,7 @@ next-env.d.ts # os .DS_Store + +# vendored skills (local-machine symlink, not portable) +.claude/skills +.agents/skills diff --git a/AGENTS.md b/AGENTS.md index 154d8bc..3f1c97a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,19 +5,11 @@ Guidance for AI coding agents working in this repository: tkodev-web-v5, the v5 ## 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/01-standards/testing.md -@docs/01-standards/performance.md -@docs/01-standards/accessibility.md -@docs/01-standards/seo.md -@docs/01-standards/git.md -@docs/02-prd/01-brief.md -@docs/02-prd/02-observations.md -@docs/02-prd/03-solution.md -@docs/02-prd/04-design.md -@docs/02-prd/05-architecture.md -@docs/02-prd/06-plan.md +@docs/prd/01-brief.md +@docs/prd/02-observations.md +@docs/prd/03-solution.md +@docs/prd/04-design.md +@docs/prd/05-architecture.md +@docs/prd/06-plan.md + +Standards (process, writing, nextjs, components, data, testing, performance, accessibility, seo, git) are supplied by the vendored skills under `.claude/skills/` and `.agents/skills/` and load automatically via skill discovery — no explicit import needed here. diff --git a/README.md b/README.md index e5ae1cf..7f4bf05 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ The v5 redesign of [tko.dev](https://tko.dev/): Tony Ko's **futuristic personal ## Tech stack -Next.js App Router on Tailwind v4, with shadcn/Radix primitives, CVA variants, Framer Motion choreography, and Vitest; the authoritative stack table (versions included) is [docs/02-prd/05-architecture.md §Stack](docs/02-prd/05-architecture.md). +Next.js App Router on Tailwind v4, with shadcn/Radix primitives, CVA variants, Framer Motion choreography, and Vitest; the authoritative stack table (versions included) is [docs/prd/05-architecture.md §Stack](docs/prd/05-architecture.md). ## Getting started @@ -30,17 +30,16 @@ pnpm test # vitest ## Docs -Docs drive the implementation, read in numbered order: the rules ([docs/01-standards/](docs/01-standards/)) split by topic, then the PRD ([docs/02-prd/](docs/02-prd/)) as a numbered pipeline ending in the plan (the live milestone list): +Rules by topic (process, writing, nextjs, components, data, testing, performance, accessibility, seo, git) are vendored as skills under `.claude/skills/` and `.agents/skills/`, symlinked from the shared [harness-skills](https://github.com/tkodev/harness-skills) library and loaded automatically via skill discovery. The PRD ([docs/prd/](docs/prd/)) is a numbered pipeline ending in the plan (the live milestone list): | Doc | What it owns | | --- | --- | -| [docs/01-standards/](docs/01-standards/) | Rules by topic: [process](docs/01-standards/process.md), [writing](docs/01-standards/writing.md), [nextjs](docs/01-standards/nextjs.md), [components](docs/01-standards/components.md), [data](docs/01-standards/data.md), [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) | -| [docs/02-prd/01-brief.md](docs/02-prd/01-brief.md) | The distilled intent: what the site is, who it's for, aesthetic, references | -| [docs/02-prd/02-observations.md](docs/02-prd/02-observations.md) | Research, risks, and the direction taken on each | -| [docs/02-prd/03-solution.md](docs/02-prd/03-solution.md) | The settled design: concept, surfaces, motion system | -| [docs/02-prd/04-design.md](docs/02-prd/04-design.md) | Design tokens (typography, color, radius, gap, fonts) | -| [docs/02-prd/05-architecture.md](docs/02-prd/05-architecture.md) | Stack, information architecture, repo structure, data layer, theming | -| [docs/02-prd/06-plan.md](docs/02-prd/06-plan.md) | The plan: the live milestone list (dependencies, status, scope) | +| [docs/prd/01-brief.md](docs/prd/01-brief.md) | The distilled intent: what the site is, who it's for, aesthetic, references | +| [docs/prd/02-observations.md](docs/prd/02-observations.md) | Research, risks, and the direction taken on each | +| [docs/prd/03-solution.md](docs/prd/03-solution.md) | The settled design: concept, surfaces, motion system | +| [docs/prd/04-design.md](docs/prd/04-design.md) | Design tokens (typography, color, radius, gap, fonts) | +| [docs/prd/05-architecture.md](docs/prd/05-architecture.md) | Stack, information architecture, repo structure, data layer, theming | +| [docs/prd/06-plan.md](docs/prd/06-plan.md) | The plan: the live milestone list (dependencies, status, scope) | ## Other diff --git a/docs/01-standards/accessibility.md b/docs/01-standards/accessibility.md deleted file mode 100644 index eb2dce7..0000000 --- a/docs/01-standards/accessibility.md +++ /dev/null @@ -1,9 +0,0 @@ -# Accessibility - -The floor, not a cleanup pass. - -1. **WCAG 2.0 AA (AODA) is the baseline:** semantic landmarks (`header`/`main`/`footer`/`nav`/`section`), one `h1` per page, accordion and nav keyboard-operable with correct ARIA, focus trapped in the nav overlay while open, visible `ring` focus states, decorative art `aria-hidden`. -2. **Respect `prefers-reduced-motion`**: ambient and entrance animations pause or reduce; every motion moment has a static equivalent, and nothing is readable only through motion. -3. **Contrast is checked in every theme scope**: AA contrast for text tokens (`muted-foreground` on `background` included) in the base theme and inside any inverse-color section. -4. **Self-starting motion carries a control**: anything that begins moving on its own and runs past a few seconds (the marquee drift) pairs with a keyboard-operable pause. A hover pause is not one: it reaches neither keyboard nor touch, and the reduced-motion path only serves the readers who set the preference. -5. **Each landmark of a kind is named**: a page with more than one `nav` labels each (`Primary`, `Footer`, `Menu`), since an unnamed pair is indistinguishable to the reader listing them. The name is passed at the call site, never baked into the component. diff --git a/docs/01-standards/components.md b/docs/01-standards/components.md deleted file mode 100644 index 0663000..0000000 --- a/docs/01-standards/components.md +++ /dev/null @@ -1,81 +0,0 @@ -# Components - -How components are added, shaped, styled, and organized. This file owns the authoring and styling rules; what components exist and what they look like is the design contract's concern, not this file's. - -## The flow: shadcn first - -1. **Check shadcn before writing anything.** Primitives use shadcn, which uses Radix primitives underneath. Adding a new component starts with a check of the shadcn library: if it exists there, import it with the CLI (`pnpm dlx shadcn@latest add `), then **reformat it to the house shape below and re-theme it with the v5 tokens**. -2. **Custom components use the identical shape.** If shadcn doesn't have it (or the design calls for something bespoke), author it from scratch in exactly the same format; the only difference is there's nothing to import. - -## The file shape - -1. **Every component follows this example skeleton:** - - ```tsx - import { forwardRef, type HTMLAttributes } from 'react' - import { cn, cva, VariantProps } from '@/utils/theme' - - const styles = { - root: cva('…', { variants: { … }, defaultVariants: { … } }) - } - - type ExampleRef = HTMLDivElement - type ExampleProps = HTMLAttributes & VariantProps - - const Example = forwardRef((props, ref) => { - // props - const { className, ...rest } = props - - // hooks - - // render vars - - // jsx - return
- }) - Example.displayName = 'Example' - - export { Example } - export type { ExampleProps, ExampleRef } - ``` - - Order within the file: **CVA styles/constants on top → types (`XxxRef`, `XxxProps`) → component.** Order within the function body, each under its comment: **props** destructure → **hooks** → **render vars** → **jsx** (composed with `cn()`). -2. **Named exports only**: the component plus its `Props` and `Ref` types; `displayName` set on `forwardRef` components. No default exports. - -## Styling - -1. **CVA for all visual variants.** Each component defines a local `styles` object of `cva()` calls; never ad-hoc conditional className logic at call sites. -2. **`cn()` for all className composition**: `twMerge(clsx(...))` from `utils/theme.ts`, which also re-exports `cva` and `VariantProps` so components have one import point. -3. **Layout utilities at the call site, visual styles in the CVA.** `w-full`, grid placement, margins come from the parent; color, radius, type, borders live in the component's variants. -4. **Semantic tokens only.** No raw hex, no palette utilities (`text-zinc-400`), no arbitrary color values in JSX. Backgrounds pair with their foregrounds (`bg-primary` → `text-primary-foreground`). -5. **Type comes from the ramps.** Use the heading/expressive/body typography utilities defined by the design tokens: no arbitrary `text-[13px]`. Uppercase is CSS `uppercase`; content is written in normal case. -6. **Tailwind v4 CSS-first.** All theme extension in `themes/theme.css` `@theme`; no `tailwind.config.ts`. -7. **`asChild` + Radix `Slot`** when a component delegates rendering (``); never nest interactive elements. - -## Organization: atomic design - -1. Components live in `components/` in an atomic-design structure: - - `atoms/`: simple components. E.g. a button, a badge, the wordmark. - - `molecules/`: collections of atoms. E.g. a search bar, a date picker, an accordion, a project card. - - `organisms/`: collections of atoms/molecules. E.g. a page block, a dialog, a menu, an overlay. - - `templates/`: layout-focused things: footer, header, layout, main, section. -2. shadcn CLI imports land in `atoms/` (the `components.json` `ui` alias points there) and are reformatted on arrival. - -## Layout shell - -1. **One persistent shell wraps every page**, composed from `templates/`: - - ```text - layout - ├── underlays # site-wide background layers (e.g. custom webgl backgrounds) - ├── header # top bar: identity + nav links - ├── main # page content, sections in flow - ├── footer # bottom bar: copyright, quick links - └── overlays # takeover layers (e.g. loading screen, nav overlay) - ``` - -2. **Pages are stacks of `section` shells.** Every section renders through the `section` template: a full-bleed wrapper with a centered inner container in one of three widths (`lg` / `md` / `sm`, values set by the design tokens), never ad-hoc page-level wrappers. - -## Reusability - -1. **All components are reusable by construction.** Content is passed in via props or children, never defined inside a component. Content is defined in `constants/`, API calls, or pages (the consuming layer) only. A component with a hardcoded heading is a bug. diff --git a/docs/01-standards/data.md b/docs/01-standards/data.md deleted file mode 100644 index 6883694..0000000 --- a/docs/01-standards/data.md +++ /dev/null @@ -1,10 +0,0 @@ -# Data and content - -Where content lives, how it's typed, and how state is managed. - -1. **All content in `constants/`.** No inline copy or data in components; no external content APIs. Copy is grounded in real career facts, never invented. -2. **`constants/` is the source of truth.** It owns the site's career data outright. The career-notes package (`ops/notes/tkodev/career-notes/profiles/linkedin`) seeded the initial types and constants and stays a reference for facts not yet captured here. -3. **State discipline.** Keep state local: `useState` and URL params for the ephemeral. No speculative global state. -4. **Dates:** job dates via `fromZonedTime(iso, appTimeZone)`, never bare `new Date()`; project display dates are pre-formatted strings. -5. **Media:** every entry carries real dimensions and real `alt` text; `src` paths are site-absolute under `public/`. -6. **Licensed assets stay put.** Licensed fonts and photography ship with the site but are never published to other repos or registries. diff --git a/docs/01-standards/git.md b/docs/01-standards/git.md deleted file mode 100644 index f2ede28..0000000 --- a/docs/01-standards/git.md +++ /dev/null @@ -1,42 +0,0 @@ -# Git - -How change is recorded. - -## Workflow - -1. **Work on the branch the process defines for the task** ([process.md](process.md) §Branches and PRs). Never push directly to `main`. -2. **Create new commits rather than amending.** Never force-push or skip hooks without explicit permission. -3. **Task PRs target their milestone branch; milestone PRs target the latest `main`.** Work outside a milestone stays on a feature branch and PRs only when explicitly asked. - -## Conventional Commits - -1. All commit subjects follow [Conventional Commits](https://www.conventionalcommits.org/): - - ```text - (): - ``` - - - **Allowed types:** `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`. - - **Scopes** match the affected area: `home`, `works`, `about`, `templates`, `tokens`, `constants`, `prd`, `docs`, etc. Omit when global. - - **Subject:** ≤ 72 characters, lowercase, no trailing period. - - **Body:** explain the *why* when the diff alone doesn't. - - **Breaking changes:** `!` suffix and a `BREAKING CHANGE:` footer for route moves, renames, or behavior changes. - -## Branch naming - -1. Branches follow the same type vocabulary as commits: - - ```text - / - ``` - - - ≤ 40 characters, lowercase, hyphen-separated. - - Milestone and task branches carry their identifiers per - [process.md](process.md) §Branches and PRs: `feat/m02-works`, - `feat/m02-t04-works-ledger`. - - Branches outside a milestone reference the affected area: - `fix/career-dates`, `docs/initial-plan`. - -## Attribution - -1. **No AI/agent attribution** in commits, PRs, or issues: no `Co-Authored-By: Claude/Codex`, no "Generated with Claude Code" markers, no `claude.ai/code` session links. diff --git a/docs/01-standards/nextjs.md b/docs/01-standards/nextjs.md deleted file mode 100644 index 8e52050..0000000 --- a/docs/01-standards/nextjs.md +++ /dev/null @@ -1,44 +0,0 @@ -# Next.js - -How the framework is used: App Router, rendering, and the built-in primitives. - -## Foundations - -Runtime, language, and what "done" requires. - -1. **pnpm only.** Never npm or yarn. Node ≥ 24. -2. **TypeScript strict.** No `any` escape hatches; domain types live in `types/`. -3. **Exported constants, hooks, types, and utils carry TSDoc.** Every export in `constants/`, `hooks/`, `types/`, and `utils/` opens with a `/** */` block: a one-line summary, plus `@param`/`@returns` for functions where the signature does not already say it, and per-member docs on non-obvious type fields; the doc is the contract a caller reads without opening the body. Components document themselves through their props types, not TSDoc. -4. **A server started for verification is killed when the check ends**: a `pnpm dev` or `pnpm start` run to confirm a change holds the port and outlives the task otherwise, so the next run collides or, worse, verifies against stale output. Long-running servers the human started are theirs to stop. -5. **A verification server runs on its own port and dies by its own pid.** Start it with an explicit `-p` well clear of `3000`, capture the pid (`pnpm start -p 3987 & echo $!`), and kill that pid. Never `pkill -f next-server` or any name match: it matches every Next process on the machine, including the human's dev server, and rule 4 leaves that one theirs to stop. -6. **Tests are [testing.md](testing.md)'s concern.** - -## Concepts - -1. **App Router conventions.** One root layout; pages compose section components inside `
`; the `app/` route tree mirrors the site's information architecture. -2. **Server components by default.** `'use client'` only where state or browser APIs demand it (overlays, accordions, marquees, motion-driven sections), and as low in the tree as possible. -3. **Static generation everywhere.** No runtime content fetching. Dynamic routes prebuild with `generateStaticParams` over their id lists and return `notFound()` for unknown ids. -4. **All images render through `next/image`** with explicit width and height. (Video loops are not images; they render as media elements with their own posters and dimensions.) -5. **Fonts load through `next/font/local`**, exposed as CSS variables and applied on ``. -6. **Metadata via the Metadata API**: a full root export plus per-page overrides (never hand-rolled `` tags). What the metadata contains is [seo.md](seo.md)'s concern. - -## Folder structure - -1. **Application code lives under `src/`**; `public/` stays at the repo root. The canonical layout: - - ```text - . - ├── public/ # static assets (fonts, images, favicons, files) - └── src/ - ├── app/ # App Router routes: layout.tsx, page.tsx, /page.tsx - ├── components/ # atomic design: atoms/ · molecules/ · organisms/ · templates/ - ├── constants/ # typed compile-time content + site config - ├── types/ # domain types - ├── themes/ # CSS token files (theme.css entry, helpers) - ├── fonts/ # next/font/local loader modules - ├── providers/ # context providers wired in the root layout - ├── hooks/ # shared React hooks - └── utils/ # helpers (cn/cva re-exports, dates, strings) - ``` - - Folders are added only when they earn their place: no empty scaffolding for layers a project doesn't use yet. diff --git a/docs/01-standards/performance.md b/docs/01-standards/performance.md deleted file mode 100644 index f37b3fd..0000000 --- a/docs/01-standards/performance.md +++ /dev/null @@ -1,10 +0,0 @@ -# Performance - -Fast is a feature; the futuristic layer never gets to make the site feel slow. - -1. **LCP first.** Fast LCP on desktop and mobile; the first screenful renders without layout shift. -2. **Images lazy-load below the fold.** Decorative image layers (texture backgrounds, thumbnail walls) never block LCP. -3. **Vector geometry ships as optimized SVG**: brand rings, lines, wordmark letterforms, not raster. -4. **The futuristic layer has a budget.** Entry and loading sequences are capped in duration; motion never blocks interactivity or input. -5. **Motion discipline.** Durations, easings, and variants are defined once and imported: no ad-hoc magic numbers per component. -6. **Font loading causes no flash of invisible text and no layout shift** on swap. diff --git a/docs/01-standards/process.md b/docs/01-standards/process.md deleted file mode 100644 index a81a52f..0000000 --- a/docs/01-standards/process.md +++ /dev/null @@ -1,176 +0,0 @@ -# Process - -How work happens: the sources of truth, how they stay honest with each other, -and how work is planned, parallelized, and reviewed. This doc is the methodology -layer and stays project-agnostic; the PRD and the plan derive -their structure from it. How change is recorded is -[git.md](git.md)'s concern. - -## The working loop - -Front-loaded on distillation and direction before any build: - -> Gather inspiration → distill the essence → set direction → design → plan implementation → deliver. - -The brief and observations stages of the PRD (§The PRD) are the path toward the -design: gathering, distillation, and direction-setting. The **design file is the -designed solution** that path produces, transcribed into the design contract. -Planning the implementation lays out the milestone graph (§Milestones) from the -PRD and the design; delivery runs each milestone through the same cycle -(§The delivery cycle). - -## The PRD - -`docs/02-prd/` is the numbered product pipeline, read in order; each stage derives -from the ones before it: - -| Stage | Owns | -| --- | --- | -| `01-brief.md` | The distilled intent: what it is, who it's for, the aesthetic, references | -| `02-observations.md` | Research and risks, each paired with the direction taken | -| `03-solution.md` | The settled design at concept level: concept, surfaces, systems | -| `04-design.md` | The design-token contract, transcribed from the design file | -| `05-architecture.md` | Stack, information architecture, repo structure, data layer | -| `06-plan.md` | The plan: the milestone graph (kinds, dependencies), cut from the stages above | - -- **Observations follow the priority frame**, the order problems get worked in: - 1. **The Problem**: one or two sentences. - 2. **The Hardest Failure Mode**: what breaks worst; design around it first. - 3. **Key Design Decisions**: the load-bearing choices everything else hangs - off. - 4. **What to Prototype First**: the riskiest slice to validate early; this - names the proving surface. -- **Directions are research, not contract.** An observation's direction lands - only when the design file (and its transcription in the design contract) - adopts it; where they conflict, the design contract wins. - -## Division of truth - -Three authorities, each owning a different kind of truth and each with the -rules that keep it honest: - -- **The repo holds law and state**: the PRD (ending in the plan, - `docs/02-prd/06-plan.md`, the milestone list with live status), the standards, - and the code; versioned, canonical for intent, contract, and work status. Docs and code - change together **in the same change**; a discovery the docs missed (a - token value, a variant, a breakpoint) is written back to the owning doc, - never left in a commit message or comment. Docs carry intent and contract; - function-level detail belongs in the code. Each fact lives in exactly one - owning doc: everywhere else points or summarizes, never restates, and when - two docs disagree the owner wins. The plan's milestone status is work state, - not contract; a fact that matters beyond a milestone moves to the owning doc. -- **Figma holds pixels**: design questions resolve against the Figma nodes, - not guesswork. Use structured design context (metadata/variables/code), not - screenshots, when reading Figma. A component isn't done until it's been - compared against its Figma node at desktop and mobile widths. -- **GitHub holds review**: PRs, machine checks, preview deploys. Nothing - lives only on GitHub; a milestone's status flips in the plan, in the - same PR as the work that completes it. - -When all three still leave a question genuinely ambiguous, ask; don't -improvise the product. - -## The delivery cycle - -Every milestone runs the same three phases. The human steers at the two cheap -points (the plan and the gate); agents and machines carry the middle. - -1. **Plan.** Scope comes from the PRD and the design frames: cut the - milestone into tasks by file ownership, map dependencies, mark trunk vs - leaf, tracked as task branches and PRs. An unknown that blocks the cut - gets a **spike** first: a throwaway experiment answering one question; - spike code is never merged, its answer is written back to the owning doc. - The human approves the cut before execution; steering a plan costs - minutes, steering merged code costs days. -2. **Execute.** Trunk tasks merge serially first; leaf tasks fan out in - parallel worktrees. Every task PR must pass the machine checks and an - agent review before merge (§Review). -3. **Gate.** The human reviews outcomes on the milestone branch's deployed - preview against the design frames at desktop and mobile widths, plus the - milestone's merged task PRs. Outcomes, not diffs; a human reads - code only on escalation. - -## Milestones: the human gates - -A milestone is a reviewable increment behind a human gate, instantiated as an -**entry in the plan** (`docs/02-prd/06-plan.md`) binding it to concrete scope, a -definition of done, and a status; its tasks are cut at its plan step and tracked -as branches and PRs. Milestones form a dependency graph, not a fixed sequence, laid -out in the plan (§The PRD, `06-plan.md`); three kinds set what may run in -parallel: - -| Kind | The work | Parallelism | -| --- | --- | --- | -| **System** | Creates or proves shared conventions: scaffold, tokens, the shell | Serial; nothing may consume unproven conventions | -| **Surface** | Delivers one surface on conventions already proven | Parallel with other surface milestones, as sibling branches with independent gates | -| **Sweep** | One cross-cutting pass over everything: coherence, polish, audits, launch | Serial, after the surfaces it sweeps | - -- **System milestones gate on a specimen.** A system milestone has no surface - to review, so its gate reviews a specimen artifact instead: a design-system - page rendering every token, ramp, and primitive, compared against the design - system file. The specimen stays in the site as a living styleguide route. -- **The readiness rule.** A milestone may open when everything it consumes is - merged and its inputs are settled: design frames in the design file, content - in the data source. An unready surface (undesigned, content missing) is a - waiting node, never a blocker for its siblings. -- **The proving surface.** The first surface milestone is chosen deliberately: - the riskiest or most representative surface, named by the observations - stage, built through every layer end to end. Its gate is what unlocks - surface parallelism; the milestone graph may scope it tighter than a full - surface. -- **The canonical arc.** Foundations (system) → the proving surface → the - remaining surfaces in parallel → polish and launch sweeps. Parallelism is - earned: it begins only once the proving surface's gate passes. -- **Launch is a sweep** with a checklist gate: metadata and SEO verified, - analytics live, performance budgets met, domain cut over. - -## Tasks: the agent work units - -A task is one unit of work an agent can complete unattended, carrying goal, -kind, owned files, dependencies, acceptance criteria, verification commands, and -the Figma node when visual; it lives as a branch and PR, not a persisted doc -entry. - -- **Scope by file ownership.** A task lists the file globs it owns; two - tasks may run in parallel only if their owned sets don't overlap. The same - disjointness applies across sibling milestone branches. -- **Trunk, then fan out.** Work touching shared files (theme, layout shell, - constants, utils) is a *trunk* task, serialized at the start of its - milestone; *leaf* tasks (components, pages) fan out afterwards in parallel - worktrees. -- **Shared discoveries become system work.** When parallel work uncovers a - shared need (a primitive two surfaces want), it lands on `main` as its own - small system task and sibling branches merge `main` forward; never two - parallel copies of the same convention. -- **Check the plan and open branches at task start**: the milestone's scope - and the sibling tasks in flight bound what may run in parallel. -- **Status flips with the work.** A task moves through its branch and PR - (open → in-review → merged) in the same PR as the change it describes; - blocked is a state carried on the PR, not a comment. - -## Branches and PRs - -- One branch per milestone (`feat/m02-works`), cut from `main`. -- One branch per task (`feat/m02-t04-works-ledger`), PR'd into the milestone - branch; the PR flips its task's status in the same diff. -- The milestone branch PRs into `main` at the gate; merge `main` forward into - any milestone branch that runs long. - -## Review - -Three tiers, split by kind, not by priority: - -- **Machines check mechanics.** Lint, types, tests, build, and a green preview - deploy gate every PR; a human never spends attention on what CI can catch. -- **Agents review correctness.** Every task PR, against the standards and - the task's acceptance criteria. -- **Humans review taste.** At plan and gate only (§The delivery cycle): the - qualities no check can score; fidelity to the design, motion feel, whether - the thing is good. - -## The board - -The board is a query, not a service: milestone status lives in the plan and -task status is the state of its open branches and PRs, so `docs/02-prd/06-plan.md` -plus the live PRs are always the board and git history is the audit trail. -Nothing is mirrored to an external tracker. diff --git a/docs/01-standards/seo.md b/docs/01-standards/seo.md deleted file mode 100644 index 825e27a..0000000 --- a/docs/01-standards/seo.md +++ /dev/null @@ -1,8 +0,0 @@ -# SEO - -The site is findable and previews well everywhere it's shared. - -1. **Full metadata at the root**: title, description, Open Graph, Twitter card, targeting the canonical domain, plus favicons and the dark `theme-color`. -2. **Every route has its own title and description.** Dynamic pages derive theirs from their data entry (title, intro as description, first media as the OG image). -3. **Real text in the DOM.** No content locked in images or canvas; heading and landmark structure follows the [accessibility](accessibility.md) baseline. -4. **Overlays and loading states never hide content from crawlers**: page content is server-rendered and present in the initial HTML regardless of lifecycle state. diff --git a/docs/01-standards/testing.md b/docs/01-standards/testing.md deleted file mode 100644 index e945aa5..0000000 --- a/docs/01-standards/testing.md +++ /dev/null @@ -1,11 +0,0 @@ -# Testing - -What gets tested and how. The current strategy: **none**. No tests are -written until a strategy is settled here; coverage is never a goal in itself. - -1. **Don't test everything.** Tests earn their place under the strategy this - doc will define; until then, don't add them speculatively. -2. **The plumbing stays warm.** Vitest stays wired and `pnpm test` stays - green (it passes with no tests), so a strategy can land without - re-plumbing. -3. **When tests exist, they are colocated** with what they test. diff --git a/docs/01-standards/writing.md b/docs/01-standards/writing.md deleted file mode 100644 index a9f7a7e..0000000 --- a/docs/01-standards/writing.md +++ /dev/null @@ -1,54 +0,0 @@ -# Writing - -How project prose reads: docs, the plan, PR and commit bodies. Where facts live is [process.md](process.md) §Division of truth's -concern; this doc owns the sentences. Site copy is out of scope, since its -voice is the design's. - -## Voice - -1. **Declarative, present tense.** State what is and what wins, not what should - ideally happen. No hedging, no marketing filler. -2. **Every sentence is load-bearing.** A sentence earns its place by adding a - fact, a rule, or a reason; otherwise cut it. Conciseness comes from selecting - what to say, not compressing how it's said: full sentences stay, whole - points go. -3. **Rationale rides along.** A rule carries its why in the same sentence, - attached with a colon, semicolon, or parenthetical; never a separate - paragraph of justification. -4. **One line of personality.** A doc's opening line may carry an aphorism; - everything after it is working prose. - -## Structure - -1. **Open with ownership.** A doc's first lines state what it owns and hand - neighboring topics to their owners ("what the metadata contains is seo.md's - concern"), then get to work. No table of contents, no preview of what the - doc is about to say. -2. **Bold-lead rules.** Rule lists are numbered; each item opens with a bold - lead naming the rule, then the detail. -3. **Tables carry enumerable facts** (tokens, stages, routes). Reasoning stays - in the surrounding prose, never in cells. -4. **Headings name what the section owns**, in sentence case, with a colon - gloss only when the bare name is opaque ("Milestones: the human gates"). - -## Economy - -1. **Summarize and point, never restate.** A neighboring doc's fact appears - only as a pointer or a one-line summary; this is the prose form of the - one-owning-doc rule. -2. **Standards name the PRD by role, not by link.** "The design contract's - concern," not a path into `docs/02-prd/`; standards stay standalone and - portable. Standards may link standards; PRD docs link each other freely. -3. **Link once.** A doc or term links at first mention; after that, plain text. - Section references use `§Section`, in-doc and across docs alike. - -## Mechanics - -- Filenames, tokens, commands, and identifiers in `code` format. -- **Bold** for rule leads and load-bearing terms; *italics* for one word of - stress at a time. Asterisk emphasis, never underscores. -- **No em dashes.** Join clauses with a colon, a semicolon, parentheses, or a - new sentence. -- Words over symbols in prose ("and", not "&"). -- **Don't use the agent's built-in memory system.** The repo is the memory: - durable guidance belongs in the owning doc under `docs/`. diff --git a/docs/02-prd/01-brief.md b/docs/prd/01-brief.md similarity index 100% rename from docs/02-prd/01-brief.md rename to docs/prd/01-brief.md diff --git a/docs/02-prd/02-observations.md b/docs/prd/02-observations.md similarity index 100% rename from docs/02-prd/02-observations.md rename to docs/prd/02-observations.md diff --git a/docs/02-prd/03-solution.md b/docs/prd/03-solution.md similarity index 100% rename from docs/02-prd/03-solution.md rename to docs/prd/03-solution.md diff --git a/docs/02-prd/04-design.md b/docs/prd/04-design.md similarity index 100% rename from docs/02-prd/04-design.md rename to docs/prd/04-design.md diff --git a/docs/02-prd/05-architecture.md b/docs/prd/05-architecture.md similarity index 100% rename from docs/02-prd/05-architecture.md rename to docs/prd/05-architecture.md diff --git a/docs/02-prd/06-plan.md b/docs/prd/06-plan.md similarity index 100% rename from docs/02-prd/06-plan.md rename to docs/prd/06-plan.md