# Suaveplan Monorepo — Genesis Bottom-up rebuild at enterprise quality. Branch `genesis` starts empty; packages land in dependency-order waves at `0.1.0` until graduation to `1.0.0`. Main branch (`/mnt/s/web/suaveplan`) is reference-only for design intent (`enterprise/*.md`) and historical audit data. Do not pull code from main into genesis — every package is rewritten fresh. ## Change workflow All non-trivial changes go through **OpenSpec**. Before coding: 1. Read `openspec/project.md` and `openspec/AGENTS.md`. 2. Create `openspec/changes//` with `proposal.md`, `tasks.md`, and spec deltas under `specs//spec.md` (`## ADDED` / `## MODIFIED` / `## REMOVED Requirements`). 3. On ship: fold the delta into `openspec/specs//spec.md` and move the folder to `openspec/archive/-/`. ## Stack - **Turborepo + Bun** monorepo at `/mnt/s/web/genesis` - **Biome** (lint/format), **Vitest** (tests), **Playwright** (E2E), **TypeScript** - Use `bunx turbo` for turbo commands - Private registry: Verdaccio at `https://npmjs.fq.io/` (auth via `NPM_TOKEN`) ## Packages ### Layout (`packages////`) Domain-first 3-level layout: every package lives at `packages////` where `` is one of the 18 canonical super-categories — `foundation`, `persistence`, `networking`, `communication`, `api-stack`, `identity`, `security-stack`, `observability`, `media`, `ui`, `threejs`, `localization`, `geospatial`, `money`, `commerce`, `testkit`, `devtools`, `gaming` — and `` matches a plugin in [`suaveplan-skills`](https://github.com/SuavePlan/suaveplan-skills). Tier (universal / browser / react / r3f / server / python) is per-package via `package.json` (`"browser"` field, peer deps, `engines`), not encoded in the path. Full category → plugin → package map in `scripts/folder-reorg/assignment.yml`; summarised in `MANIFEST.md` at repo root. The super-category vocabulary is closed — adding/removing a category requires an OpenSpec change. Add new packages, then run `bun scripts/folder-reorg/generate-manifest.ts` to refresh `MANIFEST.md` (dep graph auto-derived from `workspace:` ranges). > **Note:** Detailed package descriptions live in each package's `README.md` and co-located `.md` files. This file describes foundational packages widely depended on; everything else is listed by name only — see `MANIFEST.md` and the package sources for details. ### Foundation (zero or near-zero deps, widely consumed) - **types** — types-only foundation: `Clock`, `IdGenerator`, `Rng`, `MessageResolver`, `EventBusLike`, `LoggerLike`, `StorageLike`, `DatabaseLike`, `HashLike`, `TimersLike`, shared option bundles + cross-package crypto contract (`Authority`, `KeySlotPublic`/`Private`, `SlotId`, `DomainTag`, `AuthorityVerifier`, `AeadOps`, `AeadAlgorithm`). Zero runtime, zero deps. Permitted as testing-infra dev dep (rule 8 exception). - **error** — `SuaveplanError` base, stable code registry via `defineCodes`, cause-chain traversal, Zod-validated wire format, redaction, OTel span-event adapter, i18n resolver hook. Deps: `tslib`, `zod`. - **events** — typed event bus: pub/sub FIFO, interceptors, bounded-queue backpressure, idempotent listeners. Deps: `error`, `types`. - **env** — type-safe env loading with schema validation, dotenv + object loaders, `maskSensitive`, `createEnv`. Deps: `error`, `types`, `zod`. - **config** — layered config (5 layers: defaults/file/object/env/CLI), Zod validation, dot-path get/has, hot reload, EventBus watch. Deps: `error`, `types`, `events`, `env`, `zod`. - **logger** — structured logger: level filtering, OTel trace enrichment, sampling, redaction, pluggable sinks. Deps: `error`, `types`. - **opentelemetry** — OTel SDK utilities: `NoopSdk`, `SdkFactory`, W3C propagation, span/metrics utilities, resource builder. - **typescript-config** — shared TSConfig presets. No runtime. - **overview** — machine-readable monorepo manifest with Zod schemas + graph utilities. Leaf. - **api-schemas** — shared Zod request/response schemas. Leaf. ### Testing infrastructure (no `@suaveplan/*` runtime deps; rule 8) - **testing** — runner-agnostic utilities (FakeClock, Factory, FixtureManager, MemoryStore, builders). Owns the `./runner` conditional-export wrapper resolving to `vitest` (default) or `bun:test` (under `bun` condition) — see rule 11. - **testing-dom**, **testing-e2e**, **testing-integration** — DOM helpers + dual-runner adapters; Playwright config factory; `ServiceFixture`/`TestEnvironment`/`HealthPoller`. - **testing-integration-{surrealdb, redis, postgres, mailpit, typesense, garage-s3, step-ca}** — real-service fixtures via testcontainers; each provides env-bridge + health probe + injectable container/exec/fetch factories. ### Crypto family Foundation (widely consumed): - **crypto-utils** — hex/base64/base58, byte helpers, constant-time equality, random bytes, zeroize, Merkle, KAT/fuzz harnesses, `PrimitiveId` registry. - **crypto-hash** — sha256/384/512, hmac, hkdf, pbkdf2, argon2id. Noble + native, build-time selection. - **crypto-curve** — secp256k1, ed25519, x25519, p256, p384, p521. Noble + native. - **crypto-cipher** — aes-256-gcm, chacha20-poly1305, xchacha20-poly1305. Nonce caller-supplied. - **crypto** — multi-algorithm façade over the four primitive packages. Engine-pluggable. - **crypto-rsa** — RFC 8017 PKCS#1 v2.2: PKCS1v15+PSS sign/verify, OAEP, all 8 key formats, FIPS 186-5 keygen, RFC 7638 thumbprints, blinding-by-default, pluggable engine, HSM bridge. Gates `x509`/`jws`/`webauthn`. Specialty: **crypto-core**, **crypto-sodium**, **crypto-browser**, **crypto-cli** (`keychain` binary), **crypto-bin** (`suaveplan-hash-password`), **crypto-vault** (BIP39 + Argon2id + 2SKD + HKDF + SRP-6a + SecureBuffer; gates `vault`). ### Drive (file VFS) - **drive** — modular file-VFS core. Consumes `AbstractStorage` directly via structural `DriveStorage` view. Plugin slot + middleware chain. Template hydration (`hydrateFrom`/`getKeyStatus`/`presence`). 11 `DRIVE_*` codes. - **drive-template** — server-signed dehydrated descriptor for lazy hydration. 8-step validation pipeline, Ed25519 over canonical bytes, `TemplateNonceLru`, CDN URL builder, upload-token signing, retroactive key-grant validation. 10 `DTP_*` codes. - **drive-mesh-protocol** — wire protocol for chunk discovery/request/delivery. `ChunkRequest` union (whole/specific/bitset), `GenerationTracker`, `AdvertiseThrottle`, `TrustMap` with sample-verify. 10 `DMP_*` codes. - **drive-plugin-chunks** — chunk addressing: 164-byte fixed-width header, XChaCha20-Poly1305 streaming AEAD, Ed25519 inline-hint signing, sparse-file + chunk-keys layouts, server-signed manifest. 12 `CHUNKS_*` codes. Consumers: **drive-sharing**, **drive-transport-https**, **drive-transport-webrtc**, **drive-webrtc** (browser-tier P2P mesh plugin), **drive-mesh** (P2P orchestrator: `PeerRegistry`, `GossipEngine`, `ParallelPuller`, `ServerFallback`), **drive-react-sharing** (React 19 hooks + accessible components). ### Vault - **vault** — orchestration: `open`/`unlock`/`lock` FSM, encrypted single-blob container via `DriveLike`, items/attachments/shares/sync, `OpaqueKeyHandle`, forward-only migrations, bitpacked manifest, 25+ error codes. - **vault-sync** — sync + conflict resolution: 3 merge strategies (lww/append/atomic) with vector clocks, RFC 6902 diff/patch, `SyncEngine`/`SyncQueue`, payload encryption with AAD + 10 MiB cap. 10 error codes. ### Network - **network** — plugin-based core. `NetworkPlugin` lifecycle, `NetworkNode`, `MessageEnvelope` Zod schema, `MessageRouter` (unicast/broadcast/fan-out), `PluginManager`, `NetworkBus`, `VersionInfo`/`VersionManager`/`VersionNegotiator`, `NetworkTimestamp`, `NetworkEvents` registry, 5 `NET_*` codes. Concrete transports/governance/registry/failover/topology all live in sibling `network-plugin-*` packages. ### i18n family - **i18n** — slim integration core (post-Wave-6 split). Owns `MessageCatalog`, `createI18n`/`I18nInstance`, locale negotiation, server middleware, `defaultFormatBridge`. Re-exports siblings for back-compat. - **i18n-shared** — universal-tier shared atoms: locale constants, `LOCALE_BCP47_MAP`, `RTL_LOCALES`, `I18N_CODES` (18), `I18nError`, `./testing` `runBackendConformance` harness. - **i18n-icu-parser** — ICU MessageFormat parser (tokenizer + AST + CLDR plurals). - **i18n-detector** — 9-detector chain (querystring, userPreference, cookie, localStorage, htmlLang, acceptLanguage, navigator, cloudflareIpGeo, fallback) + `bcp47Negotiate` + RTL helpers. - **i18n-backend-{memory, http, storage, chained, fs-multifile}** — translation backends; all conform to `runBackendConformance` harness. `fs-multifile` is server-tier. - **i18n-formatter-{number, currency, date, relative-time, list, display-name, collator, segmenter}** — `Intl.*` adapters plugged into `defaultFormatBridge`. ### Time, sequencing, validation, control flow - **datetime**, **timing**, **cron** (gates `job-scheduler`), **job-scheduler** (consumes `cron` + `retry`), **validation**, **retry**, **idempotency**, **fsm**, **schema-registry**, **feature-flags**, **workflow** (universal-tier pipeline orchestration: fluent builder, sequential / parallel / conditional steps, saga compensation, retry middleware, hook registry, transition-data pipeline, Zod-validated `WorkflowConfig`, injectable `Clock`, six `WORKFLOW.*` codes, OTel counters + histogram). See per-package READMEs. ### Rules - **rules** — universal-tier rule engine + validators + actions + hooks + serializer + optimizer. 24 codes. Discriminated `Rule` union, `RuleBuilder`, 33 built-in operators. - **rules-hono** — Hono middleware suite (6 factories: rule, validation, accessControl, responseValidation, rateLimit, combine). Hono peer dep. ### Security / vault leaves - **slsa**, **security-codes**, **data-masking**, **suppression**, **macos-keychain**, **hibp**, **password-generator**, **password-strength**, **x509**, **jws**, **tpm-struct**, **cbor**, **otp**, **srp**, **webauthn** — see per-package READMEs. `webauthn` consumes cbor/x509/jws/tpm-struct/crypto-{rsa,curve}; covers all 7 attestation formats. ### Serialization / data shape - **serialize**, **diff**, **pagination**, **mime**, **templates**, **bitpacker**, **bitpacker-compressed**, **packer**, **packer-browser** (browser-tier runtime for packer archives: SW interceptor + `PackedResourceManager` + Ed25519 signature verification; no React dep), **react-packer** (React 19 companion: `usePackedResource` / `usePackedImage` / `usePackedAudio` / `usePackedVideo` / `usePackedFont` hooks + `PackedResourceProvider` context; consumes `@suaveplan/packer-browser`; React peer-dep only). ### File / media / domain utilities (mostly leaves) - **metadata**, **exif**, **dmarc**, **sitemap**, **domain-normalizer**, **dedup**, **password-formats**, **barcode**, **qrcode**, **compress-image**, **font-subset**, **font-convert**, **font-compress** (bin: `suaveplan-font-compress` — TTF/OTF/WOFF/WOFF2 → BTF pipeline). ### Geo / astronomy / tides - **geo**, **geo-planet**, **geo-earth**, **solar-system**, **stars**, **tides**, **universe** — abstract spherical geometry → planet config → Earth specifics → injectable astronomy/star/tidal providers aggregated through `universe`. ### Network clients / IO / DB / installer - **oauth-client**, **webhook-client**, **readline**, **cli**. - **db** (adapter foundation), **db-sqlite** (universal: `bun:sqlite` on Bun, `@sqlite.org/sqlite-wasm` in browser). - **installer** (plugin host, bin `suaveplan-install`), **install-agent-skills** (skill bundle installer). ### Games (universal-tier) - **ecs** — archetype-based Entity Component System: `Uint32Array` BitSet, column-oriented archetype storage with O(1) swap-remove, phase+priority `SystemScheduler` (`preUpdate→update→postUpdate→render`), entity-ID recycling with generation counters, Zod-validated component schemas, `EventBus` entity lifecycle events, OTel counter (`ecs.entity.lifecycle_total`) + histogram (`ecs.world.execute_duration_ms`), `WorldSnapshot` round-trip. 7 `ECS.*` codes. Deps: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/opentelemetry`, `tslib`, `zod`. ### Contacts - **contacts** — universal-tier contact and group management: hierarchical n-level groups (adjacency + materialised path), channel-agnostic contacts with dedup, many-to-many memberships with ancestor count propagation, audience resolution with descendant walk + dedup + filters, contact merger, CSV/JSON import-export, injectable `Clock` + `IdGenerator`, Zod input boundaries, six OTel counters + three histograms, typed `ContactsError` hierarchy with stable `CONTACTS.*` code registry. - **macos-contacts** — macOS Contacts.app bridge: AppleScript reader, `Contact` ↔ macOS `Person` mapping, deduplication via `@suaveplan/contacts/dedup`, push/pull/sync, vCard import-export. - **api-sandbox-vm** — `vm.Context`-based sandbox host (Stage 8.2). Builds a Proxy-guarded `vm.Context` with frozen-globals allowlist (`URL`/`URLSearchParams`/`TextEncoder`/`TextDecoder`/`structuredClone` + logger-routed `console` + trimmed `crypto`), `vm.SourceTextModule` plugin loader with refuse-everything linker (rejects `node:*`, bare specifiers, parent traversal), `eval`/`Function` traps, host-proxied fs/fetch with permission gating, consolidated `__suaveplan` capability receiver, in-package `PermissionChecker` default from `PermissionsManifest`, idempotent `dispose()`, OTel `sandbox_vm.{boot_duration_ms,eval_rejected_total,module_import_rejected_total}` + shared `plugin.permission_denied_total`, 5-code `SAND_VM.*` registry, `./testing/runVmSandboxConformance` harness. Requires Node ≥ 20 with `--experimental-vm-modules`. - **api-plugin-contacts** — Contacts + groups HTTP plugin for `@suaveplan/api`. Mounts `/contacts` and `/groups` (with `/groups/:id/members`, `/groups/:id/tree`, `/groups/:id/move`, `/groups/:id/resolve`) on a Hono `OpenAPIHono` backed by SurrealDB implementations of the `@suaveplan/contacts` `ContactStore` / `GroupStore` / `MembershipStore` interfaces. Bulk-import with per-row error reporting, repository-level `maxGroupDepth` enforcement, six OTel instruments (4 counters + 2 histograms), typed Hono `ContextVariableMap` + `ServiceRegistry` augmentations, and the 12-code `CONTACTS_API.*` error namespace. ### API sandboxing - **api-sandbox-wasm** — Stage-8 WebAssembly sandbox host for sandboxed-tier plugins. Instantiates a guest WASM module against a `wasi_snapshot_preview1` snapshot built from the plugin's `PermissionPolicy`: read-only WASI preopens from `permissions.fs[]` (with `rw:` opt-in), outbound socket allowlist from `permissions.fetch[]` (`sock_connect` gate raises `SAND_WASM.OUTBOUND_DENIED` BEFORE any OS socket), and capability host imports under `suaveplan_caps` permission-gated per call (denied → `WASI_ERRNO.ACCES` + `plugin.permission_denied_total{plugin,capability,reason}`). Owns a 4-code `SAND_WASM.*` registry, a `runWasmSandboxConformance` harness on `./testing`, and a hand-encoded fixture WASM builder so the test suite needs no `wabt` build step. `WasmSandboxHandle.dispose()` idempotent. ## Rules ### Critical (never compromise) 1. **NEVER run `tsc` directly** — use Vite/tsup via `bunx turbo build`. Bun runs `.ts` natively. 2. **NEVER use mocks** — real services only (no `vi.mock`/`jest.mock` unless absolutely necessary). 3. **Bun `overrides` with exact versions.** 4. **NEVER re-export** external deps for convenience — import directly from source. 5. **NEVER auto-commit/push** without user approval — never use `--no-verify`. 6. **Always use absolute paths** in tool calls. 7. **Read files before editing** — understand context first. 8. **Testing-infrastructure packages** (`testing`, `testing-dom`, `testing-e2e`) must not depend on any `@suaveplan/*` **runtime** package — external catalog deps only. Sole exception: `@suaveplan/types` (types-only, byte-size-test guarded). 9. **NEVER write `// biome-ignore` (or any static-analysis suppression comment) in migrated/new code.** Stale rule names → hard parse-error fails; right names that no longer match → `Suppression comment has no effect` warnings. Both block CI. To exercise a deliberate violation, use a coding pattern biome cannot statically reject. Full rule: `openspec/AGENTS.md §2a`. 10. **NEVER write `export *` in any non-root barrel.** Feature-module barrels MUST use explicit named re-exports. Exempt: generated `*.select/index.ts` forwarders, single-line `*.native/`/`*.noble/` impl-variant forwarders, namespace re-exports. Package roots MAY currently use `export *` but new ones SHOULD prefer namespace exports. **Migrate `export *` → named exports as part of the migration commit, not a follow-up.** Full rule: `openspec/AGENTS.md §6a`. 11. **NEVER import test-runner primitives directly from `vitest` or `bun:test` in non-exempt packages.** Test files MUST import from `@suaveplan/testing/runner`. Exempt allowlist (5): `testing`, `testing-dom`, `testing-e2e`, `testing-integration`, `testing-integration-step-ca`. CI gate: `bun scripts/lint/check-test-runner-imports.ts`. Verification: `grep -rnE "from ['\"](vitest|bun:test)['\"]" packages////src/` → zero output. Full rule: `openspec/AGENTS.md §7`. ### Git safety (non-negotiable — code has been lost twice on main) Before ANY git operation: run `git status` in **every** worktree (`git worktree list`) and confirm each is clean or its state is understood. **NEVER run these without explicit per-use user approval:** - `git filter-repo` / `git filter-branch` — rewrites history, destroys staged + working tree. - `git push --force` / `--force-with-lease` — only after user explicitly says "force push". - `git reset --hard`, `git clean -f[d]`, `git rebase`, `git stash drop`/`clear`, `git gc`/`prune`, `git checkout -- `. **Large-file push errors:** stop, do NOT rewrite history. Run `git status`/`git stash list` in all worktrees first, then ask the user (`.gitignore` + new commit, Git LFS, or manual removal). Staged changes are irreplaceable — treat them as more precious than committed history. **Worktree discipline** — long-lived worktrees are never the answer. - Before opening a worktree or dispatching a parallel agent: `git worktree list` and `git status` in each existing one. Account for every entry: active agent, work-pending-merge, or stale-and-prune. - After a worktree-based agent ships (commit on a `feat/*` branch), remove the worktree (`git worktree remove`) so the count returns to baseline. The branch + commit survive; the directory does not need to. - The baseline is **one worktree** (the main checkout). Anything beyond that is an open ticket waiting to be closed. - Run `bun scripts/worktree-prune.ts` to audit + prune in one command. It's idempotent and refuses to remove worktrees whose HEAD commit isn't reachable from any branch ref (so it never loses work). **Worktree-isolated agents: never edit the main checkout.** When dispatched into an isolated worktree at `.claude/worktrees/agent-/`, every file operation MUST target that worktree path, never `/home/paul/web/genesis/`. The hazards are real and observed: 1. First action in every agent session: `pwd && git worktree list` to confirm you're in the right tree. If `pwd` shows `/home/paul/web/genesis` instead of a `.claude/worktrees/agent-*` path, STOP and report — you are not in an isolated worktree. 2. Use **relative paths** (`packages/...`, `openspec/...`) for every read/edit/write. Avoid absolute paths in tool calls unless reading reference material from outside the worktree (e.g. main-branch source at `/mnt/s/web/suaveplan/...`). 3. Never `cd` to `/home/paul/web/genesis/` from a worktree. The Read/Edit/Write tools resolve relative paths against the working directory of the bash session, which starts in the worktree. 4. Before committing: `git rev-parse HEAD` and `git rev-parse --show-toplevel` must show your worktree's branch + path, not main's. If either is wrong, your work landed in the wrong place — recover with `git status` in BOTH locations, then move the changes back via patch (`git diff > /tmp/work.patch`, `cd $WORKTREE`, `git apply /tmp/work.patch`). Cross-worktree leakage has been the failure mode in three recent agent sessions — wasted ~1 hour each time. This rule is the prevention. **§0a Sync — worktrees fork from a stale base.** Empirically the harness's `isolation: "worktree"` may fork from an earlier session-stable ref rather than current `genesis` HEAD. This bit Wave B (5 agents all forked from a pre-Wave-A commit). Prevention: every parallel-dispatch prompt MUST include a §0a Sync block that fast-forwards the worktree to a known base SHA before any work begins: ```bash EXPECTED_BASE= if ! git merge-base --is-ancestor "$EXPECTED_BASE" HEAD; then git fetch /home/paul/web/genesis genesis git merge FETCH_HEAD --no-edit fi git merge-base --is-ancestor "$EXPECTED_BASE" HEAD || { echo "STILL OUT OF DATE"; exit 1; } ``` The orchestrator passes the expected SHA at dispatch time. Agents that can't reach it STOP and report rather than proceeding Wave-N-blind. Without this gate, agents re-invent interfaces from earlier merges and produce work that doesn't integrate. ### Workflow 1. **TaskCreate for multi-step tasks** (>3 steps). 2. **Complete all implementations** — no stubs, no placeholders, no TODOs, no mocks in production. Missing dep? Add it and wire the real implementation. 3. **Build feature-rich, production-grade packages** — comprehensive enterprise-level over minimal MVP. 4. **Professional honesty** — no marketing language or fake metrics. 5. **Preserve full public surface** during rewrites. Trim ONLY when duplicated in-repo or replaceable by an existing `@suaveplan/*` library. ### Web App & Page Verification When generating client-side pages/web apps, verification is NOT optional and a 200 response is NOT proof of correctness: 1. **Docker staging environment** — mirror production before declaring done. 2. **Full Playwright E2E sweep** — every page, every component, every navigation. 3. **Never trust HTTP 200 alone** — verify rendered DOM contains expected content. 4. **Inspect browser console** — any unexpected error or warning fails the check. 5. **Inspect network activity** — failed requests, missing assets, CORS, mixed content. 6. **Zero-defect push to live** — fix root cause first. ### Package Lifecycle - **New packages**: add to listing, then `bun scripts/folder-reorg/generate-manifest.ts`. - **Editing**: every package starts at `0.1.0`; bump only at `1.0.0` graduation. - **Pre-publish gate (non-negotiable)**: `bunx turbo lint typecheck test --filter=@suaveplan/` MUST be green AND `bunx turbo test:coverage --filter=@suaveplan/` must meet 100% on touched modules. Full-package `turbo test` required — single-file `vitest run` is not a substitute. - **After verification passes**: `bun scripts/publish.ts --package @suaveplan/`. ### Package Structure (library packages) Five files per feature module, co-located: ```text src/category/ feature-name/ index.ts # Barrel — explicit named re-exports (rule 10) feature-name.ts # Implementation feature-name.test.ts # Vitest tests feature-name.types.ts # Type definitions (no .md required) feature-name.md # Co-located docs (required) ``` Special: `types/` (shared types, flat), `utils/` (utilities, flat with tests + .md), `constants/index.ts` (simple exports, no tests/docs). **No flat modules at `src/` root.** Every implementation file paired with a `.test.ts` MUST live in a `src//` folder, not flat at `src/` root. The only flat entries permitted at `src/` root are `index.ts` (package barrel) and the three exempt directories above. This includes `error-codes`, `telemetry`, `schemas`, and similar "single-concept" modules — they get their own folder + `index.ts` barrel just like any other feature. Empirically this gets cut by agents shortcutting "atomic" modules to flat siblings of `index.ts`; lint+typecheck+coverage all accept it. CI gate: `bun scripts/lint/check-feature-layout.ts` (wired into `bunx turbo lint`). Subpath exports in `package.json` for tree-shaking: `./category/feature/feature`. **README layout:** one `README.md` at package root only. No category-level READMEs inside `src//`. ### Quality - **100% test coverage** — `bun run test:coverage --filter=@suaveplan/` (`provider: 'istanbul'`). - **100% docs coverage** — `bun run docs:check --filter=@suaveplan/`. - **~250 lines** soft / **300 lines** hard limit per code file, **500 lines** max per test file. - `.test.ts` for Vitest, `.spec.ts` for Playwright E2E. - Always add `{ timeout: 5000 }` (30000 for async) to `it()`/`test()`. - Root cause analysis — never skip/disable tests. - Every React component needs `.stories.tsx` (default + playground + variants). ### Documentation (co-authored `.md` per implementation file) Every `.ts`/`.tsx` MUST have a sibling `.md`. Exclusions: `.test.ts`, `.test.tsx`, `.spec.ts`, `.types.ts` (inside a feature dir), `.stories.tsx`, barrel `index.ts`, `constants/index.ts`. Required sections: **Purpose** (≥2 sentences), **Features**, **Usage: Basic**, **Usage: Advanced**, **API Reference**, **Implementation Notes**. Hard constraints: ≥200 words excl. code; both simple AND advanced examples mandatory; code must compile with real imports; no marketing/placeholder text; update docs when code changes. ### Vitest / WSL2 - **Use `createTestConfig()` from `@suaveplan/testing/config`** for vitest configs. For configs needing aliases/plugins, write standalone with `pool: 'forks'` + `setupFiles: ['@suaveplan/testing/polyfills']`. - **NEVER `mergeConfig` with `baseVitestConfig`** — missing polyfills cause `crypto is not defined`. - **`vmThreads` and `threads` pools both fail in Bun on WSL2** — use default `forks`. - **`fileParallelism: false`** required for browser tests. - **SurrealDB**: check `error?.code === 'ConnectionRefused' || error?.message?.includes('Unable to connect')`. ### Code Organization - **Universal**: ZERO browser/React deps | **Browser**: React/DOM ok | **Server**: Node.js ok. - Co-locate tests with source, `.md` docs per implementation file. ### Dependencies - `workspace:^` for internal deps, Bun catalogs for external. - `"sideEffects": false` on all pure library packages. ## Quick Commands ```bash bunx turbo test --filter=@suaveplan/ # Test one package bunx turbo test:coverage --filter=@suaveplan/ # Coverage for one package bunx turbo lint --filter=@suaveplan/ # Lint one package bunx turbo typecheck --filter=@suaveplan/ # Type check one package bunx turbo lint typecheck test --filter=@suaveplan/ # Pre-publish gate bunx turbo test # All tests (no DB) bunx turbo lint typecheck # All lint+types ```