# Monorepo Architecture & Organization Audit — 2026-07-16

Deep audit of the Oshun monorepo covering technical debt, architecture, DRY,
repo organization, folder structure, conventions, build system, dependencies,
CI/CD, testing, and documentation. Every finding below is backed by a measured
count or a concrete file path collected on 2026-07-16 from branch
`oshun-v1-nisaba`.

> **Meta-note:** this report was written at the repo root (the convention at the
> time — 71 sibling reports). The R-3 migration moved it, together with 53
> sibling reports, to `docs/audits/` on 2026-07-16. Tooling-parsed reports
> (`V_SERIES.md`, the `V1_V9_*` 2026-07-15 set, `DEPENDENCIES.md`, `TODOS.md`,
> `ISIS_TODOS*.md`, `ARCHITECTURE.md`, `RESPONSIBILITY_SPLIT_RECOMMENDATION.md`,
> `CONTENT_GENERATION_CAPABILITY_MATRIX.md`) and active planning docs
> (`V_SERIES_AMBIENT_RAIL*.md`) stay at root until their tooling is repointed.

---

## 0. Scale of the subject

| Metric                             | Value                                                                             |
| ---------------------------------- | --------------------------------------------------------------------------------- |
| Tracked files                      | 135,430                                                                           |
| Git pack size                      | 1.19 GiB                                                                          |
| Nx projects (`project.json`)       | 3,421 (3,007 under `libs/`)                                                       |
| Workspace `package.json` files     | 3,264                                                                             |
| Rust crates (`Cargo.toml`)         | 1,437 — **505 of them independent `[workspace]` roots**                           |
| Python projects (`pyproject.toml`) | 83                                                                                |
| tsconfig files                     | 7,044                                                                             |
| vitest configs                     | 2,654                                                                             |
| `tsconfig.base.json`               | 172 KB, 2,164 path aliases                                                        |
| Root `package.json` scripts        | 549                                                                               |
| GitHub workflows                   | 148 (27,736 LOC of YAML)                                                          |
| `libs/` domains                    | 57 (largest: neith 597 projects, kalika 192, aphrodite 184, maya 151, psyche 134) |
| `apps/` entries                    | 34                                                                                |
| Products                           | V1–V10 (ten distinct products on a shared platform) + ~50 domain libraries        |

> **V10 addendum (same day as this audit):** V10 "The Rail" (ambient companion
> layer over V1–V9) was seeded on 2026-07-16, concurrent with data collection.
> It so far consists of `V10/V_SERIES_AMBIENT_RAIL.md` +
> `V10/V_SERIES_AMBIENT_RAIL_TODOS_2026-07-16.md` (moved into the `V10/` product
> tree later on 2026-07-16, resolving their finding A-5 entries) and
> `libs/contracts/src/v10/` (channel contract + spec — correctly placed per the
> contracts convention). The `V10/` product tree now also carries
> `V10_features.md`/`V10_ARCHITECTURE.md`, so V10 does not otherwise affect the
> measurements below; it is, however, the natural first adopter of the
> single-placement convention recommended in R-8 before it grows three roots
> like its siblings.

The monorepo is polyglot (TypeScript, Rust, Python, C++/UE, Swift, Solidity) and
poly-product. Much of what follows is the natural sediment of very fast
phase-driven growth; the good news is that most of the top-payoff fixes are
mechanical.

---

## 1. Executive summary — top findings by severity

| #   | Severity     | Finding                                                                                                                                                                                                                        | Section  |
| --- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- |
| 1   | **Critical** | ~850 MB of the 1.19 GiB git pack is committed artifacts: 577 MB Swift `.build/` outputs (6,140 files), 131 MB generated HTML (3,815 files), 119 MB git-bundle backups, 24 MB Hardhat `artifacts/`                              | A-1..A-4 |
| 2   | **Critical** | DRY collapse at the utility layer: 2,844 files define their own `clamp`, 86 exported `generateId` implementations, 14 domain-local `CircuitBreaker` classes, 5 competing `sleep` implementations _inside `libs/shared` itself_ | E        |
| 3   | **High**     | 505 independent Cargo workspaces (no shared dependency catalog, `Cargo.lock` globally gitignored yet 64 committed)                                                                                                             | D-5      |
| 4   | **High**     | Deployment/IaC config split across 4 top-level dirs with **three terraform roots** (`deploy/terraform`, `infra/terraform`, `infrastructure/terraform`)                                                                         | B-2      |
| 5   | **High**     | Documentation exists in at least 8 root-level surfaces (docs/, docs-center/, DOMAINS/, systems/, platform/, 5 × \*\_WALKTHROUGH/, TODOS/, 71 root reports) with md→html twins committed for ~2,768 files                       | B-4, A-3 |
| 6   | **High**     | CI: 148 workflows, 56 of them near-identical `v4-*` clones (53-line skeleton differing only in path filters); only 1 reusable (`workflow_call`) workflow                                                                       | G        |
| 7   | **High**     | Root `package.json` carries 441 `verify:phase-N` scripts + 26 `scripts/verify-phase-*.mjs` — process artifacts fossilized in the build interface                                                                               | A-5, D-4 |
| 8   | **Medium**   | Build-target definitions are hand-rolled per project: 6,447 `nx:run-commands` expressing the same `tsc/vitest/eslint` intent ~10 different ways                                                                                | C-1      |
| 9   | **Medium**   | Python toolchain drift: `nx.json` references `{workspaceRoot}/ruff.toml` and root `pyproject.toml` that **do not exist**; 0 lockfiles for 83 Python projects                                                                   | C-3, D-6 |
| 10  | **Medium**   | Four HTTP server frameworks in production use (fastify 114, hono 67, express 19, NestJS 16 packages)                                                                                                                           | D-3      |
| 11  | **Medium**   | Test conventions split four ways (9,834 `.spec.ts` vs 5,286 `.test.ts` colocated, plus `__tests__/` and `tests/`)                                                                                                              | F-1      |
| 12  | **Medium**   | Domain-boundary governance is real but leaky: 44 depConstraints, growing allow-list, 451 untagged projects, `apps/oshun/web` opted out entirely, isis↔yemaya bidirectional coupling                                            | H        |
| 13  | **Medium**   | Four BFFs with zero shared substrate (1,987 vs 385 vs 9 vs 0 source files); `@oshun/gateway` is actually a Traefik CLI, not an HTTP layer                                                                                      | H-3      |
| 14  | **Medium**   | `scripts/isis` alone is 2,256 files (78% of scripts/), 1,088 of them near-identical `generate-v2-*` codegen shims; `apps/urania` is a fully dead app                                                                           | G-5, H-6 |
| 15  | **Low**      | CI trigger/toolchain drift: 21 jobs pin Node 24 vs `.nvmrc` 22; two "nightly" workflows have no `schedule:` trigger                                                                                                            | G-2b     |

Overall dimension health (1 = severe debt, 5 = healthy):

| Dimension         | Score     | One-line verdict                                                           |
| ----------------- | --------- | -------------------------------------------------------------------------- |
| Git/repo hygiene  | **1.5/5** | Artifacts and generated files dominate the pack                            |
| Folder structure  | **2/5**   | Strong domain idea, drowned in top-level sediment                          |
| Build system (Nx) | **3/5**   | Affected/caching/tags exist; target definitions chaotic                    |
| Dependency mgmt   | **3.5/5** | Catalog + isolated linker are genuinely good; overlap debt remains         |
| DRY               | **1.5/5** | Canonical shared libs exist but migration never finished                   |
| Conventions       | **2.5/5** | Strict TS base + commitlint exist; naming/test/docs conventions splintered |
| CI/CD             | **2.5/5** | Real affected-based CI; workflow-count explosion                           |
| Architecture      | **3.5/5** | Domain isolation mostly holds; god-files and framework spread              |
| Documentation     | **2/5**   | Enormous volume, no single navigable source of truth                       |

---

## 2. Methodology

- Full inventory passes over `git ls-files` (counts, sizes, extensions,
  directory distribution).
- Config forensics: `nx.json`, `tsconfig.base.json`, `eslint.config.js`,
  `pnpm-workspace.yaml`, `.npmrc`, `.gitattributes`, husky hooks, commitlint.
- Cross-domain import-edge mapping via scoped-import greps for 10 domains.
- Two sequential read-only exploration agents (per session-limit rules): one for
  cross-library duplication, one for apps/scripts/CI granularity.
- Executor/test/naming variance measured by hashing and tallying config files.

---

## 3. Findings

### A. Repo & git hygiene

**A-1. 577 MB of Swift build artifacts are committed.**
`libs/psyche/ios-sdk/.build/` (3,838 files) and
`apps/bellona/remote-host/macos/.build/` (2,302 files) are tracked, including
two 67 MB `data.mdb` index files and dozens of multi-MB `.pcm` module caches.
These are per-machine SwiftPM outputs; they invalidate on every Xcode/Swift
version change and bloat every clone forever (git history keeps them even after
deletion).

**A-2. 119 MB of git-bundle backups are committed.** `backups/` holds four
`.bundle` files (`lilith-*`, `yemaya-*`, Jan 2026). A git repo committed inside
a git repo is pure history bloat; these belong in object storage (the repo
already has MinIO/S3 conventions).

**A-3. 131 MB / 3,815 generated HTML files are committed.** 2,768 are exact
`.md` → `.html` twins (docs-center readers, vdocs, V1–V9 feature docs, all five
`*_WALKTHROUGH/` dirs, `DOMAINS/`), plus `vdocs-search-index.js` (1.2 MB) at the
root. The pre-commit hook (`.husky/pre-commit`) regenerates and re-stages them
on every docs commit, so every documentation change commits twice its size in
artifacts. Rendered HTML is a build output; CI already has
`vdocs-html-fresh.yml` proving it can be built on demand.

**A-4. 24 MB of Hardhat compilation artifacts are committed.**
`apps/lilith/contracts/artifacts/` (172 files, incl. two ~12 MB
`build-info/*.json`). _Correction during R-1 execution:_ the contract ABI JSONs
(1.4 MB, under `artifacts/contracts` + `artifacts/@openzeppelin`) are read at
runtime by four `apps/lilith/svc-blockchain` clients, so they are load-bearing
data and stay tracked; only `build-info/` (22.7 MB of compiler debug metadata,
referenced by nothing) is a pure artifact and was untracked.

**A-5. The repo root is a landfill.** 113 tracked root-level files, of which 71
are `.md` audit/plan/analysis reports (SCREAMING*SNAKE, dated), plus an 8 MB
`TODOS.md` \_and* a `TODOS/` directory with 247 phase files, plus dead one-off
scripts untouched since 2026-02-21 (`check-indexes.ts`, `check-schema.ts`,
`check-services.js`, `test-tara-*.ts`, `test-veritas-api.ts`,
`update-exports.js`, `.audit-rewrite.mjs`, `insights-report.md`). Domain-
specific configs also sit at root (`typedoc.kalika.json`,
`lighthouse.config.js`). `docs/audits/` already exists and is the right home for
the reports.

**A-6. LFS is configured but unused.** `.gitattributes` declares 93 LFS
patterns, yet only 20 files are actually in LFS. The 67 MB `.mdb` files, the V5
12 MB `animation_catalog.json`, and 11.5 MB
`content-coverage/seed-registry.v1.json` all live as plain git objects.

**A-7. `Cargo.lock` policy is self-contradictory.** `.gitignore:288` ignores
`Cargo.lock` globally, yet 64 lockfiles are force-added. Rust guidance is:
commit lockfiles for binaries/applications, optional for libraries — the current
state is neither, so builds of the other ~440 workspaces are not reproducible.

**A-8. Stale top-level architecture docs.** `ARCHITECTURE.md` last touched
2026-04-23 — before most of the current 57 domains existed. `DEPENDENCIES.md`
(128 KB) and `RESPONSIBILITY_SPLIT_RECOMMENDATION.md` (65 KB) similarly frozen.

### B. Folder structure & top-level taxonomy

**B-1. The top level mixes ~25 different concepts.** Products (V1–V9), platform
code (apps/, libs/, services/), infra (infra/, infrastructure/, deploy/,
docker/), docs (8+ surfaces), tooling (tools/, scripts/, testing/, tests/),
stray singletons (clients/ with one entry, integrations/ with one entry, sdks/
with three, tara/ assets, platform/ and systems/ which are actually
_documentation_), and working dirs (tmp/, dist/, models/, test-results/ —
untracked but permanently present). A newcomer cannot tell code from docs from
generated output at the root.

**B-2. Four overlapping infrastructure dirs, three terraform roots.**
`deploy/terraform` (has its own `DEPRECATED.md` but still ships main.tf +
deploy.sh), `infra/terraform` (ECS/ALB/OIDC modules — the post-Fargate-
migration active one), `infrastructure/terraform` (bootstrap/modules/env layout,
plus `infrastructure/helm` which contains a `DEPRECATED.md`). Kubernetes
manifests live in `infra/k8s`, `deploy/kubernetes`, _and_ `infrastructure/helm`.
A vendored Pulumi module hides inside `infra/terraform/iris/modules/pulumi`
(mixing IaC toolchains; `.nxignore` has to special-case it). There is no README
at any of the four roots declaring which is live.

**B-3. V-series products are fragmented across three roots each.** V3 = `V3/`
(docs+UE+ops) + `apps/v3/` (Rust services + web) + `libs/v3/` (TS libs); same
pattern for v6/v7/v8/v9 (and V2/V4/V5 keep `services/`, `web/`, `scripts/`
inside their root dirs instead). Two placement conventions exist simultaneously,
and product code is never adjacent to its docs. Path-filtered CI (56 `v4-*`
workflows) is a direct symptom of this scatter.

**B-4. Documentation has ≥8 competing surfaces.** `docs/` (6,241 files, 26 topic
subdirs incl. its own `domains/`), `docs-center/` (rendered doc portal, 305
committed HTML), `DOMAINS/` (326 files: per-domain architecture/features/
specifications md+html), `systems/` (93 per-project one-pagers), `platform/` (14
md+html), five `*_WALKTHROUGH/` dirs (1,868 md+html twins, 39 MB), root reports
(71), `TODOS.md` + `TODOS/`, plus `vdocs-*` index files at root. Domain
documentation alone exists in three places (`DOMAINS/aphrodite/*`,
`docs/domains/*`, `systems/lib-aphrodite.md`). There is no index that says which
surface is canonical.

**B-5. `services/` vs `apps/` split is arbitrary.** `services/` holds three
deployables (concordia, metis, psyche) while ~30 other deployables live under
`apps/*`; meanwhile `apps/infra` is not an app at all. `nx.json` even declares a
custom `servicesDir` in `workspaceLayout`. One convention should win.

**B-6. Naming style varies at every level.** Nested product apps
(`apps/oshun/web`) vs flat hyphenated (`apps/euterpe-studio-web`,
`apps/neith-vault`); SCREAMING_CASE doc dirs (`DOMAINS/`, `WALKTHROUGH/`) vs
lowercase (`docs/`, `docs-center/`); an orphan `libs/tsconfig.test.json` file
sitting between domain directories; `apps/urania` exists with no matching
`libs/urania` or docs entry.

### C. Build system & Nx

**C-1. Target definitions are hand-rolled 3,400 times.** Executor census: 6,447
`nx:run-commands`, 1,646 `@nx/eslint:lint`, 1,512 `@nx/vite:test`, 1,170
`@nx/js:tsc`, 148 esbuild, plus stragglers (2 × jest, 2 × `@storybook/angular:*`
— Angular is not in the stack). The same intent is spelled at least ten ways
(`tsc --noEmit` / `npx tsc --noEmit` / `pnpm exec tsc -p tsconfig.lib.json` /
`tsc -p tsconfig.build.json` / …). This defeats targetDefaults, makes cache
inputs inconsistent, and means every convention change is a 3,000-file
migration. Nx plugin inference (or a single generator

- codemod) exists precisely to avoid this.

**C-2. `parallel: 3`** in `nx.json` throttles every `run-many`/`affected` on a
box that can afford more; CI and the 8-vCPU dev box both inherit it.

**C-3. Named-input drift.** `pythonLint` references `{workspaceRoot}/ruff.toml`
and `{workspaceRoot}/pyproject.toml`; **neither file exists** (ruff invocations
live per-project as `python3 -m ruff check .`). `python` input references
`poetry.lock`; zero are tracked. Result: Python lint/test caching keys are built
from phantom files, and per-domain named-input blocks (`irisShared`,
`v3Production`, `v6Production`, `v7Production`…) accrete in `nx.json` instead of
a uniform convention.

**C-4. Boundary tags don't cover the graph.** 2,550 of 3,421 projects carry
`tags`; 451 have none (446 in `libs/neith`). The eslint `depConstraints` (44
sourceTag rules) therefore can't constrain them, and there is no wildcard
catch-all rule, so an untagged project can depend on anything. The rule is also
disabled wholesale for `apps/oshun/web` (`eslint.config.js:985`), and the
`allow` list of cross-domain exception packages keeps growing (15 entries with
phase-numbered comments).

**C-5. Two tsconfig-preset systems coexist.**
`configs/tsconfig/{base,library, node,react,service}.json` is a clean preset
layer — used by only 83 files, while ~3,300 tsconfigs extend root
`tsconfig.base.json` directly (592/600 sampled). The base is genuinely strict
(strict, verbatimModuleSyntax, noUnused\*) — good — but 324/600 sampled libs
re-declare `"strict": true` redundantly, and
`emitDecoratorMetadata`/`experimentalDecorators` are ON globally for the benefit
of 16 NestJS packages. `noUncheckedIndexedAccess` and
`exactOptionalPropertyTypes` are absent at base (already proven viable in the
mobile app).

**C-6. `tsconfig.base.json` is a global contention point.** 172 KB / 2,164
aliases, listed in `sharedGlobals`, so _every_ new library invalidates the whole
Nx graph (the pre-commit hook comment documents the 2,449-project typecheck
stampede this caused). Two aliases are dead (`@oshun/logger`, `@oshun/logger/*`
→ `libs/shared/logger` does not exist; 0 importers).

**C-7. Nx lint plugin excludes `lilith/**`, `yemaya/**`, `apps/**`\*\* — those
projects need hand-declared lint targets or silently go unlinted; combined with
C-1 heterogeneity it is impossible to say from config alone what is actually
linted.

**C-8. `nx release` config scope is near-empty (verified 2026-07-16).**
`release.projects: ["libs/*", "apps/*"]` — slash-containing patterns match
project _roots_, and almost all projects are nested two levels deep
(`libs/<domain>/<lib>`), so the globs reach only the handful of single-level
roots (`libs/contracts`, `libs/proto`, `libs/openapi`,
`apps/euterpe-studio-web`…). `release.yml` invokes
`pnpm nx release version/publish` on dispatch, and a second release mechanism
(changesets: `version-packages`/`release` scripts) coexists in `package.json`.
Widening the globs would change publish scope for ~3,300 packages, so the repair
needs an explicit decision on which mechanism owns releases — flagged, not
auto-fixed.

### D. Dependency management

**D-1. What's good:** pnpm catalog with 8,803 `catalog:` references, isolated
node-linker with curated `public-hoist-pattern`s, `save-exact`, renovate config,
a single React/Next/Expo version line (no React 18/19 split), no moment/dayjs.
This layer is healthier than most monorepos.

**D-2. Overlapping/legacy packages persist.** Both `bcrypt` and `bcryptjs` (6
users); `crypto-js` (2 users) alongside the `@noble/*` suite; `axios` (6)

- `node-fetch` (3) + native fetch wrappers (78 hand-rolled — see E); `uuid` (69
  users) + `nanoid` (32) + 86 hand-rolled `generateId`s; `jest` in 16 packages
  vs `vitest` in 2,100 (the 16 include legit Expo/RN presets, but also 2
  `@nx/jest:jest` stragglers); 103 `jest`-scoped imports inside `libs/lilith`
  alone.

**D-3. Four HTTP server frameworks.** fastify (114 packages), hono (67), express
(19), NestJS (16). Each brings its own middleware/plugin ecosystem, auth glue,
and error semantics; `libs/shared/gateway` cannot cover four stacks. No
documented decision says which is default for new services.

**D-4. 549 root scripts, 441 of them `verify:phase-N`.** Plus 10 `test:*`, 10
`openapi:*`, etc. The phase-verify family (backed by 26
`scripts/verify-phase-*.mjs`) is process history, not build interface — it
belongs in one parameterized runner (`node scripts/verify-phase.mjs 42`) or in
the TODOS tooling, not as 441 npm scripts loaded into every `pnpm run`
completion.

**D-5. Rust: 505 independent workspaces.** No root workspace, no shared
`[workspace.dependencies]` catalog across families; version specs drift
(`wgpu 29.0.1` vs `29.0.4`; `tokio 1.35/1.36/1.44/1.48/1.49`; serde spelled 6
ways). Each workspace resolves and builds its own dependency universe — massive
redundant compile time and disk (`target/` per workspace). At minimum,
domain-level umbrella workspaces (neith, maya, kalika, uzume, v3/v6/v7) with
`workspace.dependencies` would collapse most of this; the existing 119
`workspace = true` serde entries show the pattern is already understood.

**D-6. Python: 83 `pyproject.toml`, zero lockfiles, no root config.** Ruff is
invoked per-project but configured nowhere at root (see C-3). No
`uv.lock`/`poetry.lock` tracked → non-reproducible environments; the on-box
venv + `PHOEBE_SIM_PYTHON` gate pattern papers over this per session.

**D-7. `.env.example` is a 44 KB / 388-variable monolith** shared by all
products. Per-app example env files (some apps have them) with a generated root
aggregate would keep ownership clear and diffs reviewable.

### E. DRY — duplication census (evidence-sampled across `libs/`)

The platform-primitive layer (`libs/shared`, 52 `@oshun/*` libs) is real and
imported by 2,750 files (top importers: `@oshun/logging` 423, `@oshun/crypto`
146, `@oshun/database` 145, `@oshun/event-bus` 113). The debt is that the
migration to it was never finished, and the lowest-level utilities never got a
home at all:

| Pattern                 | Independent implementations                                 | Canonical exists?                                                                                                                                     | Evidence sample                                                                                                                        |
| ----------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `clamp`                 | **2,844 files** (1,234 byte-identical signature)            | **No shared math lib at all**                                                                                                                         | `libs/kuanyin/performer-protection/src/boundary-enforcement.ts:21` and 3 identical siblings                                            |
| `lerp`                  | 332 files                                                   | No                                                                                                                                                    | concentrated in nous 464, aphrodite 394, isis 257, hathor 248, calliope 238 (clamp+lerp combined)                                      |
| `generateId`/`createId` | 86 exported defs, 548 refs                                  | No general-purpose one                                                                                                                                | `libs/sophia/schemas/src/ids.ts`, euterpe/virtuoso, kuanyin                                                                            |
| Retry/backoff           | ~34 defs, 256 referencing files                             | Fragmented: 4 copies inside shared (`http-client/src/retry.ts`, `gpu-dispatcher/src/retry.ts`, `runpod-client/src/polling.ts`, `types/src/legacy.ts`) | `libs/aje/rpc/src/retry.ts`, `libs/yemaya/orchestration/src/execution/retry-manager.ts`                                                |
| `sleep`/`delay`         | 13 local + **5 competing copies inside `libs/shared`**      | No single one                                                                                                                                         | `libs/aje/rpc/src/sleep.ts`                                                                                                            |
| Circuit breaker         | 16 classes (14 outside shared, 2 inside)                    | Duplicated even in shared                                                                                                                             | `libs/lilith/service-lib/circuit-breaker.ts`, `libs/iris/failover/src/circuit-breaker.ts`, `libs/cybele/api/src/circuit-breaker.ts`, … |
| Logger                  | 8 factories + 22 raw-pino imports + 2 `class Logger`        | **Yes** — `@oshun/logging` (423 importers)                                                                                                            | `libs/yemaya/enterprise/src/utils/logger.ts`, `libs/iris/core/src/logging/logger.ts`                                                   |
| HTTP client wrapper     | 78 local wrappers                                           | **Yes** — `@oshun/http-client` (timeout+retry+CB+SSRF-guard; only 48 importers)                                                                       | `libs/bellona/client/src/api/client.ts`, `libs/veritas/b2b-sdk/src/client.ts`                                                          |
| `Result<T,E>` type      | 8 domain redefinitions                                      | **Yes** — `@oshun/types`                                                                                                                              | `libs/oya/common/src/result.ts`, `libs/seshat/common/src/types.ts`                                                                     |
| Env/config parsing      | 31 local loaders; **596 files read `process.env` directly** | **Yes** — `@oshun/config` (40 importers)                                                                                                              | `libs/galatea/core/src/config/runtime-config.ts`; even `libs/shared/storage/src/s3-client.ts` reads env ad hoc                         |
| Postgres pool factories | ~12 outside shared                                          | **Yes** — `@oshun/database` (145 importers)                                                                                                           | `libs/cybele/db/src/connection.ts`, `libs/lakshmi/db/src/connection.ts`                                                                |
| Redis factories         | 32 raw-client files                                         | **Yes** — `@oshun/cache` (56 importers); shared itself bypasses it in 6 libs                                                                          | `libs/asase/infrastructure/src/cache.ts`                                                                                               |
| deepClone/deepMerge     | 6 defs + scattered shared copies                            | Partial                                                                                                                                               | `libs/hathor/domain-models/src/common/utils.ts`                                                                                        |
| chunk/batch             | ~17 defs                                                    | No                                                                                                                                                    | `libs/aje/core/src/blocks/utils.ts`                                                                                                    |

Config duplication mirrors code duplication: the top 8 vitest-config hashes
cover ~700 identical files; 561 distinct `tsconfig.json` variants exist across
libs where ~5 presets would do.

### F. Conventions

**F-1. Test conventions split four ways.** 9,834 colocated `*.spec.ts` vs 5,286
colocated `*.test.ts` vs 1,178 files under `__tests__/` vs 364 under per-lib
`tests/`. eslint carves separate override blocks for each. Pick one (colocated
`.spec.ts` is the plurality) and codemod.

**F-2. Commit-scope vocabulary covers ~40% of reality.** `commitlint.config.js`
scope-enum lists 22 domains + generic scopes, is **warning-only**, and is
missing 30+ active domains (neith, nous, gaia, phoebe, euterpe, galatea, themis,
uzume, oya, metis, mnemosyne, seshat, shakti, calliope, kuanyin, annapurna,
athena, lakshmi, aglaea, airmid, v3–v9…). Memories show scope guessing (`core`
vs `nous` vs `neith`) is a recurring commit-time stumble.

**F-3. Per-library READMEs effectively don't exist** (3 of 400 sampled lib
dirs). The information lives far away in `systems/lib-*.md` and `DOMAINS/`,
which no editor/IDE surfaces next to the code.

**F-4. Package-scope naming is split.** Platform libs use `@oshun/*` while
domains use per-domain scopes (`@neith/*` 539, `@iris/*` 258, `@aphrodite/*`
191…). Workable, but combined with 57 mythology names there is no way to tell a
domain's purpose from its name — and no registry mapping name → purpose → owner
exists in-repo (`DOMAINS.md` is closest but 3 weeks stale and unordered).

**F-5. `eslint.config.js` is a 1,638-line monolith** mixing global policy with
dozens of app-specific carve-outs (per-service override blocks for 8 lilith
services, per-app storybook paths, a 15-entry `allowDefaultProject` list).
Project-level `eslint.config.js` files inheriting a root preset would localize
churn; today every exception edits the root file (60 KB re-parsed by every lint
of 1,646 lint targets).

**F-6. God files.**
`libs/kalika/crystallography/src/diffraction/anomalous-data.ts` (54,156 lines —
embedded dataset as source), `libs/maya/vr-studio/src/index.ts` (28,261),
`libs/maya/standards/src/index.ts` (25,021), `libs/maya/renderer/src/index.ts`
(22,753),
`libs/nisaba/languages/src/classical-chinese/constants/character-database.ts`
(25,508), `libs/yemaya/agents/src/pipelines/game-pipeline.ts` (14,927). Whole
libraries live in a single `index.ts`; datasets are inlined as source code
instead of data files loaded at build time.

**F-7. TODO debt is measurable but bounded:** 1,432 non-test source files carry
TODO/FIXME/HACK markers — notable given the zero-tolerance stub policy; most are
in vendored/dataset-like code, but no burn-down list exists.

### G. CI/CD & tooling

**G-1. 148 workflows / 27.7k YAML LOC, dominated by clones.** 56 `v4-*`
workflows share one 53-line skeleton (checkout → composite setup →
`pnpm -F @v4/scripts test` → `pnpm -F @v4/scripts <slug>-check`) differing only
in path filters and slug (verified by normalized diff of `v4-hall-of-fame.yml`
vs `v4-map-lore.yml`). One matrix- or generator-driven reusable workflow
replaces all 56. Only **1** workflow uses `workflow_call`; 112 do use the shared
`./.github/actions/setup` composite (good foundation to build on).

**G-2. Trigger drift, not broken paths, is the CI dead-weight.** A glob-aware
test of all 382 distinct path-filter entries found only **one** stale reference
(`v3-workspace.yml` → `apps/oshun/web/src/middleware.ts`, which no longer
exists) — path hygiene is good. But: 93 of 148 workflows serve the UE `V1–V9`
product lines vs 47 for the Nx apps (~63% of CI surface for the game lines); 16
workflows are `workflow_dispatch`-only, and **only 8 have a `schedule:`
trigger** — including none for `a11y-pa11y-nightly.yml` and
`v4-nightly-feel-tests.yml`, which are "nightly" in name only and never run
automatically.

**G-2b. Node version drift in CI.** `.nvmrc`, `engines`, and the composite setup
action all agree on Node 22 / pnpm 10.25.0 — but 21 workflow jobs pin
`node-version: 24` inline (vs 10 pinning 22), and 10 workflows bypass
`./.github/actions/setup` entirely with hand-rolled `actions/setup-node`
(`runpod-endpoint-*`, `stub-indicator-scan`, `tara-web-deploy`,
`external-api-guard`, `api-inventory`, `adversarial-grep-trend`,
`test-coherence-check`). CI can pass on a Node major the repo doesn't declare.

**G-3. The pre-commit hook does seven jobs** (lint-staged, V2 asset-lock python,
stub-scan, V5 docs validation, scoped typecheck, docs-center HTML regen +
re-stage, LFS locking) — it is the de-facto CI and the reason commits are slow
and sometimes surprising (HTML re-staging). Hooks should gate, not build; the
HTML regen belongs exclusively to CI (its own comment admits CI is the
backstop).

**G-4. Main `ci.yml` (1,031 lines) is properly nx-affected-based** for lint/
typecheck/build/test — this part is healthy — but also inlines product- specific
gates (four Isis schema/taxonomy/benchmark validators) that belong in those
projects' own targets so `nx affected` scopes them naturally.

**G-5. `scripts/` is 78% one domain's codegen output.** Breakdown of the 2,909
tracked files: `scripts/isis` **2,256** (2,209 `.mjs`; 1,092 `generate-*`, of
which 1,088 are `generate-v2-*` — one generated generator per ComfyUI/asset
artifact), `scripts/v3` 274, `scripts/lilith` 140, `scripts/v6` 129,
`scripts/audit` 23 (the healthy end: schema-backed, self-tested
capability-truth/verification tooling), 43 loose root files. The 26
`verify-phase-*-completion.mjs` checkers cover non-contiguous phases (8–14,
20–26, 32–33, 39, 49, 63, 65, 82, 97, 98, 143–145, 180) — pure process residue.

**G-6. Two parallel doc/codegen toolchains.** Docs rendering exists twice:
`tools/render-docs-center.py` + `tools/docs_center/` (Python, canonical,
hook/CI-invoked) _and_ `scripts/docs/generate-domain-docs.mjs` +
`generate-oshun-domain-reference.mjs` (Node). Code generation likewise splits
across `tools/codegen` +
`tools/generators/{cybele-library,iris-library,python-service}` vs the
`scripts/isis/generate-*` fleet. No single home for either concern.

### H. Architecture

**H-1. Domain isolation mostly holds.** Cross-scope import sampling of 10
domains shows dominant self+shared imports (e.g. bellona: 133 self, 0 foreign;
veritas: 112 self, 0 foreign). Real leaks are few and localized: yemaya → {oya
10, aphrodite 10, uzume 8, maya 8, isis 8}, isis/3d-generation → @yemaya/_ (14)
while yemaya/remote-film-capture → @isis/_ — a bidirectional domain couple that
the declared constraint set (yemaya may depend on isis, not vice versa) appears
not to permit; either the isis-side imports predate the rule or escape via
untagged/allow-listed packages. Worth a targeted `nx lint` sweep of
`libs/isis/3d-generation`.

**H-2. Boundary governance erodes via exceptions**: the eslint `allow` list
accretes phase-commented package exemptions; `apps/oshun/web` is fully exempt;
451 projects are untagged (C-4). The mechanism is right; the enforcement
perimeter needs closing.

**H-3. Four BFFs share a name and nothing else.**

| BFF               | src `.ts` files | Internal structure                                                             | Middleware                                                        |
| ----------------- | --------------- | ------------------------------------------------------------------------------ | ----------------------------------------------------------------- |
| `apps/oshun/bff`  | 1,987           | `routes/` + ~70 feature dirs                                                   | rich (authz, entitlements, idempotency, abuse-protection + tests) |
| `apps/lilith/bff` | 385             | `api/` **and** `endpoints/` **and** `routes/` **and** `middleware/` — all four | 2 files                                                           |
| `apps/kalika/bff` | 9               | flat files                                                                     | none                                                              |
| `apps/urania/bff` | **0**           | only a stray `node_modules/`                                                   | —                                                                 |

There is no shared HTTP substrate: zero imports of any server/app factory lib
from any BFF; CORS/auth/error handling are re-implemented (or absent) per app.
Worse, **`@oshun/gateway` is not an HTTP gateway at all — it is a Traefik
infra-config CLI**, so the obvious name for the missing shared layer is already
taken by an unrelated tool.

**H-6. Dead and hollow apps.** `apps/urania` was fully dead: 0 source files, 0
`project.json`, 0 references repo-wide — and, on closer inspection during
remediation, never even git-tracked (untracked empty scaffold dirs from 2026-05;
removed from the working tree 2026-07-16 per R-4b). Hollow scaffolds: `apps/v7`
(10 source files), `apps/infra` (13), `apps/cybele` (16), `apps/v8` (16),
`apps/v6` (19 — despite many sub-service dirs like `egbe-clio-service`),
`apps/neith-vault` (20), `apps/asase` (32). And **Nx coverage gaps**:
`apps/psyche` has 94 source files but a single `project.json`
(`apps/psyche/admin` only), `apps/euterpe-studio-web` 423 source files / 1
project — code invisible to `nx affected`.

**H-7. Backend layout vocabulary is unstandardized.** The same concept is
spelled `routes/` (yemaya/api, oshun/bff), `api/` (isis/web, lilith/bff),
`endpoints/` (lilith/bff), or ~130 feature dirs directly at `src/` root
(`apps/lilith/svc-ai`); deployable naming varies across `bff`, `api`, `svc-*`,
`api-gateway`, `worker`.

**H-4. Single-file libraries** (F-6) defeat Nx's incremental-build value: a
one-line change to a 28k-line `index.ts` invalidates the whole lib and every
dependent, and tree-shaking can't help consumers.

**H-5. Nine (now ten) products, three placement conventions** (B-3) is the
biggest architectural-navigation cost: "where does V<N> code live" has three
answers depending on N — and the newborn V10 (see §0 addendum) will make it four
unless R-8 lands first.

---

## 4. Recommendations (prioritized)

> **P0 execution log (2026-07-16):**
>
> - **R-5 done** — dead `@oshun/logger` aliases removed; phantom
>   `poetry.lock`/root-`pyproject.toml`/`ruff.toml` refs dropped from `nx.json`;
>   yemaya studio-web storybook targets moved off the never-installed
>   `@storybook/angular` executors; `nx release` scope verified and documented
>   in C-8 (decision needed, not auto-fixed).
> - **R-3 done** — eight dead root scripts deleted; `typedoc.kalika.json` →
>   `scripts/kalika/`, `lighthouse.config.js` → `.github/` with all references
>   updated. 54 root reports (including this one) moved to `docs/audits/` after
>   verifying zero inbound links and only intra-set outbound links; docs-center
>   render + `--verify` green with the reports adopted as discipline docs. Kept
>   at root: tooling-parsed reports (see meta-note) and active planning docs.
>   `TODOS.md` retirement deferred — it is parsed by phase checkers and named in
>   CLAUDE.md; needs its own repointing pass.
> - **R-4 done (phase family)** — 25 `verify:phase-N` npm scripts replaced by
>   `scripts/verify-phase.mjs` dispatcher (`pnpm verify:phase <n>`); CI, the
>   bellona composite gate, five self-wiring checkers, and doc call sites
>   updated. The 403 `verify:v3/v6/v7/v8` entries are live product gates wired
>   into five workflows and 646 doc lines — deliberately deferred to the R-14
>   target-standardization work. Found in passing: phase 13/24/33/65 checkers
>   fail on pre-existing repo drift (jest-junit pin, missing
>   `apps/oshun/web/src/middleware.ts`, `@nisaba` mappings) — phase 65 runs in
>   `nisaba-ci.yml`, so that gate was already red.
> - **R-4b done (urania)** — `apps/urania` was untracked empty scaffold; removed
>   from the working tree. Hollow-app decisions and psyche/euterpe Nx coverage
>   remain open.
> - **R-1 done** — 6,147 artifact files untracked (~720 MB of pack weight): both
>   SwiftPM `.build/` trees, `backups/` bundles, and Hardhat `build-info/`;
>   gitignore rules added and a regex-based `scripts/check-forbidden-paths.sh`
>   gate wired into the ci.yml quality job (verified against pre-purge HEAD).
>   Contract ABIs stay tracked — they are runtime inputs (corrected A-4).
>   History rewrite deferred: needs coordination across active worktrees.
> - **R-2 done** — 3,086 generated HTML files untracked (docs-center, md-twins
>   across V1–V10/WALKTHROUGH×5/DOMAINS/docs/systems/platform, vdocs index +
>   search index); verified renderer-owned via delete-and-rerender (100%
>   regenerated by `tools/render-docs-center.py`). Pre-commit regen/re-stage
>   block removed; `vdocs-html-fresh.yml` reworked from freshness-check to
>   build + `--verify` + artifact upload; `vdocs-reader-ui.yml` now renders
>   before testing; generated paths gitignored (with carve-outs for V2/web
>   hand-written `index.html` pages and TypeDoc trees under `docs/`). Follow-up:
>   the 540 TypeDoc API-reference pages under `docs/domains/*/extras/generated/`
>   are a separate generator and remain committed for now.

### P0 — Repo health (mechanical, high payoff, do first)

- **R-1. Purge committed artifacts.** Remove from the index and ignore:
  `**/.build/` (Swift), `backups/*.bundle` (relocate to S3/MinIO),
  `apps/lilith/contracts/artifacts/`, `V6/ue/Plugins/VRM4U` stray status noise
  (submodule bump hygiene). Add CI guard (a `forbidden-paths` check) so they
  can't return. Then schedule a history rewrite (git-filter-repo) or fresh
  clone-point to reclaim the ~850 MB pack — coordinate with all worktrees before
  rewriting.
- **R-2. Stop committing generated HTML.** Render docs-center/vdocs/walkthrough
  HTML in CI (job exists: `vdocs-html-fresh`) and publish to Pages/artifact
  storage; delete the 3,815 tracked HTML files and the pre-commit regen step.
  This also fixes the recurring "post-commit regenerates 96 HTML files" and
  parallel-session merge-clobber traps.
- **R-3. Root cleanup.** Move the 71 root reports into `docs/audits/` (naming:
  `YYYY-MM-DD-<slug>.md` — the convention `docs/audits` already uses); delete
  the eight dead root scripts; move `typedoc.kalika.json`,
  `lighthouse.config.js` etc. next to their owners; retire `TODOS.md` (8 MB) in
  favor of the already-split `TODOS/` dir.
- **R-4. Collapse `verify:phase-*`**: one `scripts/verify-phase.mjs <n>`
  runner + delete 441 npm scripts and 25 of the 26 clones.
- **R-4b. Delete `apps/urania`** (0 sources, 0 references) and decide each
  hollow scaffold app's fate (implement or remove; H-6). Bring `apps/psyche/*`
  and `apps/euterpe-studio-web` fully under Nx projects so `affected` sees them.
- **R-5. Fix config drift now:** remove the 2 dead `@oshun/logger` aliases; fix
  or delete the phantom `ruff.toml`/`pyproject.toml`/`poetry.lock` refs in
  `nx.json`; verify/repair `nx release.projects`; remove the 2
  `@storybook/angular` executors.

> **P1 execution log (2026-07-16):**
>
> - **R-10 done (foundation + pilot)** — `@oshun/math`, `@oshun/ids`,
>   `@oshun/collections`, `@oshun/resilience` created (73 tests, all green; ULID
>   spec-vector verified; injectable clocks/randomness). Pilot codemod
>   (`tools/codemods/adopt-shared-math.mjs`) migrated 47 kuanyin files to
>   `@oshun/math` with 1 conservative skip; all 13,438 kuanyin tests green. The
>   fail-loud clamp immediately caught a real latent NaN in
>   ncii-deepfake-protection (fixed at source). Remaining rollout:
>   domain-by-domain via the codemod. Rewiring http-client/gpu-dispatcher
>   internals onto `@oshun/resilience` is a follow-up (their retry APIs are
>   HTTP-typed public surface).
>   - _Wave 2 (nous, 2026-07-16):_ 446 files migrated; codemod jsdoc-prefix
>     regex bug found and fixed (lazy `[^]*?` docblock match swallowed unrelated
>     functions — 3 collateral deletions restored, net-deletion audit now a
>     standard gate); 11 conservative skips left for manual review.
>   - _Wave 3 (aphrodite, 2026-07-16):_ 497 files across 88 packages; zero
>     collateral deletions; all 88 suites at/above HEAD baselines. Fail-loud
>     clamp exposed 6 more latent NaN/∞ bugs (zero-duration transitions, Pearson
>     0/0, gravitational redshift 0×∞) — fixed at source. Side-payload: 73
>     dead-store lint errors fixed, one parameter-ignoring dead helper removed,
>     the crowd-control queue's skipped effect-conflict check implemented with a
>     symmetric-conflict test, 35 vestigial `rootDir` tsconfig entries removed
>     (TS6059). 20 codemod skips left for manual review.
>   - _Wave 4 (isis, 2026-07-16):_ 282 files across 32 packages; zero collateral
>     deletions; all 32 suites at/above HEAD baselines. Codemod import-anchor
>     bug found and fixed (whole-file `^import [^;]+;` regex crossed newlines
>     and matched `import` lines inside embedded template-literal scripts,
>     dropping one insert mid-class — all four waves audited, one occurrence).
>     Repairs riding along: an invalid `readonly` indexed-access type that kept
>     a quality-gates test file from ever collecting, a conflict-resolver test
>     fixture with an invented connector shape, the benchmark embedding
>     provider's fabricated `clip-vit-base-patch32` modelId (now
>     `deterministic-feature-hash-v1`), and 9 dead-store lint errors. 20 more
>     skips for manual review.
>   - _Wave 5 (hathor, 2026-07-16):_ 248 hathor files + 9 straggler files from
>     earlier waves; zero collateral deletions. New codemod shape for the
>     default-range `clamp(value, min = 0, max = 100)` idiom — short call sites
>     padded via balanced-delimiter scan, exported definitions never adopted.
>     All 9 touched package suites at/above HEAD baselines; two pre-existing
>     reds proven byte-identical at HEAD. gemini-physics-consequence-analyzer
>     stays in the backlog (needs an isis seam, not a math migration).
>   - _Wave 6 (calliope, 2026-07-16):_ 69 calliope files + 6 isis stragglers;
>     zero collateral. New const-arrow codemod shapes (plain 3-arg + a [0, 1]
>     default-range variant). Calliope's ~155 clamp+quantize hybrids
>     (`Number(...toFixed(n))`, `Math.round`, `schema.parse`) deliberately NOT
>     migrated — different semantics; a shared `clampQuantized` helper is a
>     follow-up design decision, not a mechanical dedup. The initial mass test
>     failures were a stale gitignored `@oshun/ai` dist missing the
>     `openai-compatible` subpath — rebuilt, all 16 packages green.
>   - _Wave 7 (yemaya, 2026-07-16):_ 171 yemaya files + 3 stragglers; zero
>     collateral. New shapes: default-range function clamps, statement-form
>     clamp01, and a clamp01-delegating shape gated on co-adoption. The 47
>     `Number.isFinite`-guarded fail-safe clamps stay local by design (shared
>     clamp fails loud on NaN — a different contract). **Critical codemod fix:**
>     padCallArgs applied edits in reverse match order, which breaks when a
>     short call nests inside another short call — the outer insert landed 16
>     chars early, corrupting an adjacent `Math.max` (typechecks fine because
>     Math.max is variadic; caught only by tests). Fixed with descending
>     position sort + string/comment-aware scanning; a <3-arg-call corruption
>     detector is now a standing wave gate, and the committed hathor/calliope
>     waves audited clean against it.
>   - _Wave 8 (family helpers, 2026-07-16):_ the two dominant backlog families
>     became first-class @oshun/math helpers with exact-semantics tests —
>     `clampRound(value, min, max, decimals)` (Number(toFixed) rounding, fails
>     loud) and `clampFinite(value, min, max)` (returns min on non-finite, the
>     fail-safe contract). Codemod gained a generalized call transform (pad with
>     the deleted definition's own defaults + append its decimals + rename), so
>     call sites carry semantics explicitly. 184 files across
>     calliope/yemaya/isis; all 20 touched package suites fully green.
>   - _Wave 9 (residue + seam, 2026-07-16, commit 32cd1ef5c2):_ 8 more shapes
>     (statement clamps, fail-safe operand variants, required-args quantizers,
>     lerp-with-clamped-t → shared `lerpClamped`); 68 files, 71 defs, zero
>     collateral, 28 suites green. The 65 remaining skips are documented
>     deliberate refusals (byte/int clamps, schema-parse, isFinite+round
>     hybrids, exported transformed-call defs) — the DRY math rollout (R-10) is
>     **complete**. gemini-physics-consequence-analyzer seamed off isis: it now
>     declares the structural multimodal provider subset it uses
>     (`PhysicsVisionProvider`) with required constructor injection; isis's
>     GoogleProvider satisfies it structurally at composition roots. The last
>     flagged cross-domain relative import is gone.
>   - _Ids wave (finding E, 2026-07-16):_ the id story is deliberately NOT a
>     blind codemod — a fresh survey found 536 definitions across 219 distinct
>     shapes, and unlike clamp they carry observable FORMATS (111 files parse
>     ids with `split('_')`, deterministic content-hash makeIds, persisted
>     entity ids). Executed: the format-identical `crypto.randomUUID()` wrapper
>     family migrated to `@oshun/ids` `uuid()` (arete/balance, 7 files, 240
>     tests green), and a new `oshun-stub/no-handrolled-ids` WARN rule (with
>     RuleTester coverage) points every new hand-rolled generator at @oshun/ids
>     while grandfathering existing formats — those consolidate per-format-owner
>     decision, not by lint pressure. Ride-along: the plugin's RuleTester
>     harness had been silently broken since the eslint 10 upgrade (8.x
>     `parserOptions` form) — fixed to flat-config `languageOptions`, all plugin
>     rule tests actually run again.
>   - _Per-app env split (2026-07-16):_ `tools/env/split-env-examples.mjs`
>     derives one `.env.example` per `apps/<name>` from the variables the app's
>     own source directly references, grouped by the canonical file's owner
>     sections (13 apps emitted, 21 with no canonical vars skipped). Root
>     `.env.example` stays canonical; generated files carry a
>     referenced-but-uncanonical section so drift surfaces instead of hiding.
>     `--check` wired into the ci.yml quality job next to env-ownership.
>   - _Domain doc-set reconciliation (2026-07-16):_ the "editorial merge" of the
>     25 parallel domain doc sets is resolved by the docs-center's own shipped
>     design, not by destructive merging — deep-dive/ is canonical (rendered,
>     with a supporting-docs callout linking the operational tree); the missing
>     piece was the reverse subordination. The 50 same-named
>     `architecture.md`/`features.md` operational twins now carry a canonical
>     -pointer header naming their deep-dive counterpart and their operational
>     role, so neither reads as a second source of truth. Docs-center `--verify`
>     integrity (3,432 entities) and generator pytest (27) green.
>   - _Root tara/ retired (2026-07-17):_ zero external consumers (only its own
>     @module comments matched); the tree is the phase-22.1 declarative
>     foundation (2,062 lines of app/content/feature/environment config plus
>     placeholder content/assets), richer than — not superseded by — the
>     consumed `libs/tara/config`. Moved intact to `apps/tara/foundation/`,
>     README rewritten to explain the relationship, `^tara/` added to the
>     retired-roots guard. Historical TODOS phase-22 path references left as
>     record. tara suites green; per-app env example regenerated (the moved
>     tree's env refs now surface in apps/tara/.env.example, as the sync gate
>     requires).
>   - _services/ → apps/ re-gated (2026-07-17):_ scoping found services/
>     {metis,psyche,concordia} wired into deploy-ecs.yml, deploy-hetzner.yml,
>     and infrastructure/terraform/variables.tf — container build contexts and
>     deploy paths. Moving them without a deploy-verified window risks
>     production deploys; the item moves to the owner-gated bucket alongside
>     Terraform root unification.
>   - _Neith cargo umbrella (R-18/A-7, 2026-07-17, commit 767d22e879):_ the 462
>     pure workspace roots + 1 self-rooting package under libs/neith (92% of the
>     repo's 505) consolidated into one umbrella: 599 member crates, one
>     300-entry merged catalog, one committed 816-package Cargo.lock. Merging is
>     semantics-preserving — path entries normalized (most "conflicts" were
>     vantage-point artifacts), caret-equivalent reqs unified, feature unions
>     for equal reqs, genuine conflicts (thiserror 1/2, quick-xml 0.36–0.39)
>     inlined into the 58 minority crates, the ten AGPL licenses inlined rather
>     than homogenized, six zero-dependent package-name collisions
>     parent-namespaced with lib target names kept. Cargo.lock global ignore
>     removed (A-7); CI premerge planner roots → libs/neith (plan verified
>     locally), 446 project.json cargo targets repointed, sccache manifest +
>     four neith contract checkers pass. Verified: full-graph cargo metadata,
>     sampled cargo check/test --locked across every override class.
>   - _Non-neith umbrellas (2026-07-17):_ generalized `cargo-umbrella.py`
>     consolidated kalika (24 roots → 34 members), oya (3 → 23; Rust↔TS parity
>     harness green 120/120 at 3.7e-15), and euterpe (2 → 6; dsp-core 219
>     tests); vault-crypto/native-memory folded into the neith umbrella.
>     Deliberate refusals: the two yemaya-raster-gpu roots (documented
>     standalone-by-design) and maya's two roots (already proper multi-crate
>     workspaces; engine-core CI-coupled with known build fragility). Lib
>     workspace roots 40 → 10, each now a deliberate unit.
>   - _Python hygiene (R-18 tail, 2026-07-17, commit ff34b4fec3):_ root
>     `ruff.toml` from the measured consensus of the 48 existing configs (nearer
>     configs still win — no project's lint behavior changes); poetry.lock
>     un-gitignored; 57/59 PEP-621 projects locked with uv and 21/24 poetry
>     projects locked. Locking surfaced real manifest debt fixed at source:
>     jupyter-kernel's undeclared workspace-local kalika-sdk source, phase-89's
>     unsatisfiable <3.14 claim and its seven pairwise- incompatible backend
>     extras (full conflict matrix declared), voice-engine's httpx pin
>     conflicting with the psyche platform. Documented refusals (5): nemo-rl and
>     pytorch3d have no PyPI releases, zoomus ^0.1.15 never existed, psyche root
>     inherits avatar-engine — those manifests never resolved from a clean
>     environment; the locks make that visible. **R-18 is complete.**
>   - _BFF substrate, increment 1 (R-13c, 2026-07-17, commit a50331fefa):_
>     `@oshun/bff-kit` created from apps/oshun/bff's mature middleware —
>     tracing, tenant context, authz, server-side idempotency + Redis store,
>     abuse protection + Redis store, device integrity, residency guard (nine
>     modules, shared-lib coupling only). The BFF's 1,081 middleware importers
>     are untouched via exact named re-export shims. Behavior neutrality proven
>     like-for-like: the 11 pre-existing failing test files fail identically
>     (17/86) with originals restored and with shims; full suite 6,100 green.
>     App-coupled middleware (entitlements→customer-auth-store,
>     residency-routing→consent state) stays in-app with seams named for
>     increment 2, as does adoption by lilith/kalika BFFs. `@oshun/gateway`
>     renamed to `@oshun/traefik-config` (no code consumers; 15 tests green;
>     docs re-rendered + verified) — the natural substrate name is free. Note:
>     apps/oshun/bff tsconfig has `noCheck: true`, so its tsc is vacuous — the
>     kit now real-typechecks the extracted modules.
>   - _Increment-1 corruption + increment 2 (2026-07-17):_ commit a50331fefa
>     landed CORRUPTED — a failed lint-staged run left the kit sources replaced
>     by self-referential shims, and re-running the shim generator against those
>     produced comment-only shim files; the real middleware existed nowhere in
>     the tree. Two sessions independently shipped restorations (a432f8f891 and
>     this branch's fix, merged); the generator now asserts kit files are real
>     and export lists non-empty. Increment 2 rode the fix: entitlements and
>     residency-routing joined the kit behind fail-closed injected seams
>     (`BffSessionTierResolver`, `crossRegionConsentResolver`); the oshun BFF
>     wires its stores through its shims, preserving exact behavior. Middleware
>     gates 29/29, kit suite green. Trap for the record: stale
>     `node_modules/.vite` serves pre-corruption module content — clear it when
>     middleware resolution misbehaves. Post-merge full BFF suite at the
>     pre-existing 28-failure baseline. lilith and kalika BFFs adopted the
>     substrate's request tracing (one validated x-correlation-id per request +
>     structured completion logs — additive beside kalika's x-request-id and
>     lilith's per-route correlation reads); both suites byte-identical to
>     baseline (kalika 5/5; lilith 1,402 passing with its pre-existing 34
>     collection-error files unchanged). Deeper adoption (idempotency, abuse
>     protection, authz) is per-app feature work needing each owner's
>     stores/policies — the substrate is now available to all three BFFs.
>   - _Maya monoliths split (F-6, 2026-07-17, commit d824049021):_ the six maya
>     `index.ts` god files (126,667 lines) split into 46 dependency-sound
>     modules + barrels by `tools/codemods/split-index-monolith.mjs` — TS-API
>     declaration graph, Tarjan SCC condensation (mutually-recursive decls share
>     a module), topological packing with backward-only imports, and an
>     asserted-identical public export surface. All six suites at exact
>     baselines (804 tests); over-imports pruned via tsc's own TS6133 output.
>     The F-6 remainder followed on 2026-07-17: the splitter grew a `--file`
>     mode (header imports distributed per-module with relative paths rebased;
>     modules dir named `<stem>-modules` to dodge the extensionless-resolution
>     trap), and yemaya's 14,927-line `game-pipeline.ts` became 7
>     dependency-sound modules + an 11-line barrel — 232 public exports
>     preserved, the `export * as gamePipeline` consumer untouched,
>     yemaya/agents at its exact 15,258/15,258 baseline and tsc error-count
>     identical to HEAD. Every named F-6 god file is now split or extracted.
>   - _Vitest-config dedup (R-14 slice, 2026-07-17, commit c29f1b4ab5):_ the
>     top-4 hashes among the 2,657 per-project vitest configs were one semantic
>     configuration in four spellings; two presets
>     (`configs/vitest/node-lib{,-coverage}.ts`) now carry each class exactly
>     and the 457 member files are one-line depth-correct re-exports — cwd
>     discovery, Nx targets, and --config invocations untouched. Eight sampled
>     suites green across every path depth + a --coverage smoke. Hashes 5–8
>     (~200 files) follow the same recipe when touched.
>   - _LFS correction + F-7 inventory (2026-07-17, commit bc1e1323ca):_ of 93
>     declared LFS patterns exactly one matching file was raw —
>     `V5/.../BootMap.umap`, the perpetual-modified trap — converted via filter
>     re-add (git lfs migrate refuses beside the untracked VRM4U dir), pointer
>     pushed, status finally clean. The audit's 67MB .mdb blobs were already
>     purged; the remaining large plain blobs (animation_catalog 12MB,
>     seed-registry 11.5MB) match no pattern — LFS-tracking them is a policy
>     decision coupled to CI `lfs: true` checkout settings, deferred explicitly.
>     F-7: `tools/audit/todo-burndown.mjs` + `docs/audits/TODO_BURNDOWN.md` —
>     516 files / 1,272 markers (513 actionable; apps/aphrodite alone: 669 in 51
>     files), classified per owner surface, regenerable.
>   - _Burn-down slice 1 (2026-07-17):_ viewer `shows.ts` (30 markers, the top
>     offender file) implemented for real against the prisma show domain through
>     a ShowsStore seam — explicit escrow/refund charging model with atomic
>     balance-guarded charges, lifecycle guards, and 501 `model_gap` for the
>     schema-unmodeled features (advance tickets, reminders, per-viewer goal
>     contributions). The integration spec's stub-coherent Shows sections (they
>     asserted success for random ids) rewritten to seeded-store semantics;
>     shows tests fully green, remaining 30 integration failures are the
>     pre-existing Notifications/Settings scaffolds — the next slices. Markers
>     1,254 → 1,228.
>   - _Burn-down slice 2 (2026-07-17, commit 9db22cae2c):_ viewer settings +
>     notifications implemented for real. New Notification/PushSubscription
>     prisma models (migration 00002), ViewerSettingsStore + NotificationsStore
>     (SQL + memory doubles), settings routes over the schema's real surface
>     (profile, sensual-tier opt-in, preferred categories, notifications master
>     switch) with 501 fail-loud for unmodeled display/security/account groups,
>     notifications CRUD/bulk/push-registration with fail-loud test-send. Two
>     real app.ts bugs fixed along the way: the auth middleware minted
>     `viewer-user-id` from ANY bearer token (now HS256 JWT via
>     VIEWER_JWT_SECRET, 503 fail-closed when unconfigured, verifier test seam),
>     and the rate limiter keyed on a userId that is never set at its middleware
>     position, so all callers shared one anonymous 100-req/min bucket — that
>     exhaustion, not the scaffolds alone, produced the 30 "baseline"
>     integration failures. Suite 138/138 (was 108/138). Markers 1,228 → 1,181.
>   - _Burn-down slice 3 (2026-07-17, commit d574766481):_ payment
>     tips/payouts/subscriptions + broadcaster shows implemented for real.
>     Payment: SqlTipsStore (transactional balance-guarded tip send, 20% fee
>     split, goal progress, menus, leaderboards, bucketed stats),
>     SqlPayoutsStore (token-debiting requests at the fixed 5¢/token creator
>     rate, PENDING-only cancel+refund), SqlSubscriptionsStore (tier guards,
>     price snapshots, calendar billing periods, cancelled-pair reactivation
>     forced by the schema's viewer/broadcaster unique constraint, MRR/churn
>     stats); unmodeled surfaces (payout methods/schedules/tax docs, perks,
>     billing history) fail loud. Broadcaster: JWT auth middleware added (same
>     fail-closed contract as viewer), shows routes settle real escrow — decline
>     refunds, end bills minutes clamped to [minimum, escrowed] with 80% share,
>     group shows refund entry fees on cancel; the scaffold's /goals/history
>     route was shadowed by /goals/:goalId (registration-order bug) and its
>     onError flattened HTTPExceptions to 500 (the pre-existing invalid-JSON
>     failure) — both fixed. Suites: payment 109 passed (6 pre-existing
>     earnings/webhooks failures remain), broadcaster 53/53 (was 35/36). Markers
>     1,181 → 1,078.
>   - _Burn-down slice 4 (2026-07-17, commit 86692c03df):_ payment earnings +
>     webhooks implemented for real. EarningsStore derives every figure from the
>     money-carrying rows (tips, ended shows, subscription billing-period
>     starts, payouts) through shared pure compute functions so SQL and the
>     memory double agree exactly: summary, per-source breakdown, daily/hourly
>     series, derived ledger with payout debits, window-over-window analytics
>     (incl. conversion from view_sessions), tip leaderboard, token milestones;
>     freeform ledger credits + report files fail loud. The global /leaderboard
>     literal was registered after /:userId and unreachable — the 6th
>     pre-existing failure, same shadowing class as /goals/history.
>     WebhooksStore executes verified provider events (purchase
>     complete/fail/refund/reinstate keyed by provider payment reference,
>     idempotent on replay; subscription renew/past-due/cancel with calendar
>     period advancement; payout complete/fail with token refunds); internal
>     worker callbacks now require an HMAC over the raw body
>     (INTERNAL_WEBHOOK_SECRET, fail-closed) instead of accepting unsigned
>     financial mutations, and purchase callbacks report the recorded state
>     instead of assuming success. Spec sections rewritten with real Stripe/HMAC
>     signatures, replay and clawback assertions. Payment suite fully green
>     120/120 (was 109/6). Markers 1,078 → 1,050.
>   - _Burn-down slice 5a — chat (2026-07-17, commit 27778d4c6b):_ chat
>     service + viewer chat implemented for real, with NEW
>     DirectMessage/UserBlock models (migration 00003) since DMs and user-level
>     blocks had no tables. A chat room IS a stream (views derive from streams +
>     live view-sessions + message counts); messages get real cursored
>     history/search/soft-delete/stats — /search was shadowed by /:messageId
>     (the 3 baseline failures, 4th shadowing instance); moderation bans are
>     viewer_blocks rows with the log derived from blocks
>     - deletions; DMs are pair-key conversations with bidirectional block
>       enforcement, read receipts, and synchronous mass-DM fan-out; health
>       probes run a real DB check; socket messages persist with authorship
>       checks; viewer chat gets ban-gated sends, block-filtered history,
>       EMOTE-persisted reactions, and whispers over direct_messages. Chat suite
>       50/50 (was 84/87); viewer 149/149. Markers 1,050 → 962.
>   - _Burn-down slice 5b — devices (2026-07-17, commit 3c951fe296):_ device
>     routes implemented over the schema's real model — broadcaster-owned
>     devices with a viewer-control policy. Broadcaster: registry CRUD,
>     client-reported connection state, status summaries, FK-protected deletes;
>     hardware commands/vendor pairing fail loud (device_bridge_not_configured).
>     Viewer: commands record MANUAL device_controls rows clamped to the device
>     policy with pattern validation; stop-all emits STOP controls for in-flight
>     devices; viewer-owned hardware has no table and fails loud. Devices app's
>     three dishonest comments replaced with the client-side-discovery truths.
>     Viewer 158/158, broadcaster 60/60, devices 59/59. Markers 962 → 917.
>   - _Burn-down slice 6 (2026-07-17, commit e3999be8d4):_ payment tokens +
>     transactions implemented for real. Tokens: the package catalog and
>     10-tokens/USD rate are load-bearing pricing constants — initiate records a
>     PENDING token_purchases row priced from them and the session endpoint
>     reports its true state; the old confirm endpoint minted tokens on client
>     say-so and now fails loud pointing at the signed provider webhooks;
>     viewer-to-viewer transfers are refused outright (no audit table — silent
>     money movement), holds and platform-side token refunds fail loud with
>     pointers to show escrow and the charge.refunded webhook. Transactions: the
>     viewer's unified history derives from
>     purchases/tips/show-participations/subscription periods (no transactions
>     table) through shared compute functions — filtered listings, cross-table
>     detail lookup, between/stream views, settled- only summaries and daily
>     buckets, and a ledger of signed deltas against the live balance; /flagged
>     was shadowed by /:userId (5th instance). Payment suite fully green
>     109/109. Markers 917 → 887.
>   - _Burn-down slice 7 (2026-07-17, commit c7e8fe34d7):_ streams (three
>     services) + viewer history implemented for real. Streaming (media plane):
>     the state machine validates against the ROW's stored status; ingest auth
>     matches the presented stream key against the stored one — the scaffold
>     accepted ANY non-empty key (same auth-fabrication class as the viewer JWT
>     bug); stats report recorded columns and the session-derived device split;
>     wire telemetry fails loud. Broadcaster: own-stream CRUD with status
>     filtering, key rotation and return-nothing revocation, lifecycle guards
>     with recorded stop stats, modeled device-integration settings, uploaded
>     thumbnail URLs; playback/ingest URLs are stored provisioning results,
>     never fabricated hosts. Viewer: browse/search/details/join enforce the
>     sensual-tier opt-in; trending = viewers-per-minute-live and recommended =
>     watched-category affinity (named heuristics); the category catalog derives
>     from live streams; join records a ViewSession and leave closes it,
>     crediting total_watch_time; VODs = public recordings, schedules real.
>     History: session-backed with real privacy deletion, watch-time
>     stats/favorites; watchlists point at follows, clips/screenshots fail loud.
>     Suites: viewer 160/160, broadcaster 43/43, streaming 17/17. Markers 887
>     → 812.
>   - _Burn-down slice 8 (2026-07-17, commit 07ff6a7d50):_ broadcaster
>     profile/settings/analytics implemented for real. Profile: the
>     broadcaster's own row with strict patch validation; verification read-only
>     (KYC intake fails loud); schedules are concrete stream_schedules entries,
>     not the scaffold's unpersisted weekly-slots grid; followers/subscribers
>     from the relations; the block list is viewer_blocks shared with chat
>     moderation. Settings: the modeled surface is the monetization trio
>     (tip_menu_enabled, token_per_minute, private_show_price);
>     notification/privacy/stream-default groups fail loud, payout surfaces
>     point at the payment service. Analytics:
>     overview/streams/audience/engagement/realtime/compare derived from
>     recorded rows via shared fact computes (new-vs-returning from first-seen
>     timestamps, tip conversion = tippers/viewers, compare = doubled-window
>     minus current); earnings point at the payment service, exports fail loud.
>     Broadcaster suite 62/62. Markers 812 → 776.
>   - _Auth/CDN verification (2026-07-17):_ the auth and cdn apps were already
>     fully implemented — not scaffolds. Auth has 0 markers and real
>     PBKDF2/timingSafeEqual crypto; cdn has real HMAC signing + S3 presigned
>     uploads behind an S3ClientLike seam. Both suites 26/26. No conversion
>     work; the one OAuth `Math.random()` nonce is a prior documented CSPRNG
>     carve-out, left in place.
>   - _Burn-down slice 9 — streaming sub-routes (2026-07-17, commit
>     34313560a3):_ the seven media-plane sub-routes rewritten so the
>     schema-backed surface is real and media-infra fails loud. Ingest RTMP auth
>     resolves the stream by stored key and gates on broadcaster status
>     (accepted ANY key before — 4th auth-fabrication instance);
>     on-publish/on-publish-done bridge to LIVE/ENDED. Discovery is a real
>     search/browse catalog over streams+broadcasters (named sorts, isMature
>     gating). Recording lists/gets/deletes completed VODs on the recordings
>     table + storage usage. Distribution/thumbnails serve stored asset URLs;
>     transcoding serves the fixed encoder ladder constant. WebRTC/CDN/DVR/
>     transcoding-jobs/QoE-telemetry fail loud (media_infrastructure_gap /
>     observability_gap). Two new stores (MediaControlStore,
>     StreamDiscoveryStore). Streaming suite 34/34. Markers 776 → 661.
>   - _Burn-down slice 10 — viewer following + tips (2026-07-17, commit
>     7674609758):_ following is real over the follows table (follow/unfollow
>     maintaining follower_count, status, the two modeled notification columns,
>     live subset); subscription READS real over
>     subscriptions/subscription_tiers (active subs + monthly spend, a
>     broadcaster's real tiers, detail); subscription WRITES → payment service.
>     Tips: the money path is real — atomic balance-guard + 20% fee split +
>     broadcaster credit + active-goal progress (same model the payment service
>     uses); balance/history/goals/leaderboards real; the token catalog +
>     purchase → payment service (the scaffold's prices CONTRADICTED the
>     canonical ones). Virtual gifts, tip animations/sounds, goal-earmarked
>     contributions fail loud. Two new stores (FollowingStore, ViewerTipsStore);
>     integration spec Tips+Following rewritten. Viewer suite 142/142. Markers
>     661 → 618.
>   - _Admin/analytics slice 11 (2026-07-17, commit bc33bc070b):_ the admin,
>     admin-bi-dashboard, and realtime-analytics apps were verified already-real
>     (0 markers each, real aggregation/query services — no conversion work,
>     reported like auth/cdn). The one genuine finding was the analytics
>     dashboard service: ~15 fields returned fabricated zeros/empties behind
>     `// Would need additional calculation` comments while the raw analytics
>     event stream (queryEvents) carried the data. Now computed for real via a
>     paged `fetchEvents` and seven exported, unit-tested aggregation helpers:
>     earnings top tippers (from tip.received by tipper); viewer avg/total watch
>     time + retention (viewers on ≥2 days) + returning (≥2 sessions) from
>     viewer.watched; stream engagementRate (messages/viewer); tip
>     median/amount-bucket distribution/hourly patterns/top triggers; follower
>     sources (by referrer) + the absolute current total from the LIFETIME
>     follower ledger (added − removed to window end) rather than a fabricated
>     0; peak hours (viewer/earnings/engagement) with scheduling
>     recommendations; geography (viewers/tips/watch-time by country/city/
>     region); dashboard summary engagementRate + best stream + top tipper. New
>     10-test spec (the app previously had none); each assertion would FAIL
>     against the old zeros. Analytics suite 10/10. This slice removes
>     stub-lexicon fabrications rather than plain `TODO` markers, so the
>     burn-down count is unchanged at 618.
>   - _Notifications delivery slice (2026-07-17, commit 908f7e64d9):_ the
>     notifications app's queue processor fabricated delivery —
>     `deliverViaChannel` returned `true` for every channel
>     (`// For now, simulate success`), so a notification was marked `sent` when
>     nothing was delivered, and the app-level email handler was a `console.log`
>     no-op (`// In production, would look up user email`) while push failures
>     were swallowed. Delivery is now real: `NotificationService` has a
>     per-channel deliverer registry (`registerDeliverer`/`hasDeliverer`);
>     `deliverViaChannel` awaits the registered transport and returns its actual
>     accept/reject result (thrown errors flow to the existing retry/mark-failed
>     path). `in_app` stays deliverable with no transport (already durably
>     persisted + best-effort WS push); push/email/sms with no transport raise
>     `ChannelNotConfiguredError` (a real failure) instead of fabricating
>     success. `app.ts` wires a real push transport and, behind a
>     `resolveRecipientEmail` seam, a real email transport (resolve address →
>     SendGrid); with no resolver the email channel is left unconfigured and
>     fails loud. Two new specs (the app had none for this): a service suite
>     proving `sent` is only recorded on real acceptance, that
>     rejects/unconfigured channels fail rather than fabricate, in_app via
>     persistence+WS, and mixed-channel partial delivery; an app suite proving
>     the email resolver seam + fail-loud default. Notifications suite 88/88.
>     Lexicon-fabrication cleanup, so the TODO burn-down count is unchanged (the
>     app had 0 TODO markers); the one remaining lexicon hit (email subject
>     template substitution) is a signed-off `stub:legitimate` carve-out.
>   - _Socket layers (2026-07-17):_ the correct adversarial lexicon scan (an
>     earlier per-dir scan used a PCRE lookahead that `grep -E` silently
>     rejects, so it falsely reported zero everywhere) plus a read pass found
>     real fabrications. Four slices landed:
>     - _Chat socket auth (759616831d):_ the server trusted the client-authored
>       handshake for identity AND roles (`handleConnection` read
>       `handshake.auth.userId`; `socket.data.roles = handshake.auth.roles`), so
>       any client could claim any identity and grant itself moderation via the
>       `isModerator`/`isRoomOwner` TODO stubs. New `socket/auth.ts` verifies an
>       HMAC-signed token (`signSocketToken`/`createHmacTokenVerifier`,
>       constant- time) in an `io.use` middleware; identity comes only from
>       signed claims; fails closed with no `CHAT_SOCKET_TOKEN_SECRET`. 13
>       tests.
>     - _Chat DM persistence (7e96cf1aff):_ `dm.ts` kept its own in-memory Maps,
>       so socket DMs were invisible to the HTTP `/conversations` view (the real
>       `dmStore`) and lost on restart, and the list handlers abused `dm_error`
>       code `SUCCESS` to return data. Rewired to the shared `dmStore` (pairKey
>       = conversationId); real block enforcement; two new typed events. 5
>       tests.
>     - _Chat clear-chat (dfc322fa62):_ `mod_clear_chat` announced
>       `chat_cleared` behind `// TODO: Clear messages from database` — a
>       fabricated clear. Added a real `ChatMessagesStore.clearRoom` bulk
>       soft-delete and wired it. The mute/slow-mode maps are honestly relabeled
>       `stub:legitimate` per-node ephemeral state (a horizontal-scaling concern
>       like the socket.io Redis adapter, not a fabrication). 3 tests.
>     - _Device gateway auth (4616492759):_ `extractUserId` returned
>       `handshake.query.userId ?? handshake.auth.token` unverified, so any
>       client could drive any user's intimate hardware. New `websocket/auth.ts`
>       verifies a signed token (envelope matches chat's, so one gateway secret
>       serves both); `DeviceSessionManager` fails closed without
>       `DEVICE_SOCKET_TOKEN_SECRET`. 7 tests.
>     - _VR socket auth + verifier consolidation (60f5127db1):_ the vr playback
>       ws trusted `data.userId` from the `session:start` payload, so a client
>       could start a session as anyone. Rather than add a third verifier copy,
>       the signed-token envelope was consolidated into `@aphrodite/core`
>       (`signSocketToken`/`createSocketTokenVerifier`/`resolveSocketTokenVerifier`
>       — one envelope so a single gateway secret serves all three services);
>       chat and devices now re-export the shared primitives (~90 lines of
>       duplicated crypto removed each), and vr verifies the handshake token on
>       connect and uses the signed userId (dropping `userId` from the event
>       payload). Core tagged `type:lib`/`scope:aphrodite` so the apps may
>       depend on it (needed `nx reset` for the boundary rule to see it); the
>       `rootDir` override was removed from the devices/vr tsconfigs to avoid
>       TS6059 on core-source types. Core 421, chat 71, devices 66, vr 4 (new).
>     - _Notification ws auth middleware (a5e3c4e45e):_ the notification ws read
>       `socket.data.userId` to authorize every operation, but no middleware
>       ever populated it, so all operations failed "Not authenticated"
>       (fail-closed, honest gap). `createNotificationHandler` now installs an
>       `io.use` handshake middleware on the shared `@aphrodite/core` verifier
>       (local `websocket/auth.ts`, `NOTIFICATIONS_SOCKET_TOKEN_SECRET`): it
>       verifies the signed token and sets `socket.data.userId` from the claim;
>       a missing/invalid token or no verifier rejects the connection. New
>       6-test spec (the ws layer had none); `rootDir` dropped from the
>       tsconfig. Notifications 94/94. All five aphrodite realtime socket layers
>       (chat, devices, vr, notifications;
>       analytics-dashboard/realtime-analytics were already clean) now verify
>       identity from the shared signed-token verifier — no client-trusted
>       identity remains in the socket layers.
>   - _Health-check dependency probes (9e31c12ee4):_ the readiness/detailed
>     health endpoints across six aphrodite services fabricated dependency
>     health — hardcoded `'healthy'`/`true`/`ok` behind
>     `// TODO: actual db check` / `// In production, ping ...`, so a load
>     balancer was told the service was ready even with its database down;
>     analytics-dashboard `/detailed` dressed up `abhHash`-derived fake
>     latency/hitRate/connection/ request metrics as real component health
>     (mislabeled `stub:legitimate`). Fixed: payment, broadcaster, viewer and
>     streaming run a real `checkDatabaseHealth()` probe (from
>     `@aphrodite/database`, already a dep) and gate readiness on it — `/ready`
>     now returns 503 when the DB is down instead of a fabricated 200 (payment
>     `/ready` previously returned `ready:true` unconditionally). Deps these
>     routes hold no client for (redis, kafka, MediaSoup/transcoding pools,
>     payment processor, cdn/S3) are reported honestly as `not_checked` and
>     excluded from the gate rather than faked; streaming `/stats` returns null
>     (not zero) for un-measured live-plane counters; analytics-dashboard/cdn
>     report `not_checked` with real process stats only. New `health.spec.ts`
>     per service (16 tests; these routes had none) assert readiness reflects
>     the real probe. Three pre-existing integration tests asserted the old
>     always-200 `/ready` and were updated to stub `checkDatabaseHealth` healthy
>     (partial mock, stores stay real). The eight other aphrodite health routes
>     were verified already real (`service.isHealthy`, real `redis.ping`/cache
>     round-trips, chat's real DB probe from slice 5) or liveness-only.
>   - _Alerts abhHash fabrication (339dcd7bfd):_ `analytics-dashboard/alerts.ts`
>     used an FNV-1a `abhHash` to fabricate computed-looking data in four
>     endpoints — alert history/active alerts, segment members (spending/watch-
>     time metrics fed to the real fit model), funnel analysis (user counts,
>     conversion rates). The app has no alert store and no event warehouse (only
>     a logger, in-memory cache, two scoring models). These now fail loud (501
>     `analytics_source_not_configured` via a shared `sourceNotConfigured`
>     helper); `abhHash` removed from the file; the real fit/quality models
>     untouched. 4-test spec. Suite 73/73.
> - **P0 DONE — analytics-dashboard warehouse build.** `abhHash` (FNV-1a, a
>   per-file copy) fabricated EVERY data route — dashboards.ts (38 sites),
>   viewers.ts (36), engagement.ts (53), revenue.ts (37), exports.ts (25),
>   trends.ts (37), predictions.ts (29) — ~255 sites across ~5,480 LOC, with
>   ZERO real data client. Investigation found the "real analytics source" I'd
>   pointed at does not exist: the analytics app is
>   InMemoryAnalyticsClient-only, the analytics-core dashboard services have
>   only Mock repos, and there are no analytics tables. User chose to BUILD THE
>   WAREHOUSE. Progress:
>   - _Foundation (651725d647):_ real `analytics_events` table (Prisma model +
>     migration 00004) and new lib `@aphrodite/analytics-warehouse` —
>     app-flavored analytics types + `IAnalyticsClient`, a real
>     `SqlAnalyticsClient` over `@aphrodite/database` (parameterized queryEvents
>     with WHERE/ORDER/LIMIT+ COUNT; `date_trunc('day')` GROUP BY metric
>     aggregations; jsonb INSERT) and a `MemoryAnalyticsClient` test double. 9
>     tests; SQL adversarially verified real.
>   - _Context wiring + revenue routes (170295091c):_ `getContext` exposes
>     `ctx.analyticsClient` (real Sql default; `setAnalyticsClient` test seam;
>     dashboard's unused app→app `@aphrodite/analytics` dep replaced by the
>     lib). revenue.ts fully de-fabricated: /overview, /by-source,
>     /transactions, /platform, /subscriptions, /creators earnings compute REAL
>     aggregates over the event store via a paged fetchEvents (sum by source,
>     per-day trend, distinct payers, fee = gross\*0.2); /projections fails loud
>     (501, no forecast model); tokens/gifts/upgrades = 0 (no event type, never
>     faked). 5-test spec asserts real computed values. suite 78/78.
>   - _All 7 route files wired (revenue 170295091c, exports 2e145891ed, viewers
>     c65ef3f9af, engagement cd8998cfe9, dashboards 9f5c356928, trends
>     7de1250720, predictions 3e9cb804ab):_ every abhHash route now aggregates
>     the real event store via the shared `fetchEvents` pager, or fails loud
>     where the shape has no source. Fail-loud (501
>     `analytics_source_not_configured`): all forecast/ projection endpoints,
>     trends /anomalies + /insights (fake "ARIMA"/"Isolation Forest" model-name
>     strings deleted), viewers /behavior + /cohorts, engagement /devices,
>     export-job + scheduled-report + dashboard-layout lifecycles. Honest
>     zero/empty/null for un-sourced sub-fields (systemHealth, goals, alerts,
>     recommendations, byLanguage, OS, avgConcurrent, brand/model).
>     predictions.ts feeds the REAL `@sophia/predictions` models real
>     event-store history (not fabricated inputs). 43 new tests across 7 route
>     specs, each asserting real values that FAIL against the old hash. **No
>     abhHash/Math.random /generate\* remains anywhere in the app; suite 112/112
>     (was 69).**
>   - _Ingestion producer (c81fba16eb):_ `backfillAnalyticsEvents`/`runBackfill`
>     in the warehouse lib — a real, idempotent ETL that derives
>     `analytics_events` from the existing aphrodite domain tables:
>     tips→tip.received, follows→ follower.added,
>     subscriptions→subscription.created (+ .cancelled when cancelled_at),
>     chat_messages→message.sent, view_sessions→viewer.joined (+ viewer.watched
>     when duration>0). Deterministic ids from source PKs +
>     `INSERT ... ON CONFLICT (id) DO NOTHING`, so re-running never duplicates
>     and a scheduled run with `since` is a continuous incremental sync. 9 tests
>     over a fake db; lib 18/18. **The loop is now end-to-end real: domain
>     tables → backfill producer → analytics_events → SqlAnalyticsClient → the 7
>     wired dashboard routes.** analytics-dashboard P0 fabrication is fully
>     remediated. (The BFF `events-ingest` is a separate client-telemetry
>     surface with GDPR erasure, not this warehouse's producer.)
>   - _Forward producer (eb34367b43):_ the analytics app's `createApp` now
>     defaults its client to the real `SqlAnalyticsClient` (was hardcoded
>     InMemory), so `POST /api/v1/events(/track)` persists to `analytics_events`
>     — a live forward producer alongside the backfill.
>     `AppConfig.analyticsClient` is the test seam; aligned the app's unused
>     `IAnalyticsClient` query/execute to `unknown[]` for structural
>     assignability; dropped the app tsconfig `rootDir` to avoid TS6059.
>     `app.spec.ts` proves POST→queryEvents round-trips a real event; 11/11. The
>     warehouse now has BOTH producers: historical backfill + live ingest.
> - **R-12 done (tags + neith constraint)** — all 451 untagged projects tagged
>   `scope:<domain>` (446 neith + 3 aphrodite + 1 iris + 1 yemaya,
>   JSON-validated); new `scope:neith` depConstraint (allows shared, contracts,
>   neith, and the typed `@nous` LLM-provider seam used by crash-intelligence).
>   Untagged-project escape hatch is closed; no wildcard constraint added (Nx
>   semantics make a useful one equivalent to enumerating every scope).
>   `apps/oshun/web` re-enable and the isis↔yemaya edge remain open — both need
>   violation-fix budgets.
> - **R-6 partial (evidence-corrected)** — the audit's B-2 had the canonical
>   tree wrong: `infrastructure/terraform` (not `infra/terraform`) owns the V1
>   state backends per its own deprecation notes and `deploy-ecs.yml`. Executed:
>   `deploy/terraform` (legacy EKS-era tree, deprecated 2026-07-04) deleted
>   after relocating its one live module (`modules/github-oidc` →
>   `infra/terraform/modules/`, consumer source updated); `infra/README.md`
>   added as the authoritative live-tree map with the single-root target layout.
>   Physical unification of the three live roots needs a deploy-verified window
>   (`terraform plan` + workflow working-directory updates in one change).
> - **R-9 partial** — `clients/demeter-python` → `sdks/` (zero references) and
>   `integrations/neith-vault` → `infra/neith-vault` (one spec path updated),
>   dissolving both single-entry roots. Deferred with reasons:
>   `services/{concordia,metis,psyche}` → `apps/` touches 118 tsconfig aliases +
>   5 deploy-critical workflows (psyche is in the ECS/Hetzner paths); root
>   `tara/` is live shared config wired into the mobile/web builds
>   (metro/jest/tsconfig relative paths).
> - **R-7/R-8 scoped, not executed** — renderer coupling measured at just 6
>   `tools/docs_center` files + 1 workflow filter (cheap to repoint), but the
>   walkthrough/DOMAINS trees are actively written by parallel sessions today
>   and V-tree moves invalidate 93 workflows' path filters; executing these
>   mid-flight invites the documented merge-clobber failure mode. Concrete
>   staged plan recorded in R-7/R-8 below; both need a quiet window and a single
>   dedicated change each.

### P1 — Structure consolidation

- **R-6. One infrastructure root.** Adopt `infra/` as canonical (it holds the
  active ECS/Fargate terraform); fold `infrastructure/*` and `deploy/*` into it
  (`infra/terraform`, `infra/helm`, `infra/k8s`, `infra/compose`,
  `infra/releases`); leave a README tombstone in each old path for one release.
  Delete the already-DEPRECATED trees after migration.
- **R-7. One documentation tree.** `docs/` becomes canonical source (md only):
  `docs/products/v1..v9/` (from V*/md), `docs/domains/` (merge DOMAINS/ +
  systems/ + platform/), `docs/walkthroughs/` (5 WALKTHROUGH dirs),
  `docs/audits/` (root reports). docs-center becomes a *renderer\* that reads
  `docs/`, not a second content store.
- **R-8. Pick one home per product.** Recommended target:
  `products/v<N>/{ue,services,web,libs,docs}` (or the equivalent under
  `apps/`+`libs/` if UE trees must stay at root for path-length reasons — then
  at least make V2/V4/V5 follow the V3 split so there is exactly one
  convention). Update the 56 v4 workflows' path filters as part of R-13.
- **R-9. Dissolve ambiguity dirs:** merge `services/*` into `apps/`
  (concordia/metis/psyche), `clients/demeter-python` and `sdks/*` into a single
  `sdks/` with a README, `integrations/neith-vault` next to its app, `tara/`
  assets into `apps/tara`. `apps/infra` → `tools/` or `infra/`.

### P1 — DRY closure

- **R-10. Create the missing bottom layer:** `@oshun/math` (clamp/lerp/…),
  `@oshun/ids`, `@oshun/resilience` (retry+backoff+sleep+circuit-breaker — fold
  the 4 shared-internal copies first so there is exactly one target),
  `@oshun/collections` (chunk/deepClone/deepMerge). Then codemod: the clamp
  signature is byte-identical in 1,234 files — this is a scripted find&replace
  plus import insertion, doable domain-by-domain with `nx affected`
  verification.
- **R-11. Finish the shared-lib migrations** (logging, http-client, database,
  cache, config) and enforce with lint: ban `from 'pino'`, `new Pool(`,
  `new Redis(`, and direct `process.env` outside `libs/shared` via
  `no-restricted-imports`/`no-restricted-syntax` (allow-list the 596 existing
  sites via one-time inline disables to ratchet, or migrate per-domain).
- **R-12. Close the boundary perimeter:** tag the 451 untagged projects
  (scripted from path), add a catch-all depConstraint (`sourceTag: '*'` →
  explicit), re-enable boundaries for `apps/oshun/web`, and resolve the
  isis↔yemaya bidirectional edge (extract the shared media-pipeline types into
  contracts).

> **P2 execution log (2026-07-16):**
>
> - **R-13 done (workflow collapse)** — the 51 foldable `v4-*` gates now live in
>   `V4/.ci/gates-manifest.json` (filters + commands lifted verbatim, round-trip
>   validated: 996 filters, 154 commands, 0 mismatches) behind one
>   `v4-gates.yml` (diff-driven slug matrix via git `:(glob)` pathspecs,
>   fail-open detection). 5 structural members kept standalone. 24
>   validator/JSON references repointed to the manifest. Verified: detector
>   correct on real ranges, two gates green end-to-end, `@v4/scripts` suite
>   190/191 (1 pre-existing todo-signoff failure). Workflow count 148 → 99.
>   Branch protection may need check-name updates.
> - **R-13a done (node SSOT)** — every direct `setup-node` pin (21× node-24, 9×
>   node-22) now uses `node-version-file: .nvmrc`. Two G-2b corrections: the
>   a11y nightly schedule is deliberately disabled (documented COST(pre-launch)
>   rationale), and the 10 composite-setup holdouts are lightweight jobs that
>   would _regress_ if forced through the full pnpm install — they keep
>   `setup-node`.
> - **R-16 partial** — commitlint scope-enum expanded from 22 to all 48
>   domains + v1–v10 + cross-cutting scopes (warning-level until the R-19
>   registry can generate it). Test-suffix enforcement deferred to the codemod
>   rollout.
> - **R-17 partial (evidence-corrected)** — sanctioned-framework and
>   overlapping-dependency policy written
>   (`docs/conventions/server-frameworks-and-deps.md`). The audit's "remove
>   `bcryptjs`/`crypto-js`" was wrong as a mechanical action: `crypto-js` is
>   load-bearing for React Native encryption-at-rest (Hermes has no
>   `node:crypto`; on-device ciphertext must stay decryptable) and
>   `bcryptjs`→`bcrypt` adds native compilation to six auth services' container
>   builds — both need per-service migrations, now documented in the policy.
> - **R-13b corrected, deferred** — the `scripts/isis/generate-v2-*` fleet is
>   _not_ thin shims: median 578 lines each (585K lines total) of embedded
>   per-artifact data over shared utils. Collapsing it is a data-extraction
>   refactor with artifact byte-comparison, not a sweep.
> - **R-14 corrected** — `parallel: 3` stays: the dev box has 4 cores/15 GB
>   shared across many worktrees and CI runners are 2–4 core; the audit's "raise
>   it" assumed hardware this repo doesn't run on. Target-shape standardization
>   (6,447 run-commands) remains the follow-up.
> - **R-15/R-18 deferred with evidence** — decorator-flag scoping and
>   `noUncheckedIndexedAccess` need graph-wide typecheck budgets; a root
>   `ruff.toml` would change lint results for the majority of the 83 Python
>   projects that today rely on ruff defaults (only ~30% embed `[tool.ruff]`),
>   so it ships with the per-project verification window, not before.

### P2 — Build/CI/conventions

- **R-13. Collapse workflow clones.** One reusable `product-gate.yml`
  (`workflow_call` with slug+paths inputs) or a generator that emits them from a
  JSON manifest; target ≤60 workflows total. Move the four Isis gates in
  `ci.yml` into project targets. Fix trigger drift: give `a11y-pa11y-nightly`
  and `v4-nightly-feel-tests` their missing `schedule:` (or rename them), align
  the 21 Node-24 jobs with `.nvmrc`/engines (22), and migrate the 10 hold-out
  workflows onto `./.github/actions/setup`.
- **R-13b. Consolidate scripts/tools.** Fold `scripts/docs/*` into the canonical
  `tools/` docs pipeline (one renderer); replace the 1,088
  `scripts/isis/generate-v2-*` per-artifact files with one parameterized
  generator + a manifest; adopt `tools/generators/*` (Nx generators) as the only
  scaffolding mechanism.
- **R-13c. Build a BFF substrate** (`@oshun/bff-kit` or similar: fastify app
  factory, auth/authz middleware, CORS, idempotency, error envelope — extracted
  from `apps/oshun/bff`'s mature middleware) and rename `@oshun/gateway`
  (Traefik CLI) to `@oshun/traefik-config` to free the name.
- **R-14. Standardize project targets.** Adopt Nx plugin inference (`@nx/vite`,
  `@nx/eslint`, custom cargo/pytest plugins) or one generator template; codemod
  the 6,447 run-commands variants down to a handful of shapes; delete
  per-project vitest configs where the preset suffices (top-8 hashes already
  cover ~700 identical files). Raise `parallel`, and evaluate self-hosted Nx
  remote cache for the fleet of worktrees.
- **R-15. One tsconfig preset chain:** make `configs/tsconfig/*` the only
  extension point (base → node/react/service/library), remove redundant per-lib
  re-declarations, add `noUncheckedIndexedAccess` to base, and scope decorator
  options to the 16 Nest packages.
- **R-16. Conventions:** one test-file suffix (`.spec.ts`) + placement
  (colocated) enforced by lint; commitlint scope-enum generated from the domain
  registry (error-level); README template per lib (one paragraph + owner +
  links) generated from `systems/*.md` as a starting point.
- **R-17. Dependency diet:** remove `bcryptjs`, `crypto-js`,
  `axios`/`node-fetch` (route through `@oshun/http-client`); pick `uuid` _or_
  `nanoid` per use-case policy; document fastify (services) + hono (edge/BFF) as
  the only two sanctioned server frameworks, freeze express/Nest for new code.
- **R-18. Rust & Python hygiene:** per-domain umbrella Cargo workspaces with
  `[workspace.dependencies]` catalogs; un-ignore and commit `Cargo.lock` for all
  binary/service workspaces; add root `ruff.toml` + adopt `uv` with committed
  lockfiles for the 83 Python projects.

> **P3 execution log (2026-07-16):**
>
> - **R-19 done** — `domains.json` registry (58 entries: purpose extracted from
>   the systems/ deep-dives, npm scope, scope tag, paths, project counts, owner,
>   status). `commitlint.config.js` reads it at load time; `.github/CODEOWNERS`
>   is generated from it (correction: a CODEOWNERS already existed but assigned
>   `@oshun/*` teams, impossible on a user-owned repo — every rule was inert);
>   `tools/domains/check-registry.mjs` runs in the CI quality job and
>   immediately surfaced 9 in-use non-domain scope tags, now tracked as declared
>   retag debt (`legacyScopes`).
> - **R-21 done** — `ARCHITECTURE.md` rewritten from the measured 2026-07-16
>   state (domain matrix generated from the registry; phase-14 checker's
>   required phrases preserved, failure set byte-identical before/after — its
>   remaining failures are pre-existing missing `libs/openapi` doc bundles that
>   never existed in any commit). `docs/audits/README.md` indexes all 60
>   archived reports.
> - **R-20 pilot done (datasets)** — the two dataset god-files extracted to JSON
>   data files with typed re-export shims: kalika `anomalous-data.ts` (54,156
>   lines → 17 + 1.4 MB `anomalous-data.tables.json`; 648 tests green, exact
>   values verified) and nisaba `character-database.ts` (25,508 → 85 lines +
>   `character-database.entries.json`; 8,231 tests green, lookups exact). Trap
>   for the rollout: name the JSON differently from the module — extensionless
>   imports become resolver-ambiguous otherwise. The maya `index.ts` monoliths
>   (28k/25k/22k lines) are code, not data — each needs a module-boundary design
>   pass, deferred.
> - **R-12 closed (dedicated-window session, 2026-07-16)** — the isis→yemaya
>   edge dissolved: the fourteen isis/3d-generation imports were generic
>   utilities (typed event emitter + console logger) living in `@yemaya/core`;
>   they moved verbatim to a new `@oshun/events` foundation lib, `@yemaya/core`
>   re-exports (486 tests green), isis repointed (55 tests green, zero `@yemaya`
>   imports remain). And the `apps/oshun/web` boundary opt-out proved obsolete:
>   with it removed, a full boundary lint reports **zero violations** — only 24
>   stale eslint-disable directives, now stripped. No blanket boundary opt-outs
>   remain in the workspace.
> - **verify-fleet migration COMPLETED per-family (dedicated-window sessions,
>   2026-07-16)** — after a first mechanical attempt was reverted (384 gate
>   scripts self-assert their npm wiring), all four families were migrated
>   deliberately with full-fleet baseline diffing: v7 (3 gates) and v8 (1) as
>   the pattern prover, then v6 (129 gates, 989 wiring reference lines, four
>   transformer rounds + five hand-migrated gates) and v3 (270 gates, one
>   uniform transformer + seven hand-anchored variants). Every family re-ran
>   against its pre-migration baseline with ZERO pass/fail flips: v6 keeps its 5
>   pre-existing reds, v3 its 27. All gates now run through
>   `scripts/verify.mjs` + `scripts/verify-manifest.json`; root package.json is
>   down from 549 scripts at audit time to 128.
> - **R-22 deferred with plan** — splitting `.env.example` (388 vars) requires
>   per-var ownership analysis (grep-based assignment mis-labels shared vars)
>   and the docs-center env page parses the root file; execute as: analysis
>   script → per-app `.env.example` files → root file becomes the generated
>   aggregate → renderer repointed, all in one change.

> **R-7 re-scoped on evidence (dedicated-window session, 2026-07-16):** the five
> `*_WALKTHROUGH/` trees are **not documentation sprawl and must not be moved**:
> they are a machine-integrated evidence pipeline — ~700 code files reference
> them, including the entire `apps/oshun/web/e2e` suite (which writes journey
> evidence into them), the playwright configs, and the mobile/web route-parity
> contract tests that parse them. Verifying a move requires the full e2e run
> against the live app, which no consolidation window on this box can provide.
> Finding B-4 is corrected accordingly. The genuinely movable R-7 remainder,
> with named consumers to repoint: `systems/` (phase-8/65 checkers + 4
> `tools/docs_center` files), `platform/` (phase-98 checker + v6
> privileged-access/DSAR gates), and `DOMAINS/` (renderer
> domains/coverage/platform modules,
> `scripts/docs/verify-domains-source-of-truth.mjs`, `render-domain-docs.py`,
> reader spec — plus relative-link depth rewrites in 326 files). Each is locally
> verifiable via the renderer gates + the v6 gate fleet, and each is a single
> dedicated change.

### P3 — Longer-term architecture

- **R-19. Domain registry as code:** one `domains.json` (name, purpose, owner,
  scope tag, npm scope, docs link, status) — generate commitlint scopes,
  CODEOWNERS, `DOMAINS.md`, and the boundary-tag lint from it. Add CODEOWNERS
  (none exists today).
- **R-20. Split god files:** budget-driven refactor of the 10 largest source
  files (move datasets to `.json`/binary assets loaded at runtime or build step;
  split maya `index.ts` monoliths into modules with an index barrel).
- **R-21. Refresh `ARCHITECTURE.md`** (or replace with a generated overview from
  the domain registry + Nx graph export) and mark the 60+ historical root
  reports as archived in their new `docs/audits/` home.
- **R-22. Env config ownership:** split `.env.example` per app with a generated
  aggregate; pair with `@oshun/config` schema adoption (R-11) so every var has a
  typed owner.

---

## 5. Suggested target top-level layout

```
/
├── apps/            # all deployables (absorbs services/, flat naming: <domain>-<surface> or <domain>/<surface> — pick ONE)
├── libs/            # domain + shared libraries (unchanged concept)
├── products/        # V1–V9 product trees (ue/, content/, docs/ per product)  [or keep V*/ but make all nine follow one internal convention]
├── infra/           # terraform, helm, k8s, compose, releases (absorbs infrastructure/, deploy/, docker/)
├── tools/           # durable repo tooling (absorbs scripts/ one-offs after pruning)
├── docs/            # ALL markdown documentation (audits/, products/, domains/, walkthroughs/, adr/, runbooks/)
├── sdks/            # external-facing SDKs (absorbs clients/, integrations/)
├── testing/         # shared test infra (fixtures, e2e harnesses; absorbs tests/)
└── [configs at root: nx.json, pnpm-workspace.yaml, tsconfig.base.json→configs/tsconfig, eslint.config.js (thin), .github/]
```

Everything else currently at root (WALKTHROUGH*, DOMAINS/, systems/, platform/,
TODOS.md, 71 reports, vdocs-*, backups/, stray \*.ts) either moves into one of
the eight buckets or leaves git.

---

## 6. Appendix — raw measurements

- Tracked files by top dir: libs 78,348 · apps 28,538 · V2 6,448 · docs 6,241 ·
  V4 3,053 · scripts 2,909 · V5 2,122 · WALKTHROUGH 1,713 · services 1,325 · V3
  705 · deploy 423 · V6 364 · DOMAINS 326 · infra 318 · docs-center 314 ·
  testing 281 · docker 253 · TODOS 247 · V1 199 · tools 165 · .github 155.
- Artifact weight: Swift `.build/` 576.6 MB (6,140 files) · HTML 130.7 MB (3,815
  files; 2,768 md-twins) · backups 119.3 MB · Hardhat 24.1 MB.
- Executors: run-commands 6,447 · eslint 1,646 · vite:test 1,512 · js:tsc 1,170
  · esbuild 148 · js:node 34 · vitest 33 · run-script 27 · jest 2 ·
  angular-storybook 2.
- Test files: colocated spec 9,834 · colocated test 5,286 · **tests** 1,178 ·
  libs tests/ 364. jest packages 16 · vitest packages 2,100.
- Server frameworks (package.json occurrences): fastify 114 · hono 67 · express
  19 · @nestjs/core 16. Next apps 26 · Expo/RN app.json 71.
- Workflows: 148 total · v4-_ 56 · v2-_ 7 · iris-\* 7 · schedule-trigger 8 ·
  dispatch-only 16 · workflow_call 1 · composite-setup users 112 (10 bypass) ·
  node-24 pins 21 vs node-22 pins 10 · YAML LOC 27,736 · V#-targeting 93 vs
  apps-targeting 47 · stale path filters 1 (`v3-workspace.yml`).
- scripts/: 2,909 files — isis 2,256 (1,088 `generate-v2-*`) · v3 274 · lilith
  140 · v6 129 · audit 23 · root 43 (26 `verify-phase-*`).
- BFF divergence: oshun 1,987 src ts · lilith 385 · kalika 9 · urania 0 (dead
  app).
- Cross-domain import leaks (non-self, non-shared): yemaya→oya 10,
  yemaya→aphrodite 10, isis→yemaya 14, yemaya→isis 8, psyche→isis 4, psyche→iris
  4, sophia→kalika 2, hathor→neith 7, aphrodite→aja 6.
- pnpm: catalog refs 8,803 · pinned semver in workspace manifests 4,252 ·
  catalog entries ~350.
- Rust: Cargo.toml 1,437 · workspace roots 505 · tracked Cargo.lock 64 (globally
  gitignored at `.gitignore:288`).
- eslint.config.js 1,638 lines · depConstraints 44 · allow-list ~15 · untagged
  projects 451 (446 neith).
- tsconfig.base.json 172 KB · 2,164 aliases · 2 dead · preset users
  (configs/tsconfig) 83 files.
- Root: 113 tracked files · 71 md reports · TODOS.md 7.7 MB · .env.example 388
  vars · package.json 549 scripts (441 verify:phase).

---

## 7. Final reconciliation ledger (2026-07-18)

Every finding and recommendation adjudicated: **done** (executed and verified
in-tree on 2026-07-18), **corrected** (the audit's premise was wrong — the
correction is the resolution), or **deferred** (an explicit, owner-gated
decision with the reason recorded — not an omission). Verification for this
ledger re-checked the tree directly (paths, configs, CI wiring), not just the
execution logs above.

| Finding                       | Status                                                                                                                                                                                                                                                                                                                                                                                 |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| A-1/A-2 Swift builds, backups | **Done** (R-1: 6,147 files untracked; `scripts/check-forbidden-paths.sh` guards in ci quality job)                                                                                                                                                                                                                                                                                     |
| A-3 generated HTML            | **Done** (R-2: 3,086 untracked; hook regen removed; `vdocs-html-fresh.yml` builds+verifies; `docs/audits/*.html` confirmed untracked 2026-07-18)                                                                                                                                                                                                                                       |
| A-4 Hardhat artifacts         | **Done, corrected** (ABIs are svc-blockchain runtime inputs and stay; only build-info purged)                                                                                                                                                                                                                                                                                          |
| A-5 root landfill             | **Done** (54 reports → docs/audits; dead scripts deleted; TODOS.md a pointer; 19 root .md remain = tooling-parsed + active ledgers, incl. DOCS_CENTER_PAGE_AUDIT which self-declares in-flight)                                                                                                                                                                                        |
| A-6 LFS unused                | **Done** for the one raw pattern-match (BootMap.umap via filter re-add). animation_catalog/seed-registry match no declared pattern — LFS-ing them is a policy + CI `lfs:true` coupling decision, **deferred explicitly**                                                                                                                                                               |
| A-7 Cargo.lock contradiction  | **Done** (global ignore removed; umbrella lock committed; sampled `cargo check --locked` green)                                                                                                                                                                                                                                                                                        |
| A-8 stale top docs            | **Done for ARCHITECTURE.md** (rewritten from measured state, R-21). DEPENDENCIES.md / RESPONSIBILITY_SPLIT stay at root as tooling-parsed archives — archived-in-place, indexed as such                                                                                                                                                                                                |
| B-1 top-level concept mix     | **Substantially done** via R-3/R-7/R-9 (systems/platform/DOMAINS/tara/clients/integrations/backups dissolved). Remainder rides B-5 and B-3 below                                                                                                                                                                                                                                       |
| B-2 four infra dirs           | **Partial, corrected** (canonical tree is `infrastructure/terraform`, not infra; legacy `deploy/terraform` deleted; `infra/README.md` is the live map). Physical single-root unification is **deploy-gated** — needs a terraform-plan-verified window                                                                                                                                  |
| B-3/H-5 product placement     | **Deferred with plan** (R-8): V-tree moves invalidate 93 workflows' path filters; single dedicated change in a quiet window. V10 is the designated first adopter                                                                                                                                                                                                                       |
| B-4 8+ docs surfaces          | **Done, corrected** (walkthrough trees are a machine evidence pipeline — must not move; systems/, platform/, DOMAINS/ moved under docs/; docs-center is the renderer; docs/audits README indexes reports)                                                                                                                                                                              |
| B-5 services/ vs apps/        | **Deferred, owner-gated**: services/{metis,psyche,concordia} are wired into deploy-ecs.yml, deploy-hetzner.yml, terraform variables — moving without a deploy-verified window risks production                                                                                                                                                                                         |
| B-6 naming variance           | **Done where mechanical** (SCREAMING doc dirs gone; urania gone; orphan `libs/tsconfig.test.json` deleted 2026-07-18 after a zero-reference check). Flat-vs-nested app naming folds into the R-8 decision                                                                                                                                                                              |
| C-1 hand-rolled targets       | **Deferred as R-14 follow-up**; first slice done (top-4 vitest-config hashes → 2 presets, 457 files)                                                                                                                                                                                                                                                                                   |
| C-2 parallel:3                | **Corrected** — stays (4-core box shared by worktrees; CI runners 2–4 core)                                                                                                                                                                                                                                                                                                            |
| C-3 named-input phantoms      | **Done** (phantom refs removed; root ruff.toml now real via R-18 python hygiene)                                                                                                                                                                                                                                                                                                       |
| C-4/H-2 boundary perimeter    | **Done** (R-12: 451 projects tagged, scope:neith constraint, apps/oshun/web opt-out removed with zero violations, legacy scopes retagged; registry check in CI)                                                                                                                                                                                                                        |
| C-5/R-15 tsconfig presets     | **Deferred with evidence**: graph-wide typecheck budget required; noUncheckedIndexedAccess proven viable only in mobile so far                                                                                                                                                                                                                                                         |
| C-6 tsconfig.base contention  | Dead aliases removed (R-5). The 2,164-alias sharedGlobals invalidation cost is **accepted** — no cheap fix short of Nx ts-project-references migration                                                                                                                                                                                                                                 |
| C-7 lint-plugin excludes      | **Recorded as R-14 follow-up** (target standardization decides what's linted where)                                                                                                                                                                                                                                                                                                    |
| C-8 release config            | **Done 2026-07-18**: ADR-0073 — nx release owns releases (it is what release.yml runs); dormant changesets scripts + devDep removed; root-level-only scope documented as deliberate                                                                                                                                                                                                    |
| D-2 overlapping deps          | **Done via policy + corrections** (crypto-js/bcryptjs are load-bearing, per-service migrations documented in docs/conventions/server-frameworks-and-deps.md). 2 remaining `@nx/jest` executors (bellona build/render-api) recorded as R-14 debt                                                                                                                                        |
| D-3 four HTTP frameworks      | **Done via policy**: fastify (services) + hono (edge/BFF) sanctioned; express/Nest frozen for new code                                                                                                                                                                                                                                                                                 |
| D-4 549 root scripts          | **Done** (verify:phase dispatcher + per-family verify-fleet migration with zero pass/fail flips; 549 → 128 scripts; manifest + scripts/verify.mjs)                                                                                                                                                                                                                                     |
| D-5 505 Rust workspaces       | **Done** (R-18: neith umbrella 599 members + kalika/oya/euterpe umbrellas; refusals documented — yemaya-raster-gpu standalone-by-design, maya proper multi-crate)                                                                                                                                                                                                                      |
| D-6 Python no locks           | **Done** (root ruff.toml consensus config; uv 57/59 + poetry 21/24 locks committed; 5 never-resolvable manifests documented)                                                                                                                                                                                                                                                           |
| D-7 env monolith              | **Done** (per-app .env.example derived from real refs + `--check` in CI; root stays canonical **by design** — deviation from R-22's generated-aggregate shape, reason logged)                                                                                                                                                                                                          |
| E DRY collapse                | **Done + enforced**: R-10 rollout complete (9 waves, 65 documented refusals); ids via uuid()-wrapper wave + no-handrolled-ids WARN rule; **2026-07-18: conventions ratchet in CI** (pino/pg/ioredis/process.env/CircuitBreaker/sleep file-set baselines). http-client/gpu-dispatcher internal-retry rewiring onto @oshun/resilience stays a recorded follow-up (HTTP-typed public API) |
| F-1 test suffix split         | **Convention + ratchet 2026-07-18**: .spec.ts documented as the convention; \*.test.ts count frozen at 12,602 in CI. Mass rename declined (config churn, no behavioral gain)                                                                                                                                                                                                           |
| F-2 commit scopes             | **Done** (scope-enum reads domains.json; warning-level with a written promotion condition)                                                                                                                                                                                                                                                                                             |
| F-3 no lib READMEs            | **Done 2026-07-18**: 2,466 READMEs generated from package descriptions + registry (owner, docs links, nx commands) via tools/docs/generate-lib-readmes.mjs; hand-written ones untouched                                                                                                                                                                                                |
| F-4 no name→purpose registry  | **Done** (domains.json + generated CODEOWNERS/commitlint; DOMAINS.md carries a canonical-pointer header as of 2026-07-18)                                                                                                                                                                                                                                                              |
| F-5 eslint monolith           | **Deferred with reason**: splitting the 1,638-line flat config into per-project configs is high-blast-radius config surgery on 1,646 lint targets; revisit alongside R-14 target standardization                                                                                                                                                                                       |
| F-6/H-4 god files             | **Done** (datasets → JSON with typed shims; six maya monoliths → 46 modules; game-pipeline → 7 modules; export surfaces asserted identical)                                                                                                                                                                                                                                            |
| F-7 TODO debt                 | **Done as specified** (burn-down tool + committed ledger) **and far beyond**: aphrodite scaffold burn-down slices 1–11, socket-auth, health-probe, alerts, notifications, and the analytics warehouse P0 all remediated; remaining plain markers tracked in TODO_BURNDOWN.md                                                                                                           |
| G-1 workflow clones           | **Done** (51 v4 gates → gates-manifest + one matrix workflow; 148 → 99 workflows, 102 today with net-new product lines)                                                                                                                                                                                                                                                                |
| G-2 trigger drift             | **Done** (the single stale path filter removed from v3-workspace.yml 2026-07-18; both "nightly" workflows carry documented COST(pre-launch) disabled schedules)                                                                                                                                                                                                                        |
| G-2b node drift               | **Done** (every setup-node pin → `node-version-file: .nvmrc`; 10 lightweight holdouts documented as deliberate)                                                                                                                                                                                                                                                                        |
| G-3 pre-commit builds         | **Done for the finding's core** (HTML regen/re-stage removed; hook now gates only)                                                                                                                                                                                                                                                                                                     |
| G-4 inline Isis gates         | **Recorded follow-up** under R-14 (move into project targets so affected scopes them); ci.yml remains correctly nx-affected for lint/build/test                                                                                                                                                                                                                                        |
| G-5 scripts/ codegen mass     | **Corrected + deferred**: generate-v2-\* fleet is 585K lines of embedded per-artifact data, not shims — collapsing it is a data-extraction refactor with byte-comparison, queued behind owner priorities                                                                                                                                                                               |
| G-6 two doc toolchains        | **Done 2026-07-18**: scripts/docs/\* moved into tools/docs (single home; verifier proven byte-identical, its 111 advisory content-drift findings pre-date the move and are a docs-content follow-up)                                                                                                                                                                                   |
| H-1 isis↔yemaya edge          | **Done** (generic utilities → @oshun/events; isis has zero @yemaya imports; boundary lint clean)                                                                                                                                                                                                                                                                                       |
| H-3 four BFFs                 | **Done** (R-13c: @oshun/bff-kit incr 1+2 with fail-closed seams; @oshun/gateway → @oshun/traefik-config; lilith+kalika adopted kit tracing; deeper adoption = owner feature work by design)                                                                                                                                                                                            |
| H-6 dead/hollow apps          | **Done** (urania removed; 2026-07-18 re-verification: all seven formerly-hollow apps now have per-service project.json with **zero uncovered tracked sources** — v7's shared service_contract.rs is explicitly in the v7Production named input; apps/psyche fully covered; euterpe-studio-web covered)                                                                                 |
| H-7 layout vocabulary         | **Deferred into R-8/R-16**: naming standardization lands with the product-placement decision, not as a standalone rename sweep                                                                                                                                                                                                                                                         |
| R-1 history rewrite (tail)    | **Deferred, owner-gated**: git-filter-repo/fresh-clone-point requires coordinating every active worktree and force-pushing main, which is forbidden without the owner driving the window                                                                                                                                                                                               |

### Deferral grind session (later 2026-07-18)

Every remaining deferral was either executed or advanced to a measured,
owner-executable runbook:

- **Executed:** the last 2 `@nx/jest` stragglers → vitest (D-2); the four inline
  Isis gates → project targets behind one cached `run-many` (G-4); vitest-config
  dedup slice 2 — 303 more files onto presets incl. a rooted factory trio,
  threshold enforcement proven byte-equivalent (R-14); 392 tsc launcher prefixes
  normalized across 260 project.json (R-14); the domains source-coverage
  registry reconciled 111→0 and its gate CI-wired; both large plain blobs
  LFS-tracked with the seed registry's own pre-existing drift regenerated (A-6
  tail); **`infrastructure/*` absorbed into `infra/`** with offline
  `terraform validate` + checker/spec proofs — the R-6 root count is down to the
  deploy/-gated half; the red isis coverage-formulas gate fixed at the
  vocabulary level (new `studio` domain, 15 families authored from workflow
  definitions, registry canonicalized — 7/7 metrics back at 100%); R-13b pilot —
  17 per-format ingest-certification generators collapsed to one manifest-driven
  generator with normalized byte-equivalence proof; first F-5 composition slice
  — lilith carve-outs extracted with `--print-config` byte-identical proof.
- **Adjudicated with evidence (E follow-up):** the four shared-internal retry
  copies are domain-typed public APIs whose observable contracts
  (additive-above-cap jitter, strategy families, polling semantics, frozen
  compat surface) the generic `@oshun/resilience` cannot express without silent
  behavior change — refusals recorded at each site, legacy copy `@deprecated`,
  ratchet blocks new duplication.
- **Runbooks (owner-gated on hard evidence):** services/→apps/ (79-file
  live-reference inventory; `deploy-hetzner.yml` auto-fires on main pushes and
  is under active parallel development) —
  `SERVICES_TO_APPS_MIGRATION_ RUNBOOK_2026-07-18.md`; history rewrite measured
  on a real filter-repo dry run (pack 1.2 GiB → 889 MiB) —
  `HISTORY_REWRITE_RUNBOOK_2026-07-18.md`; R-8 decided (split convention
  binding; staged V5→V2→V4 convergence) —
  `R8_PRODUCT_PLACEMENT_DECISION_2026-07-18.md`.

### Prelaunch-authorized execution (later still, 2026-07-18)

The owner confirmed the platform is prelaunch on everything, dissolving the
deploy-risk gating. Executed: **services/ → apps/ landed** (B-5/R-9 closed:
concordia, psyche flattened beside admin/, metis python backend as
apps/metis/service; all 79 live references rewired; concordia 122/122; python
compileall green — repairing a mojibake-corrupted dict that had made psyche
knowledge-base cleaning.py unparseable since authoring; nx graph, domains
verifier, env sync, filter glob-tests all green; the stub scan gained R100
rename-awareness so pure moves stop re-litigating pre-existing hits). **R-13b
wave 2:** packaging + integrity families (33 scripts) joined the manifest-driven
generator with 66/66 byte-equivalence; the contract family is a documented
refusal (configs carry per-format code). Remaining in the fleet: contract ×14,
engine-bundle ×4, self-contained bulk. Still queued: R-6 deploy/\* half, R-8
staged V5/V2/V4 convergence (both now prelaunch-unblocked, each a dedicated
change); history rewrite remains owner-executed (force-push policy).

Net additions in this reconciliation pass (2026-07-18): ADR-0073 + changesets
removal (C-8); conventions ratchet + CI wiring + baselines (E, R-11, F-1); 2,466
generated lib READMEs + generator (F-3); docs tooling single home (G-6);
DOMAINS.md canonical pointer (F-4); sdks/README (R-9); orphan
libs/tsconfig.test.json + stale v3-workspace path filter removed (B-6, G-2);
VRM4U submodule `ignore = dirty` (R-1 status noise); stray in-place compile
artifacts cleaned from the working tree. Deferred items are all owner-gated
(deploy windows, history rewrite, product-tree moves) or explicitly
cost-adjudicated (eslint split, tsconfig presets, run-commands standardization)
— each carries its reason above and in the execution logs.
