All concepts
01 — Concept

Agent-first by design

Built to be worked on by a coding agent: the rules, the per-directory guides and the test gate are the interface it reads and the check it cannot skip.

The premise

Most of your code from here on will be written with a coding agent in the loop. That changes what a good starting point looks like. An agent does not absorb a codebase by working in it for six months; it arrives with an empty head, reads what is in front of it, and acts. Whatever you did not write down, it will invent — plausibly, consistently, and wrong.

So the conventions of this kit are not folklore in somebody's head or a style guide nobody opens. They are files placed where the agent will actually read them, written in the imperative, and backed by a check that fails when they are ignored. That is the whole idea: the documentation is an interface, and the test suite is its enforcement.

Why write it down rather than rely on review. An agent will produce a route that works, passes its own test, and quietly breaks a rule you care about — a query without a tenant filter, a long job run inline, a response type declared in the route instead of the shared package. Catching that in review, every time, does not scale. Stating the rule where the agent reads it, and failing the build when it is broken, does.

One root brief, loaded every session

CLAUDE.md at the repository root is the map: the stack in a table, the commands that matter, the directory layout with a one-line job description each, and a short list of non-negotiables. It is deliberately dense and deliberately short — it is read on every single turn, so every line has to earn its place.

AGENTS.md is a symlink to that same file. Different tools look for different names; there is exactly one document behind both, so they can never drift apart.

Rules that load themselves, by path

A single enormous instruction file is a bad interface: most of it is irrelevant to whatever you are touching, and the part that matters gets lost. So the detail lives in .claude/rules/, one file per layer, each carrying a frontmatter list of globs:

---
globs:
  - apps/web/src/api/**
  - apps/web/src/worker.ts
  - apps/web/src/config.ts
  - packages/shared/src/**
---

# API Patterns

Open a route and the API rules are in context: the middleware order and the reason for each position, the fact that routes enqueue and never run long work, the one sanctioned way to read the authenticated context. Open a schema file and you get the database rules instead — tenant reference first in every index, timestamptz not timestamp, append-only enums. Seven rule files cover the API, the database, the UI, the CLI, testing, Cloudflare and code quality.

Why globs rather than one long file. Attention is the scarce resource. Rules scoped to a path arrive exactly when they apply and cost nothing when they do not — and the glob list doubles as documentation of which layer a file belongs to.

A guide in every significant directory

Thirteen directories carry their own CLAUDE.md — the routes, the middleware, the permission model, the database schema, the AI services, the agent runtime, the workflows, the cubes, the fact tables, the dashboard templates, the UI, the CLI and the shared package. Each one describes the local shape: what a file in this folder looks like, what it must not do, and what to copy when adding another.

The effect is that "add a cube" or "add an agent" is a mechanical path rather than an archaeology exercise. The agent opens the folder, finds the guide, follows the shape, and the result reads like the code beside it.

Written-down reasoning, not just rules

docs/CONCEPTS.md — the same material these concept pages are drawn from — records one section per subsystem: what it does, the invariant it protects, and the decision behind it. It exists because an agent asked to change something needs to know which parts are load-bearing and which are arbitrary.

A rule tells you what to do. The reasoning tells you when the rule stops applying — which is the difference between an agent that adapts a pattern intelligently and one that cargo-cults it into a place it does not belong.

The gate is the contract

Instructions that nothing enforces decay within a month. So the conventions that matter most are tests, and one command runs all of them:

pnpm lint && pnpm typecheck && pnpm test && pnpm build

That gate runs before every commit and again in CI. Several of its checks exist specifically to catch the mistakes an agent makes:

CheckWhat it refuses to let through
Row-level-security coveragea new tenant table that arrived without a policy, or an untenanted one without a stated reason
Cube isolationa new cube with no two-tenant isolation case — the test compares the cases to the registry
Unscoped-query allow-listcross-tenant SQL appearing anywhere it was not already sanctioned
Wrangler paritya binding, cron or variable added to one environment and not the other
Dashboard templatesa renamed cube member that would silently break every saved dashboard
Bundle checka Node-only dependency that type-checks but cannot run on the platform

Each of those is a rule from the documents above, expressed as a failure. The agent does not have to remember them; it finds out immediately when it forgets.

The kit also states plainly that a behaviour change updates the matching document in the same change — the concepts file, the setup walkthrough, the deploy reference or the layer's rules. It is the least glamorous convention here and the one that keeps every other one true.

The loop this produces

Because contracts live in one shared package and the API, the UI and the CLI all consume them, adding a feature is a fixed sequence rather than an open-ended design problem: a schema in the shared package, a route that validates with it, a page that parses with it, optionally a CLI command that does the same. Every step has a rule file, a directory guide and an existing example beside it.

That is the pay-off of everything above. The next feature is a short, well-lit path — for you, and for the agent working alongside you.

It sets itself up, too

The same approach covers the first hour, and the first deploy. Ask a coding agent "help me set up this project" and the root brief routes it to a skill that drives the bootstrap script for you — showing each step's line as it passes, stopping on the first failure, and fixing a missing prerequisite rather than reporting it. Four skills ship in .claude/skills/, one per moment where a person used to follow a checklist:

  • /setup — the first run on a machine. Drives scripts/bootstrap.sh: toolchain, Postgres, migrations, demo data, and a browser signed in as the demo owner.
  • /preflight — read-only diagnosis when pnpm dev, the migrations or the tests misbehave. It changes nothing; it names the failure and the fix.
  • /adapt — the rename. scripts/rename.mjs does the mechanical rows of docs/ADAPTING.md in one pass and reports the handful that need a person.
  • /provision — from a laptop to a URL: Cloudflare resources, a Neon project and branches, Resend, the secrets, migrations and the first staging deploy.

Each is a written procedure with a verification line at every step, in the same imperative style as the rules — so the agent walking it, and the person watching, both know what "done" looks like before it is claimed.