Required for every helper and every repository.
Who writes them: delegate to the
test-authorsub-agent after implementing a feature/fix. It writes to**/__tests__/**only, and every test has to name the regression it catches — the goal is a small set of tests that fail on real business-logic breakage, not a coverage number. Bans tautologies, mock theater, snapshots, and library tests.This is not optional advice: it is §1 of
99-verify-done.md, ahead of typecheck and the test run, and a row in the/verify-donesummary table. A green suite that never exercised the change proves nothing.
- Vitest — unit-test runner
@effect/vitest— providesit.effect(...)for Effect-yielding tests- Playwright — thin e2e smoke specs in
e2e/*.spec.ts(CI regression net, not one-per-feature). Feature-level proof is thefeature-verifiersub-agent → doc in.brain/features/<slug>/verifications/. See.brain/rules/library.md"Playwright".
Tests live in a sibling __tests__/ directory: app/repositories/user.ts → app/repositories/__tests__/user.test.ts. Imports use "../foo" to reach source.
Swap Database with makeTestDatabase(stub) from app/services/database.test-layer.ts. The chainable(value) helper builds a Proxy that mimics drizzle's chainable API.
import { describe, expect } from "vitest";
import { it } from "@effect/vitest";
import { Effect, Layer, Exit, Cause } from "effect";
import { UserRepository } from "../user";
import { chainable, makeTestDatabase } from "@/services/database.test-layer";
const provideStub = (stub: unknown) =>
UserRepository.Default.pipe(Layer.provide(makeTestDatabase(stub)));
it.effect("getUser fails with NotFoundError when missing", () => {
const stub = { select: () => chainable([]) };
return Effect.gen(function* () {
const repo = yield* UserRepository;
const exit = yield* Effect.exit(repo.getUser({ userId: "missing" }));
expect(Exit.isFailure(exit)).toBe(true);
}).pipe(Effect.provide(provideStub(stub)));
});- Tagged-error paths (NotFoundError, ValidationError, etc.)
- Validation predicates
- Condition builders
- Default schema values
- Pure helper functions
bun run test # one-shot
bun run test:watch # watch mode
bun run test:e2e # Playwright