Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,224 @@
# OpenSpec Change: folder-reorg-by-domain
- **Change ID**: folder-reorg-by-domain
- **Scope**: Monorepo-wide structural change
- **Status**: PROPOSED
- **Date**: 2026-04-25
---
## Summary
Replace the runtime-tier folder split (`universal/`, `browser/`, `react/`, `api/`, `r3f/`, `server/`, `finance/`, `mcp/`, `python/`, `gaming/`) with a **domain-first** layout where every folder corresponds 1:1 to a plugin in the upcoming `suaveplan-skills` marketplace. Tier becomes a per-package property (declared via `package.json` deps, `exports`, and the `"browser"` field) rather than a directory boundary.
Concurrently:
1. Retire `@suaveplan/overview` (manifest browser library) and replace with a generated `MANIFEST.md` at the repo root.
2. Retire `FOLDERS.yml` (replaced by the new layout itself + `MANIFEST.md`'s tier-overlay view).
3. Update every `CLAUDE.md` and `openspec/AGENTS.md` path reference from `universal/<domain>/<pkg>` / `packages/<tier>/<pkg>` to `packages/<plugin>/<pkg>`.
4. Add a `monorepo-structure` capability spec codifying the rules.
Genesis currently has only ~21 packages on disk, so the migration cost is at its lowest. Every package shipped under the legacy layout is one more `git mv` later.
---
## Motivation
The tier-first layout was a quick first cut that has not held up:
- **Cross-tier domains are scattered.** `drive` lives in `universal/storage/`, `drive-webrtc` in `browser/network/`, `react-drive-sharing` in `react/platform/`, and a future `api-plugin-file-upload` would land in `api/data/` — four directories for one feature surface.
- **The same redundancy exists for booking, dmx, audio, video, geo, and almost every gaming feature** (universal core + r3f renderer + react UI + api plugin live in 3–4 folders).
- **`r3f/` is a deprecated category by `FOLDERS.yml`'s own admission** — gaming r3f packages were already relocated into `gaming/`. The remaining three (`r3f-earth`, `r3f-booking`, `r3f-dmx`) are stranded.
- **Tier signal is redundant.** Whether a package is browser-only is determined by `package.json` (`"browser"` field, browser-only deps); the directory adds nothing.
- **Plugin marketplace coupling.** The forthcoming `suaveplan-skills` marketplace ships ~50 plugins, each a vertical slice across tiers. If folders mirror plugins, generating the marketplace, scaffolding new packages, and onboarding contributors all collapse to one mental model.
---
## Design
### New folder layout
```text
packages/
<plugin-name>/
<package-name>/
package.json
tsconfig.json
vitest.config.ts
src/
tests/
README.md
```
Plugin names match the `suaveplan-<plugin>` keys without the `suaveplan-` prefix. Inside a plugin folder, package directory names match the package's npm name without the `@suaveplan/` prefix.
### Plugin → package assignment (51 plugins, all 356 current + 22 future packages)
#### Foundation
| Folder | Packages |
|---|---|
| `packages/foundation/` | error, types, typescript-config |
| `packages/observability/` | logger, opentelemetry, profiler, audit-logging, network-observability, analytics-browser |
| `packages/primitives/` | bytes, timing, datetime, mime, serialize, diff, templates, utils, json, bitpacker |
| `packages/i18n/` | i18n, locale-data, react-translate |
| `packages/validation/` | validation, schema-registry |
| `packages/control-flow/` | retry, idempotency, fsm, undo |
| `packages/config/` | env, config, feature-flags |
| `packages/events/` | events, events-metrics, events-otel, events-schema, events-transport, event-sourcing, broadcast-channel |
| `packages/streams/` | streams, streams-metadata, streams-chunk-queue, queue, queue-distribution |
| `packages/random/` | pseudo-random, random, noise |
#### Crypto / Auth / Vault
| Folder | Packages |
|---|---|
| `packages/crypto/` | crypto, crypto-utils, crypto-hash, crypto-curve, crypto-cipher, crypto-sodium, crypto-browser, crypto-keys, crypto-vault, react-crypto, security-codes |
| `packages/auth/` | auth, permissions, jwt-tenant, rate-limiter, oauth-client, slsa, password-formats, macos-keychain, react-auth, react-auth-whitelabel, react-permissions, react-consent-overlay, api-plugin-auth, api-plugin-user, api-plugin-tenant, api-plugin-admin, server-keys, sandbox |
| `packages/vaulted/` *(MIGRATION.md future)* | keys, vault, vault-sync, srp, otp, cbor, webauthn, native-messaging, password-strength, form-detection, site-icons, hibp, biometrics, password-generator, api-plugin-vault |
#### Data / Storage
| Folder | Packages |
|---|---|
| `packages/database/` | db, db-sqlite, surrealdb, cache, cache-memory, cache-redis, cache-browser, migration, seed, api-plugin-database |
| `packages/storage/` | storage, storage-s3, storage-file, storage-browser, storage-browser-opfs |
| `packages/drive/` | drive, drive-sharing, drive-webrtc, react-drive-sharing, react-file-upload, api-plugin-file-upload, packer, packer-browser |
| `packages/data/` | etl, crdt, dedup, domain-normalizer, pagination, data-masking, ab-testing, api-plugin-import, api-plugin-export, api-plugin-graphql, api-plugin-analytics |
| `packages/search/` | search, api-plugin-search |
#### Network
| Folder | Packages |
|---|---|
| `packages/network-core/` | network, network-bootstrap, network-failover, network-governance, network-protocol, network-quality, network-registry, network-assignment, network-testing, network-websockets, network-standby-transport, service-discovery |
| `packages/network-p2p/` | network-webrtc, network-libp2p, network-libp2p-server, network-hyperswarm, network-trystero-server, network-gundb-server, network-discovery-crdt, network-discovery-gundb, network-discovery-hybrid, network-discovery-peerjs, network-discovery-trystero, network-discovery-webtorrent |
#### API / Platform / UI / Workflow
| Folder | Packages |
|---|---|
| `packages/api/` | api, api-shared, api-gateway, websocket-gateway, api-docs, api-schemas, docs, sitemap, react-docs, api-plugin-rate-limit, api-plugin-audit, api-plugin-sse, api-plugin-webhook, api-plugin-vatdash-bridge, webhook-client, api-plugin-cms, api-plugin-site, api-plugin-events |
| `packages/platform/` | cli, electrobun, readline, web-workers, pwa, clipboard, macos-contacts, react-iphone, linter, health-check, job-scheduler, caddy-imgproxy, iconz |
| `packages/react-ui/` | react-ui, react-modal, react-dnd, react-hotkeys, react-error-boundary, react-notifications, react-loading, react-store, react-charts, react-timeline, react-color-picker, react-calendar, react-rich-text, react-command-palette, react-kanban, react-tour, react-skeleton, react-infinite-scroll, react-tree-view, react-data-table, react-virtual |
| `packages/workflow/` | workflow, rules, form-builder, react-forms, react-admin-forms, react-rule-builder, react-wizard |
#### Communications
| Folder | Packages |
|---|---|
| `packages/email/` | email-processing, email-templates, campaigns, contacts, suppression, delivery-tracking, dmarc, audience-rules, emailer, react-campaigns, react-contacts, api-plugin-campaigns, api-plugin-contacts |
| `packages/messaging/` | sms, sms-providers, notification-channel, api-plugin-messaging, api-plugin-notifications |
| `packages/social/` | slack-client, discord-client, telegram-client, imessage-adapter, message-bridge, react-social, react-ui-social, api-plugin-social |
#### Commerce / Logistics
| Folder | Packages |
|---|---|
| `packages/payment/` | payment, payment-providers, license, api-plugin-payment, api-plugin-banking, api-plugin-subscription, api-plugin-store |
| `packages/currency/` | currency, currency-providers, money, cryptocurrency |
| `packages/booking/` | booking, r3f-booking |
| `packages/logistics/` | ports, react-port-tracking, api-plugin-logistics, api-plugin-customs, api-plugin-procurement, api-plugin-warehouse-ops, api-plugin-asset-register, api-plugin-inventory, api-plugin-gtap, api-plugin-port-tracking |
#### Geo / Astronomy
| Folder | Packages |
|---|---|
| `packages/geo/` | geo, geo-earth, geo-planet, heightmap-tiles, osm-buildings, r3f-earth, react-map |
| `packages/astronomy/` *(universe spec)* | universe, solar-system, stars, tides |
#### Media (per modality)
| Folder | Packages |
|---|---|
| `packages/media/` | media, metadata, exif |
| `packages/image/` | image, image-quantisation, compress-image, react-image |
| `packages/svg/` | compress-svg, emblem-solver |
| `packages/fonts/` | font-compress, font-decompress, font-convert, font-subset, react-font-decompress |
| `packages/video/` | video, video-thumbnails, react-video |
| `packages/audio/` | audio-engine, audio-plugins-fx, audio-controllers, audio-sprite-packer, voice, voice-elevenlabs, react-audio, react-audio-player, react-audio-stream, react-audio-fingerprint, python-audio-fingerprint |
| `packages/pdf/` | pdf, react-pdf |
| `packages/dmx/` | dmx, r3f-dmx |
| `packages/codes/` | barcode, qrcode, qrcode-scan |
#### Dev / MCP
| Folder | Packages |
|---|---|
| `packages/dev/` | testing, testing-dom, testing-e2e, testing-integration, testing-integration-surrealdb, testing-integration-redis, testing-integration-postgres, testing-integration-mailpit, testing-integration-typesense, testing-integration-garage-s3, test-vite, storybook-test-utils, wip |
| `packages/mcp/` | mcp |
#### Gaming (per gaming subdomain)
| Folder | Packages |
|---|---|
| `packages/gaming-engine/` | ecs, game-loop, spatial-hash, game-persistence, game-server, game-state-schemas, controller, react-controller, api-plugin-game-server, api-plugin-game-persistence |
| `packages/gaming-rigs/` | character-physics, vehicle-physics, mixamo, bone-mapping, ik-solver, animation-events, character-vehicle-picker, r3f-character, r3f-character-vehicle, r3f-character-vehicle-picker, r3f-animation, r3f-vehicle, r3f-controller |
| `packages/gaming-combat/` | combat, weapons, hitbox, destructibles, r3f-combat |
| `packages/gaming-ai/` | behavior-tree, npc, fauna, r3f-npc, r3f-pathfinding |
| `packages/gaming-narrative/` | dialogue, quest, crafting, progression, economy, react-dialogue, react-crafting |
| `packages/gaming-world/` | building, day-night *(deprecated)*, weather, fruit-machine, r3f-building, r3f-buildings, r3f-environment, r3f-vegetation, r3f-water, r3f-weather, r3f-terrain, r3f-world, gaming-universe, gaming-environment-lighting |
| `packages/gaming-multiplayer/` | lobby, party, chat, emotes, leaderboard, r3f-networking, api-plugin-matchmaking, api-plugin-anticheat, react-social-game, api-plugin-bank, api-plugin-virtual-currency, react-bank |
| `packages/gaming-ui/` | react-game-hud, react-game-map, react-game-settings, r3f-ui, r3f-minimap, r3f-inventory |
| `packages/gaming-effects/` | r3f-particles, r3f-shaders, r3f-parallax, r3f-audio, r3f-lod, r3f-performance, r3f-camera, r3f-number-plate, r3f-emulator, r3f-xr |
| `packages/gaming-physics/` | r3f-physics-core, r3f-physics-rapier, r3f-physics-cascade |
---
## MANIFEST.md (replaces @suaveplan/overview)
A repo-root `MANIFEST.md` is generated by `scripts/generate-manifest.ts` from on-disk truth (each package's `package.json`). It provides:
1. **Plugin × package table** — every plugin folder, every package within, dependency count, coverage status, npm version.
2. **Tier-overlay view** — packages grouped by inferred tier (universal / browser / react / r3f / server / python) for the rare case someone wants the old listing. Tier is inferred from `engines`, `"browser"` field, peer deps (`react`, `@react-three/fiber`), and `bin` entries.
3. **Dependency graph** — DOT-format adjacency list embedded in a fenced code block; can be piped to Graphviz.
4. **Stale-manifest CI check** — a CI job runs `bun scripts/generate-manifest.ts --check` and fails if the committed `MANIFEST.md` differs from the regenerated output.
`@suaveplan/overview` is deleted from `packages/` (it is currently published at `0.1.0` to Verdaccio; per genesis convention pre-1.0.0 deletion is a `bun scripts/unpublish.ts --package @suaveplan/overview` operation).
---
## Migration approach
**Single bulk migration in one PR.** A long-running rename branch is the worst of both worlds; everything in `packages/` moves at once, in one mechanical commit, followed by a configuration-update commit.
1. **`scripts/migrate-folders.ts`** — reads the assignment table from this proposal (or a sibling `assignment.yml`), runs `git mv packages/<old>/<pkg>/ packages/<plugin>/<pkg>/` for every package, and updates root `package.json` `workspaces` glob (`packages/*/*` covers every plugin/package pair).
2. **Path updates in configs:**
- `turbo.json` — no changes needed (uses workspace globs).
- Every `vitest.config.ts` referencing `path.resolve(__dirname, '../../testing/...')` — paths are auto-correct because they're relative to each package and the new layout still has `packages/<plugin>/<pkg>/` as the same depth.
- `tsconfig.json` `paths` mapping — regenerate.
- Per-package `package.json` exports — unchanged (relative to package root).
3. **Doc updates:**
- `CLAUDE.md` package list paths.
- `openspec/AGENTS.md` — every `universal/<domain>/<pkg>` reference becomes `packages/<plugin>/<pkg>`.
- Existing OpenSpec changes' proposals — leave historic; only update `tasks.md` for in-flight changes.
4. **Delete `FOLDERS.yml`.**
5. **Generate `MANIFEST.md`** for the first time, commit it.
6. **Add CI check** `bun scripts/generate-manifest.ts --check`.
---
## Out of scope
- **Renaming any package.** Only directories move; npm names stay identical.
- **Changing exports or APIs.** Pure structural change.
- **Migrating off Verdaccio for republish.** Republishes happen as part of normal pre-publish gates after the move.
---
## Impact
- **Every package on genesis** (~21 currently shipped + ~5 in flight) gets a `git mv`. No code change required inside packages.
- **All in-flight OpenSpec changes** that reference target paths (`enterprise-booking`, `enterprise-testing-*`, etc.) need their `Target path:` line updated. This is mechanical.
- **Existing `@suaveplan/overview` consumers** (none in genesis source — it was a leaf manifest reader) lose the package; the replacement is reading `MANIFEST.md` directly or running `scripts/generate-manifest.ts`.
- **Future `suaveplan-skills` marketplace** can be generated directly from the folder layout: each `packages/<plugin>/` becomes one plugin manifest.
---
## References
- `FOLDERS.yml` (current layout, to be deleted)
- `MIGRATION.md` (Vaulted future packages — assigned to `packages/vaulted/`)
- `docs/superpowers/specs/2026-04-25-universe-family-design.md` (universe family — assigned to `packages/geo/` + `packages/astronomy/` + `packages/gaming-world/`)
- `../suaveplan/README.md` (full 356-package inventory, source for assignment table above)
- `CLAUDE.md` § "Packages" — every path reference will be updated.

View File

@@ -0,0 +1,86 @@
## ADDED Requirements
### Requirement: Domain-first folder layout
The monorepo SHALL organise packages into domain folders that map 1:1 to plugins in the `suaveplan-skills` marketplace. The layout is `packages/<plugin>/<package>/` where `<plugin>` is the marketplace plugin name without the `suaveplan-` prefix and `<package>` is the npm name without the `@suaveplan/` prefix. Tier (universal / browser / react / r3f / server / python) is NOT a directory — it is determined per-package by `package.json` deps, the `"browser"` field, peer deps, and `engines`.
#### Scenario: Every package lives under a plugin folder
- **WHEN** any package directory is inspected
- **THEN** its path is `packages/<plugin>/<package>/` AND `<plugin>` matches a plugin defined in the marketplace assignment manifest
#### Scenario: No tier-named top-level folders
- **WHEN** the repository root is listed
- **THEN** there are no `universal/`, `browser/`, `react/`, `r3f/`, `api/`, `server/`, `finance/`, `mcp/`, `python/`, or `gaming/` directories
#### Scenario: Cross-tier domain co-location
- **WHEN** a domain has packages spanning multiple tiers (e.g. `drive` with universal core, browser P2P plugin, react UI, and api plugin)
- **THEN** all of those packages live under the same plugin folder (`packages/drive/`)
### Requirement: Plugin → package assignment uniqueness
Every package SHALL appear in exactly one plugin folder. No package may be present in two plugins.
#### Scenario: Assignment manifest has unique entries
- **WHEN** `scripts/folder-reorg/assignment.yml` is parsed
- **THEN** the union of all packages across all plugins contains no duplicates
### Requirement: Generated MANIFEST.md replaces @suaveplan/overview
The repository SHALL contain a generated `MANIFEST.md` at the root that lists every plugin, every package, the inferred tier per package, the dependency graph, and a tier-overlay view. The manifest is regenerated by `bun scripts/generate-manifest.ts` and a `--check` mode validates that the committed file is up-to-date.
#### Scenario: MANIFEST.md is up to date
- **WHEN** `bun scripts/generate-manifest.ts --check` is run
- **THEN** it exits with status 0 AND the committed `MANIFEST.md` matches the regenerated output byte-for-byte
#### Scenario: @suaveplan/overview is absent
- **WHEN** the repository is searched for `@suaveplan/overview`
- **THEN** no `package.json` declares it as a dep AND no source file imports it AND no folder named `overview/` exists under `packages/`
### Requirement: FOLDERS.yml is removed
`FOLDERS.yml` SHALL NOT exist at the repository root. The folder layout is self-describing via the `packages/` tree and the per-tier overlay lives in `MANIFEST.md`.
#### Scenario: FOLDERS.yml absent
- **WHEN** the repository root is listed
- **THEN** no file named `FOLDERS.yml` is present
### Requirement: Tier inference from package.json
`scripts/generate-manifest.ts` SHALL infer each package's tier deterministically from its `package.json` and source layout, in this priority order: python → r3f → react → browser → server → universal.
- **python**: package directory name has prefix `python-` OR `package.json` has a top-level `"python"` field.
- **r3f**: `peerDependencies` includes `@react-three/fiber` OR `three`.
- **react**: `peerDependencies` includes `react` (and tier is not r3f).
- **browser**: `package.json` has a `"browser"` field OR `engines` lacks `node`.
- **server**: `bin` field is set OR direct dependencies include `bun:sqlite`, `node:fs`, `node:net`, `node:cluster`, `pg`, `ioredis`, or similar Node-only modules.
- **universal**: none of the above match.
#### Scenario: Tier inference is deterministic
- **WHEN** `scripts/generate-manifest.ts --check` is run twice without source changes
- **THEN** both runs produce identical tier classifications for every package
### Requirement: Path references in CLAUDE.md and openspec/AGENTS.md updated
`CLAUDE.md` and `openspec/AGENTS.md` SHALL reference packages via `packages/<plugin>/<pkg>/` paths. References to legacy `universal/<domain>/<pkg>/` or `packages/<tier>/<pkg>/` paths SHALL NOT exist in either file.
#### Scenario: No legacy path references
- **WHEN** `CLAUDE.md` and `openspec/AGENTS.md` are searched for the regex `(^|[^a-z])(universal|browser|react|r3f|server|finance|mcp|python|gaming)/[a-z]`
- **THEN** zero matches are found in either file
### Requirement: Migration is reversible until merged
The folder migration SHALL execute via `git mv` (preserving file history) in a single commit, allowing `git revert` to restore the legacy layout if a regression is found before merge.
#### Scenario: File history preserved
- **WHEN** `git log --follow packages/<any-plugin>/<any-existing-pkg>/src/<any-file>.ts` is run after migration
- **THEN** the log shows commits from before the migration (i.e. `git mv` preserved history, not `rm`+`add`)

View File

@@ -0,0 +1,121 @@
# Tasks: folder-reorg-by-domain
**Change ID**: folder-reorg-by-domain
**Scope**: Monorepo-wide structural change
---
## 1. Pre-flight
- [ ] Confirm clean working tree (`git status` reports nothing) and no in-flight worktrees with uncommitted work (`git worktree list` then `git status` in each).
- [ ] Confirm all currently-published packages on Verdaccio have green pre-publish gates (snapshot the list — `bun scripts/list-published.ts` if available, otherwise grep `npmjs.fq.io`).
- [ ] Tag the pre-migration state: `git tag pre-folder-reorg`.
---
## 2. Assignment manifest
- [ ] Create `scripts/folder-reorg/assignment.yml` — machine-readable copy of the plugin → package table from `proposal.md`. Format: `<plugin-name>: [<pkg1>, <pkg2>, ...]`.
- [ ] Add a sanity check: every package referenced in `assignment.yml` exists either on disk in genesis OR in `MIGRATION.md` (future) OR in the universe spec (future). Fail fast if any package is unaccounted for.
- [ ] Add a uniqueness check: every package appears in exactly one plugin.
---
## 3. Migration script
- [ ] Write `scripts/folder-reorg/migrate-folders.ts`:
- Reads `assignment.yml`.
- For each package currently on disk under `universal/<domain>/<pkg>/`, runs `git mv universal/<domain>/<pkg>/ packages/<plugin>/<pkg>/`.
- Skips packages listed in `assignment.yml` but not yet on disk (future packages from MIGRATION.md / universe spec).
- Logs every move; outputs a summary.
- [ ] Dry-run mode (`--dry-run`) prints planned moves without executing.
---
## 4. Execute migration
- [ ] Run `bun scripts/folder-reorg/migrate-folders.ts --dry-run`. Review output.
- [ ] Run `bun scripts/folder-reorg/migrate-folders.ts`. Single commit: `chore(structure): move all packages to domain-first layout`.
- [ ] Verify `packages/` contains exactly the plugin folders from `proposal.md`.
- [ ] Verify legacy folders (`universal/`, etc.) are empty or removed.
---
## 5. Workspace + tooling updates
- [ ] Root `package.json` — `workspaces` glob: ensure `packages/*/*` covers the new layout. Remove any tier-specific globs.
- [ ] Root `tsconfig.json` — regenerate `paths` mapping if it's not glob-based.
- [ ] `turbo.json` — no change expected (uses workspace inheritance); verify by running `bunx turbo run build --dry-run`.
- [ ] Run nuclear clean install: `rm -rf node_modules bun.lockb && find . -type d -name "node_modules" -exec rm -rf {} + && bun install --force`.
- [ ] Run full lint+typecheck+test sweep: `bunx turbo lint typecheck test`. All packages must stay green — folder move should be transparent to package contents.
---
## 6. Documentation updates
- [ ] `CLAUDE.md` — replace every `universal/<domain>/<pkg>` path reference with `packages/<plugin>/<pkg>`. Update the Packages section to describe the new layout. Update Quick Commands examples.
- [ ] `openspec/AGENTS.md` — replace every `universal/<domain>/<pkg>` and `packages/universal/<pkg>` path reference. Update file-size, banned-pattern, and missing-`.md` scan commands.
- [ ] `openspec/project.md` — update if it references folder layout.
- [ ] In-flight OpenSpec changes (`enterprise-*`) — update only the `Target path:` line in each `proposal.md` if the change is not yet archived. Already-archived changes stay frozen.
---
## 7. Delete FOLDERS.yml
- [ ] `git rm FOLDERS.yml`.
- [ ] Add a one-line note to `CLAUDE.md` Packages section: "Folder layout is domain-first; see `MANIFEST.md` for the per-tier overlay view."
---
## 8. Retire @suaveplan/overview
- [ ] `git rm -r packages/data/overview/` (it has been reassigned to foundation but is being retired — confirm by re-reading `proposal.md` and removing it from the foundation row in `assignment.yml` before running the migration script).
- [ ] Unpublish from Verdaccio: `bun scripts/unpublish.ts --package @suaveplan/overview` (or manual `npm unpublish @suaveplan/overview --registry https://npmjs.fq.io --force`).
- [ ] Search the rest of genesis for any `import ... from '@suaveplan/overview'` or `"@suaveplan/overview"` dependency entries; remove them. Expected: zero matches (the package was a leaf with no in-repo consumers).
- [ ] Remove the `enterprise-overview` OpenSpec archive line from any index if one exists.
---
## 9. MANIFEST.md generator
- [ ] Write `scripts/generate-manifest.ts`:
- Walks `packages/<plugin>/<pkg>/package.json` for every package.
- Emits `MANIFEST.md` at repo root with sections:
1. **Plugins** — table of `plugin | package count | total deps`.
2. **Packages** — table of `npm name | plugin | tier (inferred) | version | dep count`.
3. **Tier overlay** — packages grouped by inferred tier (universal / browser / react / r3f / server / python). Inference rules:
- `python` if `package.json` has `"python"` field or path contains `python-`.
- `r3f` if `peerDependencies` contains `@react-three/fiber`.
- `react` else if `peerDependencies` contains `react`.
- `browser` else if `package.json` has `"browser"` field or `engines` excludes node.
- `server` else if `bin` is set OR depends on `bun:sqlite` / `node:fs` / similar.
- `universal` otherwise.
4. **Dependency graph** — DOT block listing `<pkgA> -> <pkgB>` for every workspace dep edge.
- `--check` mode regenerates in-memory and diffs against on-disk `MANIFEST.md`; exits non-zero on diff.
- [ ] Co-locate `scripts/generate-manifest.md` documentation per genesis docs rules.
- [ ] First-time generation: `bun scripts/generate-manifest.ts > MANIFEST.md`. Commit.
---
## 10. CI gate
- [ ] Add `bun scripts/generate-manifest.ts --check` as a CI step in the root pipeline.
- [ ] Add the same as a `pre-commit` hook entry (optional — if hooks are configured).
---
## 11. Verify
- [ ] `bunx turbo lint typecheck test` — all green.
- [ ] `bunx turbo test:coverage --filter=@suaveplan/*` — every package still at 100%.
- [ ] `bunx turbo build` — every package still builds.
- [ ] `bun scripts/generate-manifest.ts --check` — clean.
- [ ] `git status` — only intentional changes (folder moves, doc updates, MANIFEST.md, removed FOLDERS.yml, removed overview package).
- [ ] Spot-check three packages from different plugins (e.g. `packages/core/error/`, `packages/gaming-engine/ecs/`, `packages/drive/drive-webrtc/`) — `package.json` valid, `vitest.config.ts` resolves, tests pass.
---
## 12. OpenSpec archival
- [ ] Fold `specs/monorepo-structure/spec.md` (this change's spec delta) into `openspec/specs/monorepo-structure/spec.md`.
- [ ] Move `openspec/changes/folder-reorg-by-domain/` → `openspec/archive/2026-04-25-folder-reorg-by-domain/`.