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, theV1_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 theV10/product tree later on 2026-07-16, resolving their finding A-5 entries) andlibs/contracts/src/v10/(channel contract + spec — correctly placed per the contracts convention). TheV10/product tree now also carriesV10_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 (SCREAMINGSNAKE, 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-patterns, 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-rolledgenerateIds;jestin 16 packages vsvitestin 2,100 (the 16 include legit Expo/RN presets, but also 2@nx/jest:jeststragglers); 103jest-scoped imports insidelibs/lilithalone.
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
4. Recommendations (prioritized)#
P0 execution log (2026-07-16):
- R-5 done — dead
@oshun/loggeraliases removed; phantompoetry.lock/root-pyproject.toml/ruff.tomlrefs dropped fromnx.json; yemaya studio-web storybook targets moved off the never-installed@storybook/angularexecutors;nx releasescope 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 todocs/audits/after verifying zero inbound links and only intra-set outbound links; docs-center render +--verifygreen with the reports adopted as discipline docs. Kept at root: tooling-parsed reports (see meta-note) and active planning docs.TODOS.mdretirement 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-Nnpm scripts replaced byscripts/verify-phase.mjsdispatcher (pnpm verify:phase <n>); CI, the bellona composite gate, five self-wiring checkers, and doc call sites updated. The 403verify:v3/v6/v7/v8entries 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, missingapps/oshun/web/src/middleware.ts,@nisabamappings) — phase 65 runs innisaba-ci.yml, so that gate was already red.- R-4b done (urania) —
apps/uraniawas 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 Hardhatbuild-info/; gitignore rules added and a regex-basedscripts/check-forbidden-paths.shgate 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.ymlreworked from freshness-check to build +--verify+ artifact upload;vdocs-reader-ui.ymlnow renders before testing; generated paths gitignored (with carve-outs for V2/web hand-writtenindex.htmlpages and TypeDoc trees underdocs/). Follow-up: the 540 TypeDoc API-reference pages underdocs/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/VRM4Ustray status noise (submodule bump hygiene). Add CI guard (aforbidden-pathscheck) 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 conventiondocs/auditsalready uses); delete the eight dead root scripts; movetypedoc.kalika.json,lighthouse.config.jsetc. next to their owners; retireTODOS.md(8 MB) in favor of the already-splitTODOS/dir. - R-4. Collapse
verify:phase-*: onescripts/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). Bringapps/psyche/*andapps/euterpe-studio-webfully under Nx projects soaffectedsees them. - R-5. Fix config drift now: remove the 2 dead
@oshun/loggeraliases; fix or delete the phantomruff.toml/pyproject.toml/poetry.lockrefs innx.json; verify/repairnx release.projects; remove the 2@storybook/angularexecutors.
P1 execution log (2026-07-16):
- R-10 done (foundation + pilot) —
@oshun/math,@oshun/ids,@oshun/collections,@oshun/resiliencecreated (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/mathwith 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/resilienceis 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
rootDirtsconfig 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 matchedimportlines inside embedded template-literal scripts, dropping one insert mid-class — all four waves audited, one occurrence). Repairs riding along: an invalidreadonlyindexed-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 fabricatedclip-vit-base-patch32modelId (nowdeterministic-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 sharedclampQuantizedhelper is a follow-up design decision, not a mechanical dedup. The initial mass test failures were a stale gitignored@oshun/aidist missing theopenai-compatiblesubpath — 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 adjacentMath.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) andclampFinite(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-identicalcrypto.randomUUID()wrapper family migrated to@oshun/idsuuid()(arete/balance, 7 files, 240 tests green), and a newoshun-stub/no-handrolled-idsWARN 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.xparserOptionsform) — fixed to flat-configlanguageOptions, all plugin rule tests actually run again.- Per-app env split (2026-07-16):
tools/env/split-env-examples.mjsderives one.env.exampleperapps/<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.examplestays canonical; generated files carry a referenced-but-uncanonical section so drift surfaces instead of hiding.--checkwired 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.mdoperational 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--verifyintegrity (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 toapps/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.pyconsolidated 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.tomlfrom 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-kitcreated 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/gatewayrenamed 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 hasnoCheck: 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: stalenode_modules/.viteserves 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.tsgod files (126,667 lines) split into 46 dependency-sound modules + barrels bytools/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--filemode (header imports distributed per-module with relative paths rebased; modules dir named<stem>-modulesto dodge the extensionless-resolution trap), and yemaya's 14,927-linegame-pipeline.tsbecame 7 dependency-sound modules + an 11-line barrel — 232 public exports preserved, theexport * as gamePipelineconsumer 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 CIlfs: truecheckout 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 501model_gapfor 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-idfrom 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 calculationcomments while the raw analytics event stream (queryEvents) carried the data. Now computed for real via a pagedfetchEventsand 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 plainTODOmarkers, 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 —
deliverViaChannelreturnedtruefor every channel (// For now, simulate success), so a notification was markedsentwhen nothing was delivered, and the app-level email handler was aconsole.logno-op (// In production, would look up user email) while push failures were swallowed. Delivery is now real:NotificationServicehas a per-channel deliverer registry (registerDeliverer/hasDeliverer);deliverViaChannelawaits the registered transport and returns its actual accept/reject result (thrown errors flow to the existing retry/mark-failed path).in_appstays deliverable with no transport (already durably persisted + best-effort WS push); push/email/sms with no transport raiseChannelNotConfiguredError(a real failure) instead of fabricating success.app.tswires a real push transport and, behind aresolveRecipientEmailseam, 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 provingsentis 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-offstub:legitimatecarve-out.- Socket layers (2026-07-17): the correct adversarial lexicon scan (an earlier per-dir scan used a PCRE lookahead that
grep -Esilently 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 (
handleConnectionreadhandshake.auth.userId;socket.data.roles = handshake.auth.roles), so any client could claim any identity and grant itself moderation via theisModerator/isRoomOwnerTODO stubs. Newsocket/auth.tsverifies an HMAC-signed token (signSocketToken/createHmacTokenVerifier, constant- time) in anio.usemiddleware; identity comes only from signed claims; fails closed with noCHAT_SOCKET_TOKEN_SECRET. 13 tests.- Chat DM persistence (7e96cf1aff):
dm.tskept its own in-memory Maps, so socket DMs were invisible to the HTTP/conversationsview (the realdmStore) and lost on restart, and the list handlers abuseddm_errorcodeSUCCESSto return data. Rewired to the shareddmStore(pairKey = conversationId); real block enforcement; two new typed events. 5 tests.- Chat clear-chat (dfc322fa62):
mod_clear_chatannouncedchat_clearedbehind// TODO: Clear messages from database— a fabricated clear. Added a realChatMessagesStore.clearRoombulk soft-delete and wired it. The mute/slow-mode maps are honestly relabeledstub:legitimateper-node ephemeral state (a horizontal-scaling concern like the socket.io Redis adapter, not a fabrication). 3 tests.- Device gateway auth (4616492759):
extractUserIdreturnedhandshake.query.userId ?? handshake.auth.tokenunverified, so any client could drive any user's intimate hardware. Newwebsocket/auth.tsverifies a signed token (envelope matches chat's, so one gateway secret serves both);DeviceSessionManagerfails closed withoutDEVICE_SOCKET_TOKEN_SECRET. 7 tests.- VR socket auth + verifier consolidation (60f5127db1): the vr playback ws trusted
data.userIdfrom thesession:startpayload, 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 (droppinguserIdfrom the event payload). Core taggedtype:lib/scope:aphroditeso the apps may depend on it (needednx resetfor the boundary rule to see it); therootDiroverride 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.userIdto authorize every operation, but no middleware ever populated it, so all operations failed "Not authenticated" (fail-closed, honest gap).createNotificationHandlernow installs anio.usehandshake middleware on the shared@aphrodite/coreverifier (localwebsocket/auth.ts,NOTIFICATIONS_SOCKET_TOKEN_SECRET): it verifies the signed token and setssocket.data.userIdfrom the claim; a missing/invalid token or no verifier rejects the connection. New 6-test spec (the ws layer had none);rootDirdropped 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/okbehind// TODO: actual db check/// In production, ping ..., so a load balancer was told the service was ready even with its database down; analytics-dashboard/detaileddressed upabhHash-derived fake latency/hitRate/connection/ request metrics as real component health (mislabeledstub:legitimate). Fixed: payment, broadcaster, viewer and streaming run a realcheckDatabaseHealth()probe (from@aphrodite/database, already a dep) and gate readiness on it —/readynow returns 503 when the DB is down instead of a fabricated 200 (payment/readypreviously returnedready:trueunconditionally). Deps these routes hold no client for (redis, kafka, MediaSoup/transcoding pools, payment processor, cdn/S3) are reported honestly asnot_checkedand excluded from the gate rather than faked; streaming/statsreturns null (not zero) for un-measured live-plane counters; analytics-dashboard/cdn reportnot_checkedwith real process stats only. Newhealth.spec.tsper service (16 tests; these routes had none) assert readiness reflects the real probe. Three pre-existing integration tests asserted the old always-200/readyand were updated to stubcheckDatabaseHealthhealthy (partial mock, stores stay real). The eight other aphrodite health routes were verified already real (service.isHealthy, realredis.ping/cache round-trips, chat's real DB probe from slice 5) or liveness-only.- Alerts abhHash fabrication (339dcd7bfd):
analytics-dashboard/alerts.tsused an FNV-1aabhHashto 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 (501analytics_source_not_configuredvia a sharedsourceNotConfiguredhelper);abhHashremoved 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_eventstable (Prisma model + migration 00004) and new lib@aphrodite/analytics-warehouse— app-flavored analytics types +IAnalyticsClient, a realSqlAnalyticsClientover@aphrodite/database(parameterized queryEvents with WHERE/ORDER/LIMIT+ COUNT;date_trunc('day')GROUP BY metric aggregations; jsonb INSERT) and aMemoryAnalyticsClienttest double. 9 tests; SQL adversarially verified real.- Context wiring + revenue routes (170295091c):
getContextexposesctx.analyticsClient(real Sql default;setAnalyticsClienttest seam; dashboard's unused app→app@aphrodite/analyticsdep 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
fetchEventspager, or fails loud where the shape has no source. Fail-loud (501analytics_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/predictionsmodels 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/runBackfillin the warehouse lib — a real, idempotent ETL that derivesanalytics_eventsfrom 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 withsinceis 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 BFFevents-ingestis a separate client-telemetry surface with GDPR erasure, not this warehouse's producer.)- Forward producer (eb34367b43): the analytics app's
createAppnow defaults its client to the realSqlAnalyticsClient(was hardcoded InMemory), soPOST /api/v1/events(/track)persists toanalytics_events— a live forward producer alongside the backfill.AppConfig.analyticsClientis the test seam; aligned the app's unusedIAnalyticsClientquery/execute tounknown[]for structural assignability; dropped the app tsconfigrootDirto avoid TS6059.app.spec.tsproves 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); newscope:neithdepConstraint (allows shared, contracts, neith, and the typed@nousLLM-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/webre-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(notinfra/terraform) owns the V1 state backends per its own deprecation notes anddeploy-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.mdadded 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) andintegrations/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); roottara/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_centerfiles + 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); foldinfrastructure/*anddeploy/*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 readsdocs/, 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 underapps/+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/*intoapps/(concordia/metis/psyche),clients/demeter-pythonandsdks/*into a singlesdks/with a README,integrations/neith-vaultnext to its app,tara/assets intoapps/tara.apps/infra→tools/orinfra/.
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 withnx affectedverification. - 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 directprocess.envoutsidelibs/sharedviano-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 forapps/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 inV4/.ci/gates-manifest.json(filters + commands lifted verbatim, round-trip validated: 996 filters, 154 commands, 0 mismatches) behind onev4-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/scriptssuite 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-nodepin (21× node-24, 9× node-22) now usesnode-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 keepsetup-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 "removebcryptjs/crypto-js" was wrong as a mechanical action:crypto-jsis load-bearing for React Native encryption-at-rest (Hermes has nonode:crypto; on-device ciphertext must stay decryptable) andbcryptjs→bcryptadds 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: 3stays: 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
noUncheckedIndexedAccessneed graph-wide typecheck budgets; a rootruff.tomlwould 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_callwith slug+paths inputs) or a generator that emits them from a JSON manifest; target ≤60 workflows total. Move the four Isis gates inci.ymlinto project targets. Fix trigger drift: givea11y-pa11y-nightlyandv4-nightly-feel-teststheir missingschedule:(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 canonicaltools/docs pipeline (one renderer); replace the 1,088scripts/isis/generate-v2-*per-artifact files with one parameterized generator + a manifest; adopttools/generators/*(Nx generators) as the only scaffolding mechanism. - R-13c. Build a BFF substrate (
@oshun/bff-kitor similar: fastify app factory, auth/authz middleware, CORS, idempotency, error envelope — extracted fromapps/oshun/bff's mature middleware) and rename@oshun/gateway(Traefik CLI) to@oshun/traefik-configto 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). Raiseparallel, 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, addnoUncheckedIndexedAccessto 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 fromsystems/*.mdas a starting point. - R-17. Dependency diet: remove
bcryptjs,crypto-js,axios/node-fetch(route through@oshun/http-client); pickuuidornanoidper 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 commitCargo.lockfor all binary/service workspaces; add rootruff.toml+ adoptuvwith committed lockfiles for the 83 Python projects.
P3 execution log (2026-07-16):
- R-19 done —
domains.jsonregistry (58 entries: purpose extracted from the systems/ deep-dives, npm scope, scope tag, paths, project counts, owner, status).commitlint.config.jsreads it at load time;.github/CODEOWNERSis 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.mjsruns 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.mdrewritten 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 missinglibs/openapidoc bundles that never existed in any commit).docs/audits/README.mdindexes 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 MBanomalous-data.tables.json; 648 tests green, exact values verified) and nisabacharacter-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 mayaindex.tsmonoliths (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/eventsfoundation lib,@yemaya/corere-exports (486 tests green), isis repointed (55 tests green, zero@yemayaimports remain). And theapps/oshun/webboundary 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.examplefiles → 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 entireapps/oshun/web/e2esuite (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 + 4tools/docs_centerfiles),platform/(phase-98 checker + v6 privileged-access/DSAR gates), andDOMAINS/(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 mayaindex.tsmonoliths 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 newdocs/audits/home. - R-22. Env config ownership: split
.env.exampleper app with a generated aggregate; pair with@oshun/configschema 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 (26verify-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/jeststragglers → vitest (D-2); the four inline Isis gates → project targets behind one cachedrun-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 intoinfra/with offlineterraform 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 (newstudiodomain, 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-configbyte-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/resiliencecannot 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.ymlauto-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.