Platform Surfaces and Services
Status: Draft for review | Date: 2026-07-23 | Refines: Control Plane Design (four-plane model), Agentic Coding Platform, Studio Local Mode, Edge OTA
1. The platform thesis
Auraison is being built as a general platform for AI in computational science and engineering. The applications already in flight (AR4 manipulation, TurtleBot navigation, sidewalk extraction, counter-UAS, the USV) are instances of a repeating pattern: capture or ingest data about a physical environment, build models over it, run simulation and training on GPU compute, and deliver the result back to a running system. The platform's job is to make each of those capabilities a service that any application can call, rather than a script that one application owns.
The pattern has a consequence the earlier draft of this document understated: the platform's agents produce both the applications and the models those applications run against. An agent that writes ROS code for the AR4 consumes a VLA policy; another agentic process produced that policy by writing and dispatching the training code. Both are the same loop, agent generates code, code runs in an isolated sandbox, artifacts come out, and they differ only in substrate. Section 3 makes that symmetry structural.
The four-plane model (user, control, data, management) said where things run and what their failure isolation is. It did not say how the platform presents itself to a user, how the code inside the control plane divides between running the platform and delivering its capabilities, or what keeps agent-generated code from becoming a security liability. This document fixes that structure. It grounds the design on one external reference, Cloudflare's enterprise AI vibe-coding architecture (section 2), and on a direction set by the founder on 2026-07-23 that is treated here as decided; what remains open is the mapping of current code onto it and six implementation decisions, resolved in section 7.
The structure has four parts. End users reach the platform through two surfaces, Studio (the browser console) and a CLI. Internal staff run the platform through a third surface, an administration UI that end users never see. Behind the surfaces the backend divides into two service classes: platform services (the Platform API), which provision and operate the resources the platform itself needs, and application services (the Application API), which deliver the computational-science capabilities, organized into namespaces. Environment capture with Gaussian splatting is one such namespace; the lakehouse, experiment tracking, model serving, and model training are others.
2. Enterprise isolation: the Cloudflare reference architecture
The platform adopts Cloudflare's enterprise AI vibe coding platform reference architecture as its isolation model. The reference's premise is that AI-generated code is inherently untrusted, and that protection is therefore enforced at the platform level, not the code level. It organizes an agentic coding platform into three operational planes (development, deployment pipeline, production), and inside the development plane it draws the separation this document treats as first principle. Three tiers:
- The agent loop runs apart from execution. Orchestration is server-side (in our case the Studio Orchestrator Durable Object, or a CLI session), and every LLM call reaches Anthropic through AI Gateway, which provides prompt logging, cost attribution, and DLP inspection.
- Agent-generated code executes only inside a sandboxed runtime, Cloudflare Containers for full environments or Dynamic Workers for lightweight evaluation. The sandbox holds no credentials. Secrets live in Secrets Store and are injected by the platform at the egress boundary; the reference states it plainly: "the sandboxed environment never has direct access to credentials."
- Everything the sandboxed code needs to reach (external services, databases, models) it reaches only through governed egress: an outbound handler that intercepts traffic, enforces a destination allowlist, and injects secrets, with Workers VPC and Cloudflare Tunnel providing the private path to systems that are not on the public Internet.
Applied to Auraison, the tiers land concretely. The agent generates ROS code; that code is bundled into a Cloudflare Container and runs there. Cloudflare Containers are CPU-only, so any vLLM model, VLA policy, or heavy GPU library the ROS code depends on cannot run in the sandbox. It runs outside, on the GPU tailnet, as Ray Serve plus vLLM endpoints (AURA-577, AURA-704), and the sandboxed code reaches it only as an inference API through the Tunnel and the outbound handler. That governed hop is the enterprise win: agent-generated code can call inference but can never hold the key, and can never reach an endpoint that is not on the allowlist. This is the design content of AURA-782, the GPU workspace provider via Cloudflare Tunnel into Ray and Isaac Sim.
The tier boundaries are also the audit boundaries. AI Gateway records every prompt with tenant and session attribution; the outbound handler records every egress attempt, allowed or refused. A sandbox compromise is contained by construction, because the sandbox holds nothing worth stealing and can call nothing that was not explicitly granted. This is the posture the security epic (AURA-730) reviews against, and every later decision in this document either preserves it or is wrong.
3. Two agentic loops: application development and model development
Auraison must support model development itself, not only applications written against fixed models. Both are agentic loops of the same shape, an agent generates code, the code runs in an isolated sandbox, and artifacts come out, and both keep the three-tier separation of section 2. They differ in substrate:
- Application development: the agent writes ROS or application code, the code runs in a Cloudflare CPU sandbox, it calls inference APIs over the Tunnel, and the result is a published application.
- Model development: another agentic process writes training code, the code runs in a GPU-backed sandboxed training container on the KubeRay/Ray substrate (not Cloudflare, which has no GPUs), and the result is artifacts: checkpoints and models.
The loops connect through a serving and registry tier. Checkpoints from the model-development loop are registered, then served by Ray Serve and vLLM as the inference APIs the application loop consumes over the Tunnel. The same artifacts flow outward a second way, as signed model bundles delivered to Jetson fleets through the OTA pipeline (the edge OTA design specifies that channel, including the compatibility contract and A/B promotion on device). The serving tier is the join: the platform's agents produce both the models and the applications that use them, and everything between the two loops passes through registered, versioned artifacts rather than through shared state.
One nuance is worth stating precisely, because it decides where tokens are spent. The training code is agent-generated, but the training execution is a deterministic pipeline dispatched by the agent, not driven token by token. The agent gets three verbs, run, status, and result; a workflow engine (AURA-805, Prefect 3 per the deterministic-orchestration research in .claude/plans/2026-07-23-deterministic-workflow-orchestration-research.md) executes the pipeline steps, submits RayJob CRs to KubeRay, retries failures, and produces checkpoints. The agent is re-invoked at terminal states, not per step, so no tokens burn on deterministic training. This dispatch-and-observe contract is the same split the application loop already has between the Orchestrator DO and its container: the agent owns what is unpredictable, the infrastructure owns what is predetermined.
The mechanism that generalizes execution across substrates already exists as a seam: Studio's workspace provider interface. The Orchestrator DO issues workspace.* calls against the interface without knowing which substrate answers; CfContainerProvider answers with a Cloudflare Container today, LocalDockerProvider answers in local mode, and a GPU/Ray provider (AURA-782) answers with a tailnet session over the Tunnel. The model-development loop is a new caller of the same seam, not a new execution model. What the provider abstraction does not hide, and should not, is the trust and egress story of each substrate, which is why both loops sit inside the section 2 tiers rather than beside them.
4. The surface and service model
A surface is something a person opens; a service is something a surface (or another service) calls. The rule that gives the model its shape: surfaces own interaction state, services own capabilities. A surface may be thick (Studio carries a session orchestrator) but it does not own a domain capability outright; a capability lives in a service so that every surface, and every other service, can reach it.
The two service classes differ in who calls them and what breaks when they fail. Application services are tenant-facing: a request names a tenant's data or session, and an outage degrades a capability for users. Platform services are operator-facing: a request changes the platform's own resources (a cluster scaled, a bucket provisioned, an egress allowlist entry added), and an outage degrades the operators' ability to run the platform while running workloads continue. This is the same failure-isolation instinct as the plane separation, applied one level down, inside the control plane.
The section 2 tiers map onto the classes cleanly. Governed egress, the Tunnel, secret injection, and provisioning are platform services: no tenant request names them, every sandbox depends on them. The sandboxes themselves are runtimes owned by application namespaces: the CPU app sandbox is the coding namespace's runtime, the GPU training sandbox is the training namespace's, and the inference endpoints are the serving namespace's product. A namespace never implements its own egress; it declares what its sandboxes may reach, and the platform enforces it.
Namespaces organize the Application API. A namespace is a coherent capability with its own API prefix, its own code package, and a home under exactly one capability epic in the backlog. It is a logical unit, not a deployment unit: two namespaces may share a process today and separate later without their consumers noticing, because the prefix is the contract.
5. Current code, mapped
The repository already contains most of the pieces; they are just not named or bounded this way. The mapping below is the founder's first pass, verified against the tree and extended.
| Current | Target role | Notes |
|---|---|---|
control-plane/backend/api/jobs.py, clusters.py | Platform API | Compute dispatch and cluster ops; job store still in-memory |
control-plane/backend/api/lakehouse.py, experiments.py | Application API namespaces | First two namespaces, extracted in place |
control-plane/backend/agents/ | Agent layer, shared by both classes | cluster_agent serves platform; lakehouse_agent, wandb_agent, notebook_agent serve application namespaces |
control-plane/backend/mac/ | Application namespace candidate | MAC simulation; a domain capability, not platform machinery |
control-plane/frontend/ | Seed of the internal admin UI | Pages /jobs, /clusters, /experiments are already operator views |
control-plane/studio/ (Worker + ui/) | Studio, the browser surface | Worker owns session orchestration (Orchestrator DO, phase machine, publish, storage, workspace providers) |
| Studio connector CLI (designed, not built) | Seed of the end-user CLI | BYO substrate connector from the agentic coding platform doc §5 |
| cloudflared Tunnel + Access service tokens | Platform service: governed egress | Already carries Studio-to-control-plane traffic; outbound handler and allowlist land with AURA-782 |
| Ray Serve + vLLM endpoints (AURA-577, AURA-704, in flight) | serving namespace | Inference APIs on the GPU tailnet, reached only over the Tunnel |
| Workflow engine (AURA-805, not built) | training namespace's execution spine | Prefect 3 recommended; dispatch-and-observe contract in section 3 |
infra/terraform/ (stacks: cloudflare, minio, postgres, studio) | Substrate the Platform API's provisioning wraps | Human-run today |
user-plane/ros2-workspace/ | Workload images, invoked by namespaces | Execution substrate, not a service |
Two observations from the verification. The FastAPI routers already carry versioned prefixes (/api/v1/jobs and siblings), so the namespace split is a reorganization of prefixes and packages, not an API redesign. And the Studio Worker's source (index.ts, orchestrator.ts, phase-machine.ts, llm.ts, publish.ts, storage.ts, db.ts, providers/) is session machinery end to end; nothing in it duplicates a FastAPI capability, which makes decision 2 below less painful than it first appears.
6. Terminology note
Earlier docs use "control plane" to mean the on-prem FastAPI service specifically. In this document the control plane is the plane; the FastAPI service and the Studio Worker are both deployments inside it (the agentic coding platform doc already extended the control plane to the edge). "Platform API" and "Application API" name service classes within the control plane, not new planes. Likewise "sandbox" names an isolation property, not a place: the CPU sandbox is a Cloudflare Container at the edge, the GPU training sandbox is a KubeRay-managed container on the tailnet, and both satisfy the same tier-2 obligations from section 2.
7. Decisions
7.1 Backend shape: one service, two router packages
The question is whether the platform/application split means one FastAPI service with two router packages or two separate services. Two services would give independent deploy cadence, separate auth policies (operator tokens vs tenant tokens), and a hard blast-radius boundary. They would also double the operational surface (two processes, two health checks, two deploy pipelines) at a stage where the job store is an in-memory dict and one person operates the platform.
Decision (settled 2026-07-23): one FastAPI service, restructured into api/platform/ (jobs, clusters, provisioning) and api/apps/<namespace>/ packages, with URL prefixes /api/v1/platform/... and /api/v1/apps/<namespace>/.... Enforce the boundary in code review and imports (an application namespace may import platform client code, never the reverse), so that a later physical split is a deployment change, not a refactor. The trade-off accepted is that the API process has no independent per-namespace deploy or scale yet; the logical boundary buys the separation of concerns now and makes the physical split cheap when it is earned. The Gaussian-splatting case does not argue against this: the capture namespace is a thin API in front of Ray GPU jobs, so its heavy compute already scales independently through KubeRay regardless of how many API processes there are. Revisit when the job store lands in Postgres and tenant-facing traffic needs auth or scale the operator path does not.
Two additions follow from sections 2 and 3. The platform package grows a pipelines broker over the workflow engine, exposing the dispatch-and-observe verbs (run, status, result) with idempotency keys, so agents never talk to the engine's API directly. And governed-egress configuration (allowlist entries, secret bindings, Tunnel routes) is platform-router territory from the start; an application namespace requests an egress grant, it never writes one.
The claude -p agent wrappers in agents/ stay a single shared package. They are an agent-ops substrate, not a service class: cluster_agent executes platform work, lakehouse_agent and wandb_agent execute application work, and splitting the package by caller would duplicate base.py and the tool-scoping pattern for no isolation gain. What must not happen is an application namespace invoking cluster_agent directly; it requests compute through the platform routers, which own that wrapper.
7.2 Studio's Worker: a thick surface, and one namespace in disguise
Studio is an end-user surface, and the model says surfaces call APIs rather than own backend logic. The Worker plainly owns backend logic: the Orchestrator Durable Object, the phase machine, publish, storage. Making Studio a thin client over the FastAPI service would mean re-hosting per-session DO state on-prem, which the agentic coding platform doc §4 already evaluated and rejected (it concentrates multi-tenant isolation on a single on-prem process and walks back the central-runtime direction).
The resolution is to read the Worker as two things that happen to share a deployment. The static UI plus the HTTP and WebSocket routes are the surface. The Orchestrator DO and its session machinery are an application service, the coding namespace, whose capability is agentic ROS2 development sessions, implemented in the Worker runtime because that is where per-session durable state and container brokerage are cheap. Namespaces are logical units (section 4), so a namespace implemented in TypeScript on Cloudflare is as legitimate as one implemented in Python on-prem. In tier terms, the DO is the coding namespace's tier-1 agent loop and the Cloudflare Container it brokers is its tier-2 sandbox; the container holds no credentials, and everything it reaches off-sandbox crosses the tier-3 outbound handler. The obligations that follow: the coding namespace reaches every other capability through the Application and Platform APIs (its gpu.request_session already calls the FastAPI service over the Tunnel, which is the pattern), and no other surface is required to go through the Worker to reach a non-coding capability.
Decision (settled 2026-07-23): keep the Worker self-contained, name its session machinery the coding namespace, and hold the line that new domain capabilities land in the Application API rather than accreting into the Worker because it is close to the user. The line is neither "the Worker owns nothing" nor "the Worker owns everything" — it owns the coding namespace and the surface, and reaches every other capability as an API. The trade-off accepted is that the coding namespace runs in a different runtime (TypeScript on Cloudflare) from the Python namespaces, which is the intended two-runtime split of 7.3, governed by the versioned API contract. Revisit only if the Worker starts accreting non-coding domain logic; that accretion is the signal to push the capability into the Application API instead of the Worker.
7.3 Two runtimes: the three-tier separation, bridged by governed egress
FastAPI on the tailnet and a Worker on Cloudflare are two languages, two deploy targets, and two operational models. The earlier draft defended this as intended because the placement reasons are physical. That defense stands, but it understates the point: the two-runtime shape is the section 2 isolation model made concrete, and it is foundational rather than a convergence target. The edge runtime hosts the agent loop and the untrusted CPU sandbox, where multi-tenant isolation, Durable Object state, Access, and container brokerage are native. The tailnet runtime hosts everything a sandbox must never touch directly: GPU inference, training compute, kubectl, claude -p subprocesses, and operator credentials. The Tunnel plus outbound handler is not a compromise between them; it is the deliberate, auditable bridge, and the only one. Both agentic loops repeat the split, the application loop between edge sandbox and tailnet inference, the model-development loop between agent dispatch and GPU pipeline execution. Collapsing the runtimes would collapse the trust boundary with them.
What must converge is the contract, not the runtime. The boundary rules: all traffic between the two crosses the Cloudflare Tunnel with service tokens; the Worker is a client of the Platform and Application APIs and nothing on-prem calls into the Worker except explicit callbacks (the copyback webhook pattern); every cross-runtime call targets a versioned /api/v1 route; and the FastAPI service publishes an OpenAPI schema that the Worker's client code is generated or checked against. The studio local mode doc adds a second reason to keep the Worker's core portable rather than merging it: workerd runs anywhere, and local mode depends on that.
7.4 Admin UI: repurpose control-plane/frontend
The existing Next.js dashboard already renders the operator's view of the platform: jobs, clusters, experiments. That is the admin UI's starting inventory, not a coincidence, because the dashboard was built before any external surface existed and so was built for the operator. Standing up a new app would buy a clean slate at the cost of rebuilding three working pages, and the slate is not dirty.
Recommendation: repurpose control-plane/frontend as the internal admin UI, deployed behind Cloudflare Access using the same access pattern the Terraform cloudflare stack already manages for other internal surfaces. Its scope is everything operator-shaped: fleet and cluster operations, provisioning runs and their plan approvals (section 7.6), cross-tenant job inspection, agent-ops observability (which claude -p sessions ran, with what tool scopes), egress-allowlist review (which endpoints each namespace's sandboxes may reach, and refused-egress audit from the outbound handler), and, as the management plane lands, tenancy and metering views. Studio keeps everything tenant-shaped: a tenant's projects, sessions, workspaces, artifacts, and their own usage. The dividing question for any new page is whose resources it shows; a page that shows another tenant's resources is admin by definition.
The rename is worth doing in the tree (control-plane/admin/ or an explicit statement in the frontend README) so the next contributor does not read the dashboard as the product.
7.5 Application namespaces: the model, and where capture lives
A namespace is defined by four things: an API prefix /api/v1/apps/<name>/, a code package control-plane/backend/api/apps/<name>/ (or, for the coding namespace, the Worker), one owning capability epic, and a statement of what substrate its heavy compute runs on. The last matters because namespaces do not execute science in the API process; they orchestrate jobs that execute in the user plane and write to the data plane. A namespace cuts across planes; it is not a plane.
The initial namespace inventory and epic mapping:
| Namespace | Capability epic | Today | Compute substrate |
|---|---|---|---|
lakehouse | Data & Lakehouse (AURA-176) | api/lakehouse.py + lakehouse_agent | data-plane containers |
experiments | Robot Learning / Policy (AURA-758) | api/experiments.py + wandb_agent | W&B, Ray training jobs |
coding | Agent Orchestration / Control (AURA-544) | Studio Worker sessions | three workspace substrates (CPU tier is the Cloudflare sandbox) |
serving | Robot Learning / Policy (AURA-758) | Ray Serve + vLLM in flight (AURA-577, AURA-704) | GPU tailnet, exposed only over the Tunnel |
training | Robot Learning / Policy (AURA-758) | designed; engine is AURA-805 | GPU training sandboxes as RayJobs on KubeRay, via the pipelines broker |
capture | Perception (AURA-709) | does not exist | Ray GPU jobs (torch.dev.gpu) |
sim | Simulation & Digital Twins (AURA-210) | pieces in user-plane runbooks | Isaac Sim / Gazebo sessions |
mac | Agent Orchestration / Control (AURA-544) | backend/mac/ | in-process today |
The serving and training namespaces are the section 3 loops folded into the model. serving owns the inference endpoints the application loop consumes and the registry face the OTA pipeline pulls signed bundles from; its consumers never see a GPU node, only an allowlisted API behind the Tunnel. training owns model-development sessions: an agent's training code becomes a pipeline dispatched through the platform pipelines broker, executes in GPU sandboxes, and registers checkpoints with serving. Checkpoints and datasets themselves are data-plane artifacts under the lakehouse's remit (AURA-176); the namespaces orchestrate their production and their exposure, they do not own the storage.
Environment capture with Gaussian splatting, the founder's example, lands as capture: routes in control-plane/backend/api/apps/capture/, a capture agent or direct job submission through the platform jobs router, training and rendering as Ray GPU jobs using images under user-plane/, and reconstructions written to the lakehouse and R2 as data-plane artifacts. Its API prefix is /api/v1/apps/capture. Whether capture's outputs feed sim (a splat as a digital-twin environment) is a capability question for the Perception and Simulation epics, not a structural one; the namespace boundary already gives them a way to call each other.
The project facet (ar4-physical-ai, turtlebot-maze, usv) stays a label, exactly as the functional-epic taxonomy prescribes for Jira. A project is a consumer of namespaces, never a namespace; the day a project needs its own routes is the day a capability is hiding in it and should be extracted.
user-plane/ keeps its current meaning: workload images and runtime code that execute on the substrate. Namespaces reference user-plane images; they do not live there.
7.6 Platform services and Terraform
Provisioning has two layers with different cadences and different risk. Substrate provisioning (R2 buckets, DNS, Access applications, Postgres, MinIO/RustFS) changes rarely, is declarative, and already lives in infra/terraform with human-run plan and apply. Runtime elasticity (scaling a RayCluster, allocating a GPU session, restarting a worker group) changes hourly and is already automated through cluster_agent. The Platform API should wrap both, differently.
For the runtime layer, the existing pattern stands: platform routers invoke cluster_agent, which executes kubectl and helm under scoped tools. For the substrate layer, the recommendation is a provisioning service in the Platform API that runs Terraform through an agent with a hard human gate: the agent may run terraform plan autonomously, the plan output is surfaced in the admin UI, and terraform apply executes only after an operator approves that specific plan. Secrets stay where they are (1Password injection into TF_VAR_*), meaning the provisioning agent runs where the operator's credentials can be injected, on the tailnet, not at the edge. Fully autonomous apply is explicitly not proposed; a wrong kubectl scale self-heals, a wrong terraform apply deletes a bucket.
Governed egress joins provisioning as the third platform service, and it inherits the same review posture. The Tunnel, the outbound handler, the destination allowlist, and secret injection into egress are operated by the platform and consumed by every namespace; an allowlist change is a small, frequent, security-relevant act, so it gets the runtime layer's automation (an API call, recorded and attributed) with the substrate layer's visibility (surfaced in the admin UI's egress review). Nothing tenant-facing can widen its own egress.
The management plane relationship: billing, tenancy, and quotas are consumers of platform services, not members of it. The Platform API provisions and meters; the management plane (v2, with its first slice already pulled forward into Studio's D1 tenancy tables) prices and enforces. Keeping that direction means the management plane can arrive without the Platform API changing shape.
8. Reconciliation with the four-plane model and the capability epics
The four-plane separation in the control plane design is untouched by this document; the surface/service model is orthogonal to it and finer-grained. Planes answer where code runs and what happens when it fails; surfaces and service classes answer who calls what; the section 2 tiers answer what is trusted. Every element of section 4 has a plane assignment consistent with the existing docs: both APIs, the agent layer, and all three surfaces are control plane (with Studio's Worker being the control plane's edge extension, per the agentic coding platform doc §5); namespace compute, including both sandboxes and the serving endpoints, executes in the user plane; namespace outputs, checkpoints included, land in the data plane; Access gating, metering, and tenancy are management plane. The plane invariant (user-plane failures must not cascade to the control plane, control-plane outages must not halt running agents) gains a sibling one level down: an application-namespace outage must not impair platform services, which is what the import rule in 7.1 and the eventual physical split protect.
The capability epics map onto the structure without strain. Model development is Robot Learning / Policy (AURA-758), which now owns the training, serving, and experiments namespaces. Checkpoints, datasets, and every other artifact the loops exchange are Data & Lakehouse (AURA-176). The GPU substrate, the workflow engine (AURA-805), and the Tunnel plumbing are Platform Infrastructure (AURA-670). The agent loops themselves, Studio sessions and the claude -p wrappers, are Agent Orchestration / Control (AURA-544). The isolation model of section 2 is not an epic's deliverable but a posture that Security (AURA-730) audits: sandbox credential-freeness, allowlist governance, and the AI Gateway audit trail are its standing review items.
One bookkeeping correction surfaced while writing this: the root CLAUDE.md cites the four-plane doc at docs/architecture/2026-02-23-four-plane-architecture.md, but the canonical statement now lives in docs/control-plane/design.mdx (§"Four-Plane Architecture"), and that doc's own trace line cites architecture/four-plane.md, which does not exist either. Both references should be updated to point at the design doc, or the four-plane section extracted back into docs/architecture/ if a system-level home is preferred.
9. Convergence sequencing
The order below is chosen so that each step is independently shippable and none blocks product work.
- Backend reorganization: move routers into
api/platform/andapi/apps/<namespace>/, add the new prefixes, keep the old prefixes as deprecated aliases for one release. Mechanical; no behavior change. - Admin UI declaration: rename or document
control-plane/frontendas the internal admin console and put it behind Cloudflare Access via the existing Terraform stack. The pages already exist; the change is identity and gating. - CLI seed: build the Studio connector CLI (already designed for the BYO substrate) as
aura connect ...inside a singleaurabinary, so the end-user CLI exists from day one with one real command and grows namespace subcommands (aura lakehouse query,aura capture submit) against the Application API rather than appearing later as a second tool. - Serving namespace: wrap the Ray Serve and vLLM endpoints already in flight (AURA-577, AURA-704) as
/api/v1/apps/serving, reachable from sandboxes only through the Tunnel and outbound handler; this is also the acceptance test for the AURA-782 egress path. - Capture namespace: when environment-capture work starts, it lands directly in the target layout (
api/apps/capture/), the first capability to never exist in the old shape. - Training namespace: after the workflow engine lands (AURA-805), add the
pipelinesbroker to the platform routers and stand up/api/v1/apps/trainingon the dispatch-and-observe contract, with checkpoint registration intoservingas the reference pipeline's last step. - Provisioning service: after the job store moves to Postgres, add the plan/approve/apply pipeline over
infra/terraformwith its admin UI surface.
Deferred without a date: the physical two-service split (revisit at Postgres plus external Application API traffic), management-plane billing (v2, per the existing roadmap), and any change to Studio's runtime (the portable-core work in the local-mode doc proceeds on its own track).
10. What this doc does not decide
The CLI's implementation language, distribution channel, and auth flow are open; only its existence, its name-level shape (one binary, namespace subcommands), and its first command are set here. The Postgres schema for the job store is not designed here. The workflow engine choice is a recommendation (Prefect 3, per the deterministic-orchestration research note) tracked under AURA-805, not a decision this document closes. The model registry's manifest schema and signing chain live in the edge OTA design and its implementation issue, not here. The outbound handler's allowlist governance (who approves an entry, how a namespace requests one) needs its own short design under AURA-730, as does the admin UI's eventual scope over Studio tenants (suspend, impersonate, quota override); DLP policy on AI Gateway beyond logging is deferred with it. Whether mac stays in-process or becomes a served namespace is deferred until it has a second consumer. The interaction between capture outputs and sim inputs is a capability design for those epics. Tenant-facing exposure of the Application API beyond Studio (external API keys, rate limits) is management-plane work and is not scheduled.