# Design: Dedicated Full AWS Service Graph

GitHub issue: #402

Parent issue: #363

Input inventory:
[`20260610-dedicated-full-staging-inventory.md`](./20260610-dedicated-full-staging-inventory.md)

Status: Proposed for HITL approval.

## Summary

The first `dedicated-full` AWS persona should run the Dedicated control plane
inside cp9 while preserving the real Dedicated path to a dynamically
provisioned AWS dataplane. This is not a Premium variant and not a fake local
dataplane. The service graph below converts the #401 staging inventory into one
role per observed service:

- `source`: built from declared local source and shown in the cp9/Tilt loop.
- `live`: real component or resource deployed/created under the cp9 session.
- `stub`: deterministic local/session replacement for an off-path dependency.
- `skip`: not part of the first Dedicated full AWS slice.

The default runtime shape is:

1. local k3d runs Dedicated global CP source services;
2. local k3d runs Dedicated regional CP source service `regional-server`;
3. cp9 stubs non-Dedicated product dependencies;
4. cp9 keeps app-delivery/template inputs staging-faithful;
5. later train steps prove the real dynamic AWS dataplane through the
   `regional-server` boundary before final acceptance.

## First Vertical Runtime Path

The first vertical path to prove is:

```text
OpenAPI Dedicated create
  -> tidb-mgmt-portal
  -> tidb-mgmt-service
  -> dedicated-global-service
  -> regional-server
  -> generated Dedicated dataplane materialization boundary
  -> real cp9-owned AWS dataplane
  -> Dedicated status/user-operation proof
  -> cp9 destroy with direct AWS zero-survivor evidence
```

The graph deliberately excludes data-product flows such as import, migrate, BR,
and CDC from the first proof. Those should be a second dimension after the core
Dedicated cluster create/status path is stable.

## Global Control Plane

Observed source: `staging-base-us-west-2`, namespace
`tidb-management-service`.

| Service | Role | Runtime | Justification from #401 |
| --- | --- | --- | --- |
| `tidb-mgmt-portal` | `source` | local k3d | Staging exposes the Dedicated OpenAPI entrypoint through `tidb-mgmt-portal`; the service points at the generic portal pods and is required for OpenAPI-driven proof. |
| `tidb-mgmt-service` | `source` | local k3d | Staging `tidb-mgmt-service-sts` is the core management service and routes Dedicated requests toward `dedicated-global-service`; source ownership is in `tidbcloud/tidb-management-service`. |
| `dedicated-global-service` | `source` | local k3d | Staging runs this Dedicated-specific global service from the same release image; it owns Dedicated global business logic and is on the create path. |
| `nextgen-global-service` | `skip` | none | Present in the same namespace but #401 found no Dedicated-specific reason to include it in the first core Dedicated path. Add only if a traced Dedicated workflow reaches nextgen. |

## Shared Global Infrastructure

Observed source: `staging-base-us-west-2`, namespace `infra`.

| Service | Role | Runtime | Justification from #401 |
| --- | --- | --- | --- |
| `dedicated-api-server` | `skip` | none | Staging deployment exists with desired replicas `0`; no active runtime dependency was proven for the first Dedicated create path. |
| global `infra-exporter` | `skip` | none | Staging deployment exists with desired replicas `0`; metrics export is not required for create/status/user-operation proof. |
| global `infra-webhook` | `skip` | none | Staging deployment exists with desired replicas `0`; webhook validation is not proven active for the first slice. |

If a later dataplane proof shows one of these services is required, promote it
through a focused issue with the exact failing object and app-delivery path.

## Regional Control Plane

Observed source: `staging-seed-us-west-2`, namespace
`regional-server-system`.

| Service | Role | Runtime | Justification from #401 |
| --- | --- | --- | --- |
| `regional-server` | `source` | local k3d | This is the Dedicated regional orchestration service. It owns root/addon/infra/dedicated/dp template config and is the required bridge from global CP to regional/dataplane materialization. |
| `o11y-agent-control-server` | `stub` | local/session stub | It is a regional observability companion from an external observability repo. The first Dedicated core proof does not need real o11y agent config generation, but source services may need a reachable contract endpoint. |

`regional-server` must keep staging-faithful config shape: root config,
dedicated templates, dataplane templates, app-delivery registry path, and
service names. cp9 may rewrite endpoints, credentials, regions, account IDs,
and session names, but must not invent a different orchestration path.

## infra-provider / eks-provider

Observed source: `staging-seed-us-west-2`, namespace `infra`.

All listed provider deployments are app-delivery owned but currently have
desired replicas `0` in staging. That is strong evidence to avoid starting them
by default in the first CP graph. The dataplane path should instead be proven
from `regional-server` and the generated Dedicated dataplane boundary; only
promote these controllers when runtime evidence shows the path calls them.

| Service | Role | Runtime | Justification from #401 |
| --- | --- | --- | --- |
| `eks-infra-provider` | `skip` | none | Staging seed deployment is scaled to zero. It may become live if #406 proves cluster-manager controller behavior is required. |
| `dp-eks-infra-provider` | `skip` | none | Staging seed deployment is scaled to zero. Do not assume active dataplane controller behavior before materialization proof. |
| `dp-eks-infra-provider-br` | `skip` | none | Backup/restore data-product controller; not in core Dedicated create/status proof. |
| `dp-eks-infra-provider-cdc` | `skip` | none | CDC data-product controller; not in core Dedicated create/status proof. |
| `dw-eks-infra-provider-dumpling` | `skip` | none | Data-work/export controller; not in core Dedicated create/status proof. |
| `dw-eks-infra-provider-dwworker` | `skip` | none | Data-work/export controller; not in core Dedicated create/status proof. |
| `k8s-version-controller` | `skip` | none | Kubernetes upgrade/version controller; not in first create/status/user-operation path. |

## tcidm / Data Products

Observed source: `staging-seed-us-west-2`, namespace `tcidm`.

| Service | Role | Runtime | Justification from #401 |
| --- | --- | --- | --- |
| `regional-tcidm-service` | `stub` | local/session stub | It exposes `/api/v1/tcidm`, but the first Dedicated core proof excludes import/migrate data products. A stub keeps source services fail-closed if they probe the API. |
| `dm-controller` | `skip` | none | It is an infra-provider `/eks-provider run-dm-controller` subcommand for migrate-from-MySQL; not in the core Dedicated create path. |
| `import-controller` | `skip` | none | It is an infra-provider `/eks-provider run-import-controller` subcommand for import; not in the core Dedicated create path. |

Data products are a second graph dimension. When the Dedicated core persona is
stable, add separate role decisions for migrate, import, backup/restore, and
CDC instead of expanding this first proof.

## Legacy cluster-service Namespace

Observed source: `staging-seed-us-west-2`, namespace `cluster-service`.

These workloads exist in staging and have app-delivery paths, so they cannot be
ignored as unknown. They are still classified away from the first source graph
because #401 did not prove that the Dedicated core path must execute legacy
cluster-service logic before the `regional-server` dataplane boundary.

| Service | Role | Runtime | Justification from #401 |
| --- | --- | --- | --- |
| `cluster-control-server` | `stub` | local/session stub | Regional config references a cluster-control service endpoint, but the first graph should record calls before running legacy control logic. Stub the HTTP contract and promote to `live` only if #403/#406 proves it is required. |
| `cluster-controller` | `skip` | none | Legacy controller for cluster/config/workflow/backup/restore/replay paths. Do not run until the stubbed `cluster-control-server` evidence proves this path is active. |
| legacy `infra-exporter` | `skip` | none | Metrics-only support service, app-delivery-owned as `cluster-exporter`; not required for first user operation. |
| `webhook-server` | `skip` | none | Legacy CR validation service. Promote only if generated manifests fail without its webhook contracts. |

This is the main review tradeoff. Running all legacy `cluster-service` workloads
would be more staging-complete, but it would also widen the persona before the
Dedicated path is traced. A recorder stub on `cluster-control-server` gives the
next issue a hard signal: if no calls arrive, legacy stays skipped; if calls
arrive, promote the minimum needed service with evidence.

## Dynamic Dataplane Boundary

Observed source: #401 regional-server template/config evidence, plus #363
Dedicated full goal.

There are two dataplane modes in the train. They must stay separate because
they have different ownership and cleanup contracts:

- #406 staging DP reference evidence is read-only inspection of a
  human-provided Dedicated staging dataplane in another AWS account. It is
  `live` evidence, but cp9 does not own it and must not imply cleanup
  responsibility.
- #407 cp9 dogfood proof is a `live` dynamic dataplane only if the later
  dogfood run provisions resources under cp9 owner/session tags and cleanup
  selectors.

| Boundary | Role | Runtime | Justification |
| --- | --- | --- | --- |
| #406 staging DP reference | `live` | read-only human-provided staging dataplane | This proves the real Dedicated dataplane shape from staging. cp9 must inspect only metadata needed for evidence and must not claim ownership or cleanup of this dataplane. |
| #407 cp9 dogfood DP materialization | `live` | cp9-owned AWS/Kubernetes resources | The final persona goal is a real dynamically provisioned AWS dataplane, not a fake local dataplane. This mode is valid only when the resources are created under cp9 owner/session tags and cleanup selectors. |
| Dataplane internal services | `live` | staging DP for #406, cp9-owned DP for #407 | The proof should inspect the real dataplane enough to prove status and a final user operation. cp9 should not source-build dataplane internals unless a later issue explicitly scopes a dataplane source loop. |
| Dataplane observability/export sinks | `stub` | local/session stub | Endpoint/status proof should not depend on real shared observability pipelines. Stub off-path telemetry sinks unless a failing service requires a live contract. |

Only #407 cp9-created dynamic dataplane resources must follow cp9 AWS
conventions: `cp9-owner` and `cp9-session` tags, session-name resource prefixes
where cp9 controls names, and `cp9 destroy` direct zero-survivor verification.
The #406 staging reference dataplane is evidence only.

## Cross-Product Dependencies

| Dependency | Role | Runtime | Justification |
| --- | --- | --- | --- |
| Account/Auth identity | `stub` | local/session stub | Needed as identity/project facts for OpenAPI and internal calls; Account persona is separate. |
| Billing | `stub` | local/session stub | Billing is off-path for Dedicated create/status/user operation. |
| Dataflow global services | `skip` | none | #401 did not observe a Dedicated global CP dataflow service in the captured runtime. Data products are out of the first core path. |
| Notification/email/eventbus | `stub` | local/session stub | Off-path integrations should be deterministic and visible if a source service emits to them. |
| Shared staging databases, queues, kubeconfigs, and cloud resources | `skip` | none | Staging is evidence only. Runtime success must use cp9-owned generated data or stubs, never shared staging state. |

## Generated Inputs

cp9 should generate or rewrite these values for the approved graph:

| Input | Source |
| --- | --- |
| local k3d kubeconfig and service DNS | cp9 session |
| service config endpoints | rendered from selected `source`/`stub`/`live` graph |
| local metadb/Dedicated seed rows | staging-derived rows where available, locally rewritten and reviewed in later seed issue |
| AWS owner/session tags | cp9 runtime identity |
| dynamic dataplane names and cleanup selectors | cp9 session name and AWS substrate outputs |
| credentials, certs, tokens, and kubeconfigs | cp9-generated or local-only; never copied from staging |

## Remaining Unknowns

These are explicit follow-up questions for later issues, not hidden assumptions:

- whether `regional-server` can complete the first create/status path with only
  a recorder stub for `cluster-control-server`;
- which exact dynamic dataplane objects prove the boundary in #406;
- which Dedicated seed rows are real staging facts versus local compatibility
  rows in #404;
- whether any global `nextgen-global-service` call appears during the traced
  Dedicated path;
- whether data-product dimensions should later add live `tcidm`,
  backup/restore, CDC, import, or migrate controllers.

## Approval Section

Human reviewer, please choose one:

- Approve this graph as the #402 decision and proceed to #403.
- Change these roles before implementation:
  - `tidb-mgmt-portal`:
  - `tidb-mgmt-service`:
  - `dedicated-global-service`:
  - `regional-server`:
  - `cluster-control-server`:
  - dynamic dataplane boundary:
  - tcidm/data products:
  - infra-provider controllers:
  - other:

Implementation must not proceed to #403/#404 until this section is approved in
the Slock thread or PR review.
