Distributed Storybook snapshot testing and agent control surface. See README.md for the pitch.
A spec is the accurate reference for the current code: it states the invariants and edge cases the code alone does not show. To modify a feature, read its spec first, and when code covered by a spec changes, change the spec.
docs/specs/glossary.md— Canonical vocabulary: image, render, batch, approval, reference. Read first; every spec defers to it for names.docs/specs/system.md— The whole system's staged build order, and the behavior that spans the local app and the cloud.docs/specs/access.md— The GitHub App, who can see and change a project, and how images are served. Read first for anything touching auth or visibility.docs/specs/renders.md— Render batches, render states, decisions, and approvals: the data layerselfie reviewand the review UI use.docs/specs/store.md— Image storage: image identity, decoding, keys, hash collisions, kept built Storybooks, and the SQL and blob adapters.docs/specs/sync.md— Moving batches, images, decisions, and goldens between stores.docs/specs/cloud.md— The Worker atapp.selfie.dev: its projects, origins, pages, and a commit's status.docs/specs/feedback.md— Notes: how a person tells a coding agent what they see, and how the agent answers.docs/specs/render.md— The renderer: rendering a built Storybook into PNGs in a pinned environment, the environment ID, and the manifest.docs/specs/cli.md— TheselfieCLI:review,approve,reject, andui, their exit codes and JSON, and local data's layout.docs/specs/ui.md— The review UI: its routes, the seam a platform implements, and what each screen must show. Readdocs/specs/access.md→ Local review server with it.
- What, not why. A spec says what the code is: each rule once, as a bolded imperative (Must …, Never …, May …), in the spec that owns it. Other mentions are bare pointers to the spec and heading. The why goes in
docs/specs/<foo>.rationale.md, keyed by the spec's headings and marked(rationale)at the rule it backs. - What stays. Keep contracts: what crosses a module, process, or host boundary, and the semantics a caller relies on. Mechanism and presentation live at the code as comments, tests, or stories.
- The fold. Everything above
## Futuredescribes the code as it is, in present tense. Everything unbuilt lives under## Future, always the last section. - Design-stage specs. A spec for a component that does not exist yet keeps its whole design under
## Futureand opens with> Status: design — nothing here is implemented yet. - Named scopes. A cut is recorded as a named scope in
## Future(**Scope: store**). A scope is defined in exactly one spec; others link it by name. - Reservations. Unbuilt design that constrains present code is stated in the body, marked
Reserved:, pointing at the## Futureitem it serves. - Promotion is part of done. A staged item is finished only when its text moves above the fold, rewritten to present tense, and the built portion is deleted from
## Future.
store/, render/, cli/, and ui/ are the product; ui/src/worker/ is the cloud service at app.selfie.dev. site/ is the landing page at selfie.dev, plain HTML with no build step; its PRODUCT.md and DESIGN.md are the brief for it. OPERATIONS.md says how each is deployed, and what holds which secret.
cli/skills/ holds guides for a coding agent, linked from .claude/skills/, and printed for anyone by selfie skill. quickstart sets Selfie up in a repository, which the README's Quickstart points an agent at. fix-flakes is how to make every story render the same way every time, which selfie flakes measures.