# Module-by-module code cleanup audit

Active execution checklist, not an architecture standard or permission to delete
every listed candidate. Ownership decisions follow
[`../design/l0-l1-standard.md`](../design/l0-l1-standard.md); test disposition follows
[`../design/test-quality-standard.md`](../design/test-quality-standard.md).
The existing [legacy API consumer inventory](serviceification/legacy-api-consumer-inventory.md)
provides architectural context; current source and consumers decide each deletion.

## Current audit boundary

- Initial inventory baseline: `1b7dac32d` (2026-09-08).
- Route cleanup baseline: `cb0a75d1c` after lifecycle cleanup PR #4838.
- Current module: `backend/distributions`, after the bounded legacy REST cleanup
  in `backend`. Neither module has received a complete audit.
- App-packs comparison: locked source `fbb0db216c3db5c25c2b9eaa40d0056e64b37c43`
  and observed main `2bb9a9700fc8a670f4b745022d7399e9ee8c1e38`.
- Prefer a coherent retired subsystem over many small helpers. File size is a
  prioritization signal, never evidence of redundancy.
- Finish a bounded module pass before moving to the next module. An unresolved
  candidate gets a named blocker and disposition; it does not silently vanish
  from the checklist or force unrelated feature work into the cleanup.

## Checklist for every module

1. Inventory production entrypoints, build tags, generated sources, tests, and
   command/package dependency closures. Check separate Go modules explicitly.
2. Map direct calls, interfaces, stored callbacks, registries, initialization
   effects, cross-module consumers, and pinned external consumers.
3. Inspect large retired subsystems and duplicate responsibilities. For two
   implementations, identify the canonical owner and differences before merging
   or deleting either. Similar names and bodies do not prove equivalent behavior.
4. Classify each candidate as removable, requiring a coordinated cutover, or
   retained. Record shared helpers, historical data/recovery, security guarantees,
   and public compatibility surfaces that must survive.
5. Define deletion and test boundaries; execute appropriate owner tests,
   producer-to-consumer checks, and compilation. A skipped test is not a pass.
6. Record the resulting PR and remaining candidates. Mark a module pass complete
   only after all inspected candidates have dispositions; that is not a claim
   that the module can never contain further cleanup opportunities.

## Core module queue

Source lines are a prioritization snapshot: tracked Go/TS/TSX/JS/JSX, including
comments and blanks, excluding declaration files and sources bearing a generated
code marker. Test files/directories are counted separately; nested modules are
assigned to their own row. Counts are not promised deletion totals.

| Order | Module | Source lines | Test lines | State | Focus of the next pass |
|---|---|---:|---:|---|---|
| 1 | `backend/distributions` | 7,301 | 7,180 | In progress | Retired CRM HTTP/lifecycle composition versus live setup registrations |
| 2 | `backend` | 59,698 | 82,011 | Partially audited | Remaining ServiceManager/runtime assembly overlap, recovery-only composition, orphan helpers |
| 3 | `nexuscrm-automation` | 60,106 | 84,014 | Not started; replay boundary noted | Old execution/worker paths, shared synchronous approval logic, durable recovery |
| 4 | `nexuscrm-persistence` | 53,429 | 26,654 | Not started | Duplicate query/write adapters and metadata persistence paths |
| 5 | `nexuscrm-records` | 36,166 | 61,986 | Not started | Legacy CRUD/query surfaces versus current Runtime consumers |
| 6 | `nexuscrm-metadata` | 36,156 | 36,669 | Not started | Authoring/read-path overlap; preserve actual field creation and shape ownership |
| 7 | `nexuscrm-kernel` | 29,073 | 21,343 | Not started | Compatibility abstractions and duplicated contracts/utilities |
| 8 | `nexuscrm-analytics` | 22,755 | 27,424 | Not started | Old report/query adapters and current execution owners |
| 9 | `nexuscrm-permissions` | 22,727 | 21,046 | Not started | Duplicate admission/permission read paths; preserve security and managed lifecycle |
| 10 | `shared` | 20,073 | 7,479 | Not started | Compatibility types/adapters versus canonical contracts; external consumers |
| 11 | `nexuscrm-auth` | 6,691 | 7,773 | Not started | Session/OAuth implementations and current strong-admission consumers |
| 12 | `frontend` | 6,271 | 3,577 | Not started | Host runtime versus migrated L1 UI, exports and bundler entrypoints |
| 13 | `nexuscrm-audit` | 5,131 | 1,933 | Not started | Worker/store lifecycle and historical repair paths |
| 14 | `nexuscrm-files` | 3,072 | 4,736 | Not started | Attachment/read adapters, detached references, recovery consumers |
| 15 | `nexuscrm-db` | 2,878 | 336 | Not started | Pool/bootstrap wrappers and actual driver consumers |
| 16 | `nexuscrm-events` | 2,802 | 3,583 | Not started | Subscription/dispatch paths and process ownership |
| 17 | `tools/boundarygate` | 1,596 | 407 | Not started | Obsolete policy entries; preserve real forbidden-edge checks |
| 18 | `nexuscrm-outbound` | 1,254 | 1,602 | Not started | Delivery/replay adapters; preserve durable attempts and recovery |
| 19 | `nexuscrm-storage` | 948 | 364 | Not started | Unused storage wrappers and ownership overlap |
| 20 | `nexuscrm-worker` | 923 | 1,925 | Not started | Scheduler/wake abstractions and all independent worker consumers |

Conformance modules, scripts, and CI are supporting consumers of these rows, not
automatically removable production code. Their fixtures and source guards require
a separate disposition when the owning implementation changes.

External release boundaries are checked as consumers during the relevant Core
pass. Their own cleanup passes remain unstarted: `nexuscrm-contract`,
`nexuscrm-controlplane`, `nexuscrm-api-host`, `nexuscrm-connectors`, and the L1
app-service, dialect, and frontend modules in `nexuscrm-app-packs`. Tenant delivery
is a consumer check; tenant data must not be copied into this audit.

## Current module findings: backend/distributions

The module still has a real CRM setup command:
`cmd/setup/distribution_crm.go` calls
`RegisterProductDistributionCapabilities(NewProductDistribution(crm.ProductHooks()))`.
Do not remove the module, `ProductHooks`, source locks, capability registration,
managed lifecycle providers, or setup validators wholesale.

Production references below were resolved with Go type information for `./crm`
using `GOWORK=off` and `-tags crm`, against the module's checked-in dependency
configuration. These are source reachability findings, not endpoint parity tests.

### D1 — retired in-process SCIM host: blocked by successor acceptance

- Files: `crm/scim_identity_surface.go` (1,781 lines),
  `crm/scim_identity_admin.go` (598), `crm/scim_identity_config.go` (237).
- Size: 2,616 production lines plus 1,782 lines in their three test files.
- The group has one external production reference:
  `registerScimIdentitySurface` in `crm/product.go`, stored in
  `RuntimeRouteSurfaces`. The old Core route-mounting consumer was retired.
- **Retained.** The authoritative [SCIM rebuild design §6.1](../design/scim-l1-rebuild.md)
  explicitly gates removal: “deleting it is authorized only when a SCIM AppService
  successor has been built, admitted (§5 E), and accepted as the production owner”.
  Lack of a current route consumer alone does not satisfy this handover gate.
- L1 `appservices/sfcrm/scim.go` contains a Runtime-based implementation, but
  `serveSCIM` has no production caller and is absent from the inspected
  `Service.ServeHTTP` dispatcher. Successor activation/acceptance is unproved.
- Owner/next boundary: CRM identity-sync/serviceification migration must prove
  successor production ownership and the design's acceptance gates. This cleanup
  does not weaken the gate or claim SCIM parity. Core source, configuration, tests,
  shared SCIM grammar, metadata, and historical data remain unchanged.

### D2 — retired in-process lifecycle adapters: landed in PR #4838

- Files: `crm/product_lifecycle.go` (466 lines), `crm/oauth_grant_lifecycle.go`
  (184), `crm/assignment_policy_eligibility_lifecycle.go` (291): 941 production lines.
- The group has one external production reference: `registerProductLifecycleHooks`
  stored in `ProductHooks.RegisterLifecycle`. The remaining Core call is inside
  the composition callback; the terminal monolith invoker was retired.
- Consumer audit closed: Core and the six sibling repository checkouts have no
  terminal production invoker of this callback; observed app-packs main likewise
  has no `RegisterLifecycle`/`ProductLifecycle` consumer. The old adapters have no
  initialization side effects beyond their private mutex/map state.
- Removed the three private implementations, their `ProductHooks` callback binding,
  and three dedicated test files. The public callback contract and Core composer
  remain; setup capabilities continue to use the other live hook registrations.
- Preserved the shared policy, mutation-handler, and transaction test helpers in
  `crm/runtime_l1_lifecycle_test.go` under `crm && runtime_l1_integration`. The live
  Runtime/TiDB concurrent profile-rename test still uses these helpers and was not
  deleted with the retired adapter tests.
- Verification: CRM-tagged distribution owner suite and full backend package
  compilation passed. The three source-lock guards passed with the official
  app-packs checkout supplied. The live TiDB test
  `TestCRMAssignmentPolicyUserProfileReadSerializesConcurrentRename` passed against
  port 4001 with `crm runtime_l1_integration` and the conformance fixture module
  configuration used by CI; none of these environment-dependent tests was skipped
  in its final run. `git diff --check` passed. Net code/test reduction: 1,543 lines.
- Preserve `assignment_policy_eligibility_projection.go` and
  `newCRMAssignmentPolicyManagedLifecycleRegistration`: they are still registered
  in the setup-managed component lifecycle. Also preserve the independent Runtime
  path using `permissions.NewAssignmentPolicyEligibilityLifecycleHook` in
  `backend/internal/runtimeassembly/recordmutation/records_mutation.go`.

### D3 — Gmail and send-record-email binding: retained for accepted old packs

- `crm/send_record_email_runtime.go`: 925 production lines, 1,235 test lines.
- The typed audit found eight external references. The old route registration
  writes `sendRecordEmailRuntimeBinding`; the Flow handler in `flow_actions.go`
  reads it. `ProductHooks` and `FlowActionCallHandlerImplementations` expose the
  handler through setup capability registration. The retired route mounting
  path was the only production binding setter.
- Current metadata is already migrated: both the per-pack lock `d05e54b5` and
  build-source lock `fbb0db21` route `Std_SendRecordEmail` to
  `enqueueOutboundMailV3`; neither contains the old
  `crm:standard-action/send-record-email` metadata reference. The live generic
  owner is `nexuscrm-automation/runtime_outbound_mail.go`; mailbox HTTP/OAuth and
  provider delivery are composed by `backend/internal/integrationservice`.
  The L1 frontend's Gmail URL is supplied by the provider metadata public path,
  so that URL alone is not evidence of a caller of this old implementation.
- **Concrete compatibility blocker:** `6f82feb4` and `fc272da8` still contain
  `flow_action_call_handlers/send_record_email.json` referencing the old handler,
  and their `Std_SendRecordEmail` flows still use `sendRecordEmail`.
  `isAcceptedCRMDistributionSourceRevision` in `crm/product.go` accepts both
  because their contracts declare the CustomPermission exact set. Checking only
  the newest source lock would miss these supported metadata consumers.
- Disposition: keep the old group and its registration/tests. The CRM pack
  migration owner must close the accepted-source window or explicitly migrate
  those descriptors and persisted Flow versions before whole-group retirement.
  Preserve connector OAuth state, accepted delivery recovery, and immutable
  activity materialization. Do not change the compatibility predicate merely to
  make this deletion possible; restoring old route composition is also outside
  this cleanup. This is a bounded compatibility finding, not a claim that the old
  production route currently serves.

### D4 — unmounted CometD, instance proxy, and root identity adapters: removed in this change

- Removed `crm/cometd_handler.go` (261 lines), `crm/sf_instance_proxy.go` (94),
  the three route registration callbacks and private dialect bridge in
  `runtime_route_surfaces.go`, and their registration entries in `ProductHooks`.
- Removed the 416-line dedicated CometD test file. All its helpers are private
  to those deleted tests. Its source-string guards only constrained the retired
  adapter; generic streaming principal-isolation tests remain in their owner.
- Source reachability: Go type resolution of the three production files found
  ten external uses: three registration callbacks and seven live policy helpers.
  Core only composes `RuntimeRouteSurfaces`; its terminal mounting consumer was
  retired previously. Six sibling repositories have no source consumers of the
  callback collection or the removed private registrations.
- Preserved all seven live policy helpers: data-API classification, two CORS
  predicates, three OAuth scope predicates, and root identity auth challenge.
  Retained the root-identity name because CORS still uses it. Generic streaming
  session/event engines and CRM event-channel registrations also remain.
- Net code/test reduction: 848 lines. No active endpoint is switched or replaced;
  this does not claim current L1 CometD/proxy/identity parity. SCIM and Gmail are
  separate retained dispositions.
- Verification passed: `GOWORK=off go test -tags crm -count=1 -timeout=180s
  ./...` in `backend/distributions` with the official app-packs source supplied;
  `go test -count=1 -timeout=120s ./pkg/serverruntime ./internal/features/streaming`
  in `backend`; and all-backend compilation with `go test -run '^$'
  -timeout=60s ./...`. No individual test was skipped. Removed-symbol scan found
  no remaining Go references; `git diff --check` passed. Full backend runtime
  and frontend suites were not rerun for this distribution-only deletion.

### Duplicate-implementation findings

- The old Core OAuth transport overlapped with L1 session/OAuth transport; the
  unmounted Core packages were removed in PR #4836. L1's session dispatcher and
  underlying authorization mechanisms remain.
- Core and L1 contain different SCIM implementations. Their duplicate product
  responsibility is real, but activation and semantic differences prevent treating
  them as interchangeable copies.
- A scan of non-test Core Go functions with at least 35 source lines found no
  exact duplicate formatted function bodies. This narrow result does not prove
  absence of structural or semantic duplication.

## Landed cleanup evidence

These are completed scoped deletions, not completion marks for entire modules.
The linked PRs own the detailed review and verification records.

| PR | Scope | Net lines removed |
|---|---|---:|
| [#4829](https://github.com/pingcap-inc/NexusCRM/pull/4829) | Retired connector execution and worker lifecycles | 23,103 |
| [#4830](https://github.com/pingcap-inc/NexusCRM/pull/4830) | Unused private serverruntime composition helpers | 2,447 |
| [#4833](https://github.com/pingcap-inc/NexusCRM/pull/4833) | Retired private product runtime composition | 1,222 |
| [#4836](https://github.com/pingcap-inc/NexusCRM/pull/4836) | Nine unmounted legacy REST packages and dedicated tests | 14,189 |
| [#4838](https://github.com/pingcap-inc/NexusCRM/pull/4838) | Retired in-process CRM lifecycle adapters and dedicated tests | 1,543 |

## Next execution boundary

D2 landed in PR #4838; D4 is removed in this change. D1 is retained behind successor
acceptance; D3 is retained behind the accepted old-pack metadata contract.
These inspected route/lifecycle groups now have explicit dispositions. Continue
with the remaining setup registrations and exported helpers before declaring the
entire distribution module pass complete, then return to `backend`
assembly/recovery consumers. None of these scoped dispositions marks the whole
repository audited.
