# Suaveplan Genesis — Project Conventions Authoritative project-wide context for all OpenSpec changes on the `genesis` branch. Every proposal inherits these rules. ## Mission Suaveplan is a monorepo of composable `@suaveplan/*` packages. The `genesis` branch is a bottom-up rebuild: every package lands fresh at enterprise quality, starting from the leaves. Designs are informed by the matching `enterprise/*.md` specification in the `main` worktree (`/mnt/s/web/suaveplan/enterprise/`). Packages start at version `0.1.0`; the Verdaccio private registry is wiped and repopulated from genesis output. No package on genesis is "enterprise-ready" until its acceptance criteria (coverage, docs, structured errors, Zod schemas, observability, property tests, benchmarks, security review, full export surface) are all green. ## Stack | Area | Technology | |------|------------| | Runtime | Bun ≥ 1.3.0 (TypeScript native, ESM-first) | | Monorepo | Turborepo + Bun workspaces (`//`), catalogs, overrides | | Registry | Verdaccio at `https://npmjs.fq.io/` (auth via `NPM_TOKEN` env var) | | Lint/Format | Biome (strict base; no per-package overrides unless justified) | | Unit/Integration Tests | Vitest (istanbul coverage) | | E2E Tests | Playwright | | Bundling | Vite, tsup, `Bun.build` — **never `tsc` directly** | | Property tests | fast-check | | Benchmarks | mitata | | Runtime validation | Zod (external catalog dep, not via `@suaveplan/schema-registry`) | | Observability | `@opentelemetry/api` (external) until `@suaveplan/opentelemetry` ships | ## Package taxonomy Genesis starts empty. Packages land under `packages///`, where `` is one of 18 super-categories (foundation, persistence, networking, communication, api-stack, identity, security-stack, observability, media, ui, threejs, localization, geospatial, money, commerce, testkit, devtools, gaming) and `` is a domain folder defined in [`FOLDERS.md`](./FOLDERS.md). Tier (universal / browser / react / r3f / server / python) is inferred per-package from `package.json` — it is never encoded in the directory path. Packages live at `packages///` (e.g. `packages/security-stack/crypto/crypto`, `packages/foundation/core/error`). Workspace glob: `packages/*/*/*`. Category → plugin → package map lives in `scripts/folder-reorg/assignment.yml` and is summarised in `MANIFEST.md` at the repo root. Run `bun scripts/folder-reorg/generate-manifest.ts` to refresh `MANIFEST.md` after any package add, remove, or category move. ## Dependency-layer order Build packages in dependency-order waves. A package cannot land until every `@suaveplan/*` workspace dep it needs is already enterprise on genesis: 1. **Layer 0** — testing-infrastructure packages (`@suaveplan/testing`, `testing-dom`, `testing-e2e`). These are forbidden from depending on ANY `@suaveplan/*` package — see "Non-negotiable rules" below. 2. **Layer 1** — true leaves with no workspace deps (`error`, `datetime`, candidate `opentelemetry` adapter). 3. **Layer 2+** — packages that depend on Layer 1 (`schema-registry`, `utils`, etc.). ## Non-negotiable rules 1. **Never run `tsc` directly.** Use Vite/tsup via `bunx turbo build`. Bun runs `.ts` natively. 2. **No mocks.** Real services only. `vi.mock` is unreliable in Bun ESM — use dependency injection. No `vi.mock` / `jest.mock` in production tests. 3. **Bun `overrides` with exact versions.** Catalogs for external deps (`catalog:`), `workspace:^` for internal. **Never use bare version strings** (e.g. `"^1.2.3"`) in `package.json` — always reference a catalog entry. If a catalog key does not exist for a dep, add it to the root `package.json` `catalog` block first. Note: some Suaveplan skills say `workspace:*` — genesis uses `workspace:^` exclusively. 4. **Never re-export external deps** for convenience — import directly from source. 5. **Never auto-commit or push** without user approval. Never `--no-verify`. 6. **Always use absolute paths** in tool calls. Read files before editing. 7. **No stubs, no TODOs, no placeholder implementations** in shipped code. Enterprise-grade only. 8. **Professional honesty** — no marketing language, no fabricated metrics. 9. **Testing-infrastructure packages** (`@suaveplan/testing`, `testing-dom`, `testing-e2e`) MUST NOT depend on any `@suaveplan/*` workspace package. External catalog deps only. Circular-use-of-testing otherwise. 10. **Preserve the full public surface during rewrites.** Trimming is allowed only when code is duplicated elsewhere in-repo or can be replaced by an existing `@suaveplan/*` library. Never trim on "probably unused" grounds. 11. **Subpath exports per feature module.** Every feature directory under `src/` must have its own entry in the `exports` map in `package.json` (e.g. `"./retry/retry"`, `"./circuit-breaker/circuit-breaker"`). A single `"."` barrel export is not sufficient — tree-shaking requires granular subpaths. 12. **`@vitest/coverage-istanbul` must be in `devDependencies`.** Use `catalog:testing` or equivalent. The `provider: 'istanbul'` setting silently falls back to v8 if the package is missing. 13. **Clean workspace on task completion.** Remove any scratch files, temporary outputs, or debugging artifacts before declaring a task done. ## Pre-publish gate (non-negotiable) Before any `bun scripts/publish.ts --package @suaveplan/`: - `bunx turbo lint typecheck test --filter=@suaveplan/` MUST be green. - `bunx turbo test:coverage --filter=@suaveplan/` MUST meet the coverage threshold for the package layer (see Quality gates below). - A full-package `turbo test` run is required — a single-file `vitest run` is not a substitute. Never publish on red. ## Quality gates (per package) | Gate | Threshold | |------|-----------| | Test coverage — every package, no exceptions | **100%** statement + branch + function + line (istanbul). No "foundation only" carve-out, no degraded-situation floor. Pre-publish gate hard-fails below 100%. | | Docs coverage | ≥ 90% (every public export has a sibling `.md`) | | Code file size | ~250 lines soft / 300 lines hard | | Test file size | 500 lines max | | Test extension | `.test.ts` (Vitest) / `.spec.ts` (Playwright E2E) | | `it()` / `test()` timeout | `{ timeout: 5000 }` sync, 30000 async | | Vitest coverage provider | `istanbul` — requires `@vitest/coverage-istanbul` in `devDependencies` | | React component | Every component has `.stories.tsx` (default + playground + variants) | | Public types | Modeled by Zod schemas exported from `*.schemas.ts` | | Error shape | Extends a structured error class with `{ code, cause, context }` | | Subpath exports | One `exports` entry per feature module for tree-shaking | | `sideEffects` | `false` (or explicit array); entry points must not import with side effects | ## Package enterprise checklist Every package is "enterprise-done" only when: - [ ] `README.md` exists at the package root (not inside `src/`) — one-paragraph description, install, quick-start, **Modules** section linking to every co-located `.md` in `src/` - [ ] Every `.ts` / `.tsx` implementation file has a sibling `.md` (≥200 words, simple + advanced examples, API reference, implementation notes) — excludes `.test.ts`, `.spec.ts`, `.types.ts` inside feature dirs, `.stories.tsx`, barrel `index.ts`, `constants/index.ts` - [ ] Every public function has Zod input/output schemas in a sibling `*.schemas.ts` - [ ] Every thrown error extends the package's structured error class with a stable `UTILS..`-style code (or equivalent namespace) and `{ cause, context }` fields - [ ] Every function reading time / randomness / iterating accepts an optional `{ clock?, rng?, signal? }` options parameter; zero-config defaults preserved - [ ] `AbortSignal` checks on every iterative helper at bounded intervals (≤ 256 items or ≤ 1 KB) - [ ] OTEL instrumentation via `@opentelemetry/api` — counters, histograms, spans on public entrypoints (no-op when no exporter registered) - [ ] fast-check property tests for pure functions covering round-trip, idempotency, associativity, boundary invariants - [ ] mitata benchmarks with baseline + CI regression gate (>10% fails) - [ ] Full public surface preserved relative to the design spec - [ ] Zero `any`, `ts-ignore`, `ts-expect-error`, `TODO`, `FIXME`, `@deprecated`, `.skip`, `.only` in `src/` - [ ] `sideEffects: false` holds; entry point imports verified to have no side effects; tree-shake test included - [ ] Subpath exports: one `exports` entry per feature module in `package.json` - [ ] `@vitest/coverage-istanbul` in `devDependencies` (catalog ref, not bare version) - [ ] React version conflict (if browser/react package): verify single React version with `find . -path "*/node_modules/react/package.json"` — use exact overrides if multiple found - [ ] Workspace clean: no scratch files, temp outputs, or debug artifacts remain - [ ] OpenSpec change validates and is archived to `openspec/archive/-/` ## Repo ↔ enterprise spec mapping Every enterprise-level package rewrite starts by: 1. Reading the matching `enterprise/.md` on the main branch (`/mnt/s/web/suaveplan/enterprise/.md`). 2. Reading the current implementation on the main branch for shape-preservation (export inventory). 3. Creating `openspec/changes/enterprise-/` with `proposal.md`, `design.md`, `specs//spec.md`, and `tasks.md` — **adapting** each enterprise-doc clause to the constraints above (especially rule #9: no `@suaveplan/*` workspace deps in testing-infrastructure packages). ## Vitest / WSL2 quirks - Use `createTestConfig()` from `@suaveplan/testing/config` once `@suaveplan/testing` lands. - **Use `forks` pool.** `vmThreads` and `threads` both fail in Bun on WSL2. - **`fileParallelism: false`** required for large browser test suites. - SurrealDB connection errors use `'ConnectionRefused'` (not `'ECONNREFUSED'`). ## Package lifecycle - **New package:** land via an `enterprise-` OpenSpec change. Package starts at version `0.1.0`. - **Edit:** no version bump during genesis; version stays `0.1.0` until graduation. - **Publish:** `bun scripts/publish.ts --package @suaveplan/` after pre-publish gate passes. - **Wipe + republish:** Verdaccio is wiped once genesis is sufficiently complete; republish happens as part of the cutover. ## Commonly-used commands ```bash # Single package bunx turbo test --filter=@suaveplan/ bunx turbo test:coverage --filter=@suaveplan/ bunx turbo lint typecheck test --filter=@suaveplan/ # pre-publish gate # Workspace-wide bunx turbo lint typecheck bun run gate # all packages pre-publish gate # Turborepo advanced filtering bunx turbo test --filter=@suaveplan/... # pkg + everything it depends on bunx turbo test --filter=...@suaveplan/ # pkg + everything that depends on it bunx turbo test --filter=...[main] # packages changed since main branch bunx turbo test --filter=...[HEAD^1] # packages changed in last commit bunx turbo test --filter=@suaveplan/{pkg-a,pkg-b} # multiple packages (OR) bunx turbo test --filter=!@suaveplan/ # exclude one package # Publish bun scripts/publish.ts --package @suaveplan/ # publish one package # Dependency management — nuclear clean install (use after overrides changes) rm -rf node_modules bun.lockb && find . -type d -name "node_modules" -exec rm -rf {} + && bun install --force # Profiling (Bun ≥ 1.3.7 — outputs Markdown for LLM analysis) bun --cpu-prof-md run