Skip to main content

SOLID post–Wave 17 closure

Tier: Internal
Status: Active — canonical SOLID program status after Wave 17 (bfd6214)
Audience: maintainers, module authors, AI agents
Related: solid-audit-charter.md, solid-decoupling-audit.md, solid-audit-inventory.md


1. Verdict

Hand-written Single Responsibility (S) debt from the 2026-06 SOLID audit is resolved for P0/P1 god units (services, routes, pages). Automated inventory is green:

MetricValue (post–Wave 17)
P00
P12 (generated OpenAPI client blobs only)
P20
P30

The mechanical Wave 11–17 program is closed. Do not schedule Wave 18+ proactively.

Guiding sentence: Follow dependency direction and single ownership; extend via registration and contracts; when coupling is intentional, say why in code.


2. What landed

TrackScopeReference
Tier AProjection IDs, AuthService, WaterCalcService, boundaries spikeChild plans A1–A4
Tier BGod services, recipe-edit shells, projection port, thin routes, B5 CIChild plans B1–B5
Waves 15–17Hygiene band + tail parity + Tier A route thinning + test barrels54b4f06, bfd6214
S closure epicComposer thinning, WS6 promotion, water/brew-session tailThis doc + successor commits
WS5 app boundariesLocale vertical + recipe-cluster fences; LINTING + charter §1197f583d
Agent SOLID/D gateAGENTS.md § SOLID and dependency direction (D); toolset 03-layering-and-coupling-discipline.mdcpost-WS5

Regenerate inventory after structural changes:

npm run audit:solid-inventory

3. Tier C — explicit wont-fix (do not split as hygiene)

PatternWhy keep
domain/waterCalc/mashAcidificationTargetMashPh.ts, spargeAcidification.tsCohesive domain math; logical SRP ≠ file size
packages/sdk/module-sdk/src/moduleRegistry.tsBoot composition root
Generated OpenAPI under packages/platform/api-client/src/generated/Codegen output — tooling epic, not runtime S
DI containers / interface per Prisma serviceAudit Tier C — Fastify + vi.mock sufficient

See solid-audit-charter.md §9.


4. When to reopen mechanical waves

Run npm run audit:solid-inventory on major feature merges. Re-open a scheduled hygiene wave only if:

  • New P2 or P3 production findings appear, or
  • A production file reaches ≥400 LoC without a documented @arch-boundary, or
  • A P0 boundary violation appears (boundaries/element-types on modules/**).

Otherwise: split opportunistically when touching an area for a feature — not inventory-driven waves.


5. Remaining S backlog (S closure epic)

Status: complete (S closure epic landed on master).

All targeted composer thinning and native parity work from the epic is done:

  • Recipe edit: web useRecipeEditPage + native useRecipeEditScreen composers thinned; native mashing hook parity.
  • Water + brew-session: mash/sparge handlers, hub recap, brew-session detail hook splits.
  • Equipment + section tail: native equipment mutations, hops rows, save-recipe payload split.

Further splits are opportunistic only (feature-driven) or Tier C / tooling — see §3 and §8.


6. Verification for SOLID PRs

These gates already exist. They are not a new SOLID initiative — agents and contributors run them before every push.

WhenCommandWhat it is
Every push with TS/lint surfacenpm run verify:pre-pushT2-PR — path-aware ci-parity on committed HEAD + auto API vitest when diff matches api.yml paths
WIP iteration only./scripts/ci-parity-check.sh run --jobs …Fast feedback; not push proof
API behavior or tests changedSkill api-integration-tests-pre-pushFull vitest (332/332); complements ci-parity when API paths touched
Manifest / SDK tags / ci-parity pinsnpm run verify:pre-push:releaseT2-release — not the default pre-push

Agent rules

  1. Dependency-direction work — read AGENTS.md § SOLID and dependency direction (D) and charter §2 before adding cross-folder imports in apps or canonical modules.
  2. Agents run T2 before push — never delegate to the operator. See AGENTS.md § Pre-push CI parity.
  3. Use ./scripts/ci-parity-check.sh — not bare npx @umbraculum/ci-parity (Cursor AppImage PATH issue).
  4. Do not schedule Wave 18+ proactively; run inventory on large merges instead.
  5. Do not split Tier C files or generated OpenAPI as “SOLID hygiene.”
  6. Commit first; working tree must be clean for archive replay push proof.

Full tier reference: VERIFICATION-TIERS.md, CI-PARITY.md.


7. Enforcement status

RuleLevelScope
B5 boundaries/element-typeserrorservices/api/src/modules/**
WS6 client-safe importserror (post S-closure epic)apps/{web,native}/** — see solid-client-safe-imports-spike.md
WS5 apps boundarieserror (pilot 2026-06-05; locale vertical expansion 2026-06)apps/{web,native}/** — see solid-boundaries-eslint-apps-spike.md, LINTING.md § App layer boundaries

8. Out of scope (separate epics)

  • OpenAPI generator / client split (P1 inventory — I segregation)
  • Full BreweryScheduleProjection port (Tier B — on-demand with MRP/CRP features)

Closure doc introduced with S closure epic. Amend when program status or enforcement promotion changes.