# Legacy API and in-process consumer inventory

> **Status: non-normative migration inventory.** This document records the
> current/legacy dependency shape that serviceification must retire. It is not
> the target wire contract and must not be used to generate remote APIs.
>
> The target authority is
> [`docs/design/nexuscrm-serviceification-target-architecture.md`](../../design/nexuscrm-serviceification-target-architecture.md).
> If this inventory conflicts with that design, the target architecture wins.

## Purpose

The current Salesforce dialect and backend were composed in-process. Go
interfaces, type assertions, context values, callbacks, the EventBus, caches,
and direct repository access therefore cross boundaries that will become
network or durable-work boundaries. This inventory exists to prevent a
migration from silently dropping one of those consumers.

The inventory does **not** approve:

- mirroring the current Go dependency graph as a 33-plane RPC API;
- JSON/HTTP as the internal synchronous transport;
- L1 access to platform databases;
- Runtime reads from Catalog implementation tables;
- fire-and-forget cross-service delivery;
- a network call inside an active mutation transaction.

## Current capability families

The legacy `contract.Deps` surface is grouped below by consumer purpose. Method
counts and individual call sites must be regenerated from the current tree
before each migration slice; they are observations, not protocol commitments.

| Family | Legacy capability surfaces | Target disposition |
|---|---|---|
| Records | Records, RecycleBin, AuditLog, TreeNodeWriter, RecordAccessReader, RecordDefaultPreviewer | Re-design as coarse neutral Runtime query/read-graph/mutation use cases |
| Query | Query and aggregate-fetch context controls | Neutral QuerySpec/IR; no SOQL/SOSL grammar in L0 |
| Metadata reads | Metadata, LayoutMetadataReader, ObjectMetadataCatalogReader | Full immutable CatalogSnapshot through one RuntimeMetadataView |
| Policy | Policy, CapabilityPolicy | Runtime-owned authoritative enforcement; batch/plan-aware contract |
| Identity | UserSessions and legacy auth/session adapters | Single Runtime Identity authority and delegated execution context |
| Automation | FlowExecutor, FlowCatalog, FlowInterviews | Mutation hooks stay in Runtime transaction; external execution is explicit and bounded |
| Approvals/actions | Approvals, StandardActionService | Generic mechanisms remain L0; App recipes remain metadata; no opaque handles on wire |
| Bulk/files | BulkJobs, BulkIngest, Files | Job/streaming contracts and shared durable storage references |
| Search/reporting | SearchScope, Reports and dialect report callbacks | Neutral search/query/report IR; App grammar/projection remains L1 |
| Notifications/resources | Notifications, Activity, ResourceAccess, FolderAccess | Classify by actual owner/use case before admitting a wire method |
| Connector integration | ConnectorSyncStatus, ConnectorWebhookSecrets | Integration service owns receipts/delivery; secrets remain references, not snapshot values |
| Metadata writes | MetadataAuthoring, LayoutMetadataAuthoring, MetadataDeploy, MetadataMaintenance, FlowAuthoring, ApplicationNavigation | Catalog job API and publication state machine |
| User-owned runtime rows | ListViewAuthoring and similar private state | Runtime data owner, not Catalog, unless the ownership standard says otherwise |
| Transaction coordination | RecordMutationCoordinator and transaction closures | Never cross the wire; replace with a complete Runtime mutation use case |

## Runtime type-assert seams

The legacy in-process adapter discovers optional capabilities with Go type
assertions. A generated remote client cannot preserve that behavior implicitly.
Known families include:

- record tree writes;
- record access reads;
- record default previews;
- layout reads;
- object catalog reads;
- layout authoring;
- capability policy;
- attachment metadata/authorization.

For each seam, migration must choose exactly one outcome:

1. absorb it into an existing coarse use case;
2. admit a new neutral capability with both CRM and non-CRM consumers;
3. keep it App-local;
4. delete it as redundant.

Turning each type assertion into its own RPC is explicitly rejected.

## Wire-hostile in-process shapes

### Transaction closures

`RunInPessimisticTransaction`-style closures and mutation coordinators carry an
active transaction and cannot become RPC. The complete transaction remains in
L0 Runtime.

### Opaque bindings

Standard-action resolution can carry engine-private/opaque values. Wire
contracts must send a stable action identity and inputs; Runtime resolves its
own implementation.

### Caller callbacks

File authorization, metadata diagnostics, lifecycle reporters, and report
dialect callbacks currently rely on reverse calls. Migration must invert the
operation or return explicit data. Request-time reverse RPC is not the default.

### Context side channels

Security level, connector execution context, sync origin, aggregate limits,
diagnostics, deadlines, request ID, OrgContext, and AppInstallation identity
must become explicit authenticated contract fields. A missing field fails
closed when it affects authorization or transaction semantics.

### Streams and local files

Bulk CSV, file content, and deploy archives are streams, not JSON fields. Local
filesystem handoff cannot survive separate deployments; use streaming APIs or
durable storage references owned by the appropriate service.

## Process-local state inventory

Before a route or work family moves out of the legacy process, derive the live
publisher/consumer map for:

- EventBus publishers and subscribers;
- metadata and permission caches;
- request-scoped access/read memoization;
- WebSocket/CometD session state;
- scheduler and worker ownership;
- package globals, `sync.Once`, registries, and singleflight;
- after-commit hooks;
- cache invalidation callbacks;
- connector worker reconciliation;
- shutdown/drain goroutines.

Each item must become one of:

- local state owned by the destination service;
- an immutable snapshot;
- an authoritative identity/security read;
- a durable outbox/inbox message;
- a versioned/fenced ownership record;
- deleted state.

No process-local fact may be preserved through an undocumented best-effort RPC.

## Legacy durable tables and handoffs

The current system already uses database-backed coordination for several work
families, including outbox events, rollup deltas, scheduled reservations,
approval replay, connector receipts/events, audit delivery, and bulk jobs.
Their table schemas alone are not the contract.

For every family, re-derive and document:

- producer transaction;
- claim predicate and ownership epoch;
- lease/renew/recovery;
- dedupe key and retention;
- ordering partition;
- payload and implementation version;
- success/retry/dead/unknown outcome states;
- repair and cleanup owner.

Runtime API-to-worker queues remain internal to the single Runtime logical
service. Integration receipts remain owned by Integration and are delivered to
Runtime through an idempotent command contract.

## Catalog/control-plane inventory

Legacy setup and authoring operations cover:

- pack validate/install/reapply/remove;
- bootstrap, repair, ensure-indexes, and rebuild-derived;
- object/field/layout/flow/application authoring;
- formula-view and autonumber maintenance;
- namespace and KeyPrefix allocation;
- deploy requests and tenant overlay application;
- shallow/deep verification and drift repair.

Serviceification must route all Catalog-owned mutations through the target
writer lease, operation journal, DDL reconciliation, immutable snapshot, and
activation protocol. Existing CLI, SQL, or backend paths are migration inputs,
not parallel authorities.

## Migration rule

For every migrated route or work family:

1. derive the current consumers from the live tree;
2. add golden and performance baselines;
3. implement the approved target contract;
4. switch the versioned route/ownership epoch to one new owner;
5. keep the legacy implementation dormant during the rollback window;
6. delete the legacy path after compatibility and observation gates pass;
7. update this inventory or remove the completed section.

The inventory is complete only when no production behavior relies on an
unlisted in-process seam.
