Files
suaveplan/openspec/archive/2026-04-25-folder-reorg-by-domain/proposal.md
2026-05-27 23:29:53 +01:00

225 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.