Agentic Coding Platform (Auraison Studio)
Status: Proposed (RFC) · Updated: 2026-07-18 · Jira: AURA-743 (this doc closes its assessment scope), AURA-744 (data model, done), AURA-730 / AURA-733 (security, linked)
1. Context and scope
Auraison's architecture docs have been converging on a Cloudflare-hosted central agent runtime for over a quarter: the system architecture commits to a Claude Managed Agent on Cloudflare (Agents SDK, Durable Objects, Dynamic Workers), and the agent data model distilled the ontology of Cloudflare's vibesdk into a canonical Auraison schema. What has been missing is the product that makes those commitments concrete. This doc designs that product: a browser-based agentic ROS2 development service, modeled on Cloudflare's enterprise AI vibe-coding reference architecture, in which a session agent orchestrates ROS2 development the way vibesdk's agent orchestrates web-app generation. The nearest existing service is Leet Robotics, which puts ROS2, Gazebo, and Foxglove in the browser as a learning platform; Auraison Studio differs in that the agent, not a lesson sequence, drives the development loop, that a GPU execution tier (Ray, Isaac Sim) sits behind the free tier, and that tenants can attach their own hardware, laptop included, as a workspace substrate.
The doc also discharges AURA-743: section 6 maps both Cloudflare reference architectures onto Auraison's four planes with an adopt/adapt/skip decision per component, and section 4 gives the vibesdk verdict with license.
Working name: Auraison Studio, at studio.aegeanai.com. "Studio" below means the product
surface; "control plane" keeps its existing meaning (the on-prem FastAPI service and its
agents).
2. Product definition and user journey
An external user signs in, describes a robotics task in chat ("make the TurtleBot patrol the maze and stop at obstacles"), and a session agent plans the work, scaffolds a ROS2 workspace, builds it, runs it in simulation, and streams the running sim back into the browser as a live Foxglove view. The session terminates in a shareable artifact: the packaged ROS2 workspace plus a recorded replay at a public URL. Reference apps seed the catalog (TurtleBot maze first, AR4 manipulation later) the way courses seed Leet Robotics, but the user's primary interaction is conversational, with an embedded editor available as a secondary surface.
Robotics development on the platform is wider than the code-build-simulate loop. Recorded runs accumulate in the tenant's storage and the lakehouse, and working with them means annotation (labeling episodes and events for training data), visualization (Rerun and Foxglove views over stored recordings, not just live sims), and analytics (success rates, regressions across runs). Sessions can therefore generate companion web apps for these functions and deploy them as isolated Workers (section 9), so "an annotation tool for my grasp dataset" is as valid a session outcome as "a patrol behavior for the TurtleBot".
The v1 journey:
- Sign in at
studio.aegeanai.comthrough Cloudflare Access; first login creates the tenant and provisions the free tier. - Pick a reference-app template or start blank. A hosted CPU workspace container is provisioned by default; alternatively the user runs the Auraison connector on their own laptop or on-prem machine (CPU or GPU) and the session attaches to that instead.
- Chat with the session agent. The agent produces a Blueprint, writes ROS2 packages into the
workspace, runs
colcon build, launches headless Gazebo, and the UI embeds Foxglove web against the workspace's bridge. - Iterate conversationally. Sessions can burst to a GPU-tier session (quota- and waitlist-gated) for full-physics simulation, Isaac Sim, or training.
- Publish. The workspace is packaged to R2 and the final sim run is recorded; the share page
at
artifacts.aegeanai.comembeds the replay.
3. Decisions
Five product decisions were made before the architecture was drawn, and the rest of the doc follows from them.
| Decision | Choice |
|---|---|
| Audience (v1) | External users; a product, not an internal tool |
| Execution substrate | Three, behind one provider interface: Cloudflare Containers (hosted CPU, default), Auraison GPU nodes (hosted burst, gated), BYO connector (tenant's own laptop or on-prem machine, CPU or GPU) |
| Primary surface | Chat-first vibe coding; editor secondary |
| Terminal artifact | Two kinds: shareable sim artifact (packaged workspace + recorded replay) and companion web apps (annotation, visualization, analytics) on Workers for Platforms; no physical robots in v1 |
| Monetization (v1) | Full metering and free-tier quotas from day one; Stripe deferred to v1.5 |
Choosing an external audience pulls parts of the management plane (tenancy, quotas, metering) forward from v2 into this design. Choosing a sim artifact as the terminal deliverable keeps physical robots, and the safety and scheduling machinery they need, out of v1; the user-plane actuation-gating constraints remain the path for a later deploy-to-robot tier.
4. Build strategy
The strategy question concerns the platform layer only: the chat surface, the session agent, tenancy, and metadata. It does not decide where workspaces execute; workspace execution is a provider interface with three substrates (section 5), and the tenant's own hardware is one of them. Three strategies for the platform layer were considered. Forking vibesdk would buy a working chat product, session catalog, and sandbox lifecycle, but its blueprint prompts, phase machine, preview model, and deploy pipeline all assume web apps deployed to Workers for Platforms; the ROS2 domain and the multi-substrate workspace model would be surgery against inherited assumptions. Extending the existing FastAPI control plane with Cloudflare as a mere front door would minimize new technology but concentrate multi-tenant isolation, metering, and free-tier scaling on a single on-prem process with an in-memory job store, and it would walk back the central-runtime direction the system architecture already adopted. The chosen strategy builds natively on the Cloudflare Agents SDK, implementing the canonical ontology from the agent data model doc, and treats vibesdk as a reference to quarry rather than a base to fork.
The vibesdk verdict, for AURA-743: reference, not fork. The repository is MIT-licensed, so forking is legally clean, but web-app generation is its only deliverable, wired through the core of the codebase; ours is one deliverable among several (ROS2 workspaces, sim recordings, companion apps) on a multi-substrate workspace model it has no concept of. Its data model has already been absorbed into agent-data-model.mdx; its sandbox lifecycle and phase-machine patterns are adopted below in adapted form, and its Workers-for-Platforms deploy path is adopted as-is for companion apps (section 9).
5. System architecture
Cloudflare runs the product surface, the agent runtime, and all tenant-facing state. Workspace execution happens on one of three substrates behind a single provider interface: Cloudflare Containers (hosted CPU, the zero-friction default), Auraison's GPU nodes (hosted burst, gated), or the tenant's own hardware attached through a connector. The on-prem cluster keeps its existing control plane, demoted from public front door to internal service.
In the monorepo, the Studio Worker, its UI, and the Orchestrator Agent live under
control-plane/studio/ (they are control-plane surface); the ros2-workspace image and its CI
live under user-plane/.
The Studio Worker serves the Next.js UI and the platform API. Each session is an Orchestrator Agent, a Durable Object created through the Agents SDK, which holds live session state and drives the agent loop. Every LLM call from every session goes through AI Gateway, which is what makes per-tenant cost attribution and prompt auditing a configuration rather than a feature. D1 holds the platform catalog (tenants, apps, sessions, artifacts, deployments; the target schema in agent-data-model.mdx §5 lands here for platform metadata, while the control plane keeps its own store for GPU jobs). KV holds session and permission lookups. R2 holds workspace snapshots and published artifacts, tenant-prefixed. Secrets Store holds platform credentials, injected at the platform layer.
All three substrates run the same pinned ros2-workspace image (ROS 2 Jazzy, Gazebo Sim
headless, foxglove_bridge, colcon, reference-app templates) and are driven through one
workspace provider interface: the Orchestrator DO issues workspace.* and sim.* calls
against the interface and does not know which substrate answers. The hosted CPU provider runs
one Cloudflare Container per active workspace; the container's preview URL carries the Foxglove
websocket into the browser, and there is no X11 or VNC in the CPU tier. The hosted GPU provider
is the existing user plane (Ray on Proxmox, ros.dev.gpu, Isaac Sim over WebRTC using the
multi-user port scheme from the
Isaac Sim runbook), reached only through a
Cloudflare Tunnel; GPU endpoints have no public exposure, the FastAPI control plane and its
claude -p specialist agents keep their current responsibilities on that side, and the
Orchestrator DO is a client of the control plane, not a replacement for it.
The BYO provider is a small connector CLI the tenant runs on their own machine (laptop or
on-prem server, CPU or GPU). The connector pulls the ros2-workspace image, runs it locally,
and holds a single outbound connection to the platform (a persistent WebSocket to the tenant's
Orchestrator DO, or equivalently a cloudflared tunnel); no inbound port is ever opened on the
tenant's machine. Through that connection the DO drives the local container exactly as it
drives a hosted one. Visualization improves rather than degrades on this substrate: the browser
connects to the local container's Foxglove bridge on localhost when the browser and connector
share a machine, falling back to a relay through the connector otherwise. GPU-capable tenant
machines run the same image with the GPU runtime enabled, which makes the connector the
self-serve alternative to the waitlisted hosted GPU tier.
In four-plane terms: the Studio Worker, Orchestrator DOs, and AI Gateway extend the control plane to the edge; workspace containers and GPU sessions are user plane; D1, KV, R2, and the lakehouse are data plane; tenancy, metering, and quotas are the first shipped slice of the management plane.
6. Reference-architecture component mapping (AURA-743)
The table maps the components of Cloudflare's base and enterprise vibe-coding reference architectures onto this design. "Adopt" means used as the reference intends; "adapt" means the role is filled differently; "skip" means deliberately not used in v1, with the reason.
| Component | Decision | Plane | Role here |
|---|---|---|---|
| Cloudflare Access | Adopt | Management | Signup/SSO, tenant identity, service tokens on the Tunnel |
| AI Gateway | Adopt | Control | All LLM traffic; cost attribution, prompt logging, caching |
| Sandboxes / Containers | Adopt | User | CPU-tier ROS2 workspaces with preview URLs |
| Durable Objects (Agents SDK) | Adopt | Control | Orchestrator Agent per session; SQLite-in-DO session state |
| D1 | Adopt | Data | Platform catalog; per-tenant rows, schema from agent-data-model.mdx |
| KV | Adopt | Data | Session and permission lookups |
| R2 | Adopt | Data | Workspace snapshots, published artifacts; tenant prefixes |
| Secrets Store | Adopt | Management | Platform credentials, injected at platform layer only |
| Cloudflare Tunnel | Adopt | Control | Only path from Cloudflare to the on-prem control plane and GPU tier |
| Logpush / Tail Workers / Analytics Engine | Adopt | Management | Platform observability and the compute-minutes meter |
| Workers for Platforms | Adopt | User | Deploy target for tenant-generated web apps (annotation UIs, Rerun/Foxglove visualization, analytics over recorded runs) as isolated Workers with per-app bindings; sim runs themselves publish as static replays |
| Artifacts (git-compatible storage) | Adapt | Data | Git bundles in R2 in v1; move to Artifacts when it generalizes |
| Dynamic Workers | Skip | — | Wrong runtime for ROS2; code executes in containers |
| Workers VPC / Hyperdrive | Skip | — | Tunnel suffices at this scale; revisit with fleet growth |
| DLP on prompts | Adapt | Management | AI Gateway logging + audit in v1; enterprise DLP policies deferred |
Two deltas against the reference are worth stating. First, our production plane has two artifact kinds where the reference has one. A sim run publishes as a static, replayable recording, which executes nothing on our infrastructure; a companion web app (annotation, visualization, analytics) deploys exactly as the reference intends, an isolated Worker in a dispatch namespace whose only data reach is its explicitly attached bindings. Second, the reference assumes all execution lives on Cloudflare; here only the default CPU tier does. The GPU tier runs on our nodes and the BYO tier on hardware the platform does not control at all, so the outbound-only connection plus scoped-token boundary carries the isolation burden the reference assigns to bindings alone.
7. Session orchestration
Each session runs the phase machine below, adapted from vibesdk's generator agent. Build and
sim failures are inputs to the loop, not errors: the agent reads compiler output and sim
telemetry in REVIEWING and decides to iterate or present, within a phase budget
(MAX_PHASES, default 10, adopted from vibesdk and enforced alongside the AgentOps runtime
policies).
SIMULATING launches headless Gazebo with the generated launch file and evaluates declared
outcomes (goal reached, no collisions, required topics alive) rather than just exit codes, so
REVIEWING has telemetry to reason over. The Blueprint, the append-only event log, and the
file state live in the DO per the canonical ontology; terminal state is mirrored to D1 when the
session closes.
The agent's tool surface is small and typed, mirroring the control plane's ALLOWED_TOOLS
scoping pattern:
| Tool | Effect |
|---|---|
workspace.write_files | Write/patch files in the workspace |
workspace.exec | Run a command (build, test, rosdep) in the container |
sim.launch / sim.stop / sim.status | Manage the Gazebo run and read outcome telemetry |
viz.stream | Return the Foxglove websocket URL for the UI to embed |
gpu.request_session | Broker a GPU-tier session through the control plane |
artifact.publish | Run the publish pipeline (section 9) |
app.deploy | Build a companion web app and deploy it to the Workers-for-Platforms dispatch namespace (section 9) |
8. Workspace execution
A hosted CPU workspace moves through Provisioning → Ready → Active → Idle → Hibernated → Destroyed. On idle timeout the workspace directory is snapshotted to the tenant's R2 prefix
and the container is released; resume rehydrates from the snapshot. Containers are cattle and
R2 is the workspace of record, which is also what makes a mid-session container death a
recoverable event rather than data loss.
A BYO workspace inverts the ownership: the tenant's disk is the workspace of record, and the
platform holds only what the tenant publishes plus optional snapshots. The connector lifecycle
is Registered → Attached → Detached: registering binds a named connector to the tenant with a
scoped token, attaching makes its workspace available to sessions, and detaching (or simply
closing the laptop) leaves the session paused, resumable when the connector returns. A
workspace snapshotted to R2 can move between substrates, so a session started on a laptop can
burst to a hosted GPU session and come back.
gpu.request_session calls the control plane over the Tunnel. The control plane allocates a
Ray-managed ros.dev.gpu session, or an Isaac Sim WebRTC session using the existing
multi-user signal/media port scheme, syncs the workspace from R2, and returns connection
details to the DO. GPU sessions carry hard caps (wall-clock duration, concurrent sessions per
tenant) enforced on the control-plane side, so a compromised or runaway edge component cannot
exhaust the pool.
9. Artifact pipeline
artifact.publish is the deploy step and it is transactional: the share page is minted only if
all three writes land.
- Package the workspace as a git bundle plus tarball to the tenant's R2 prefix, versioned, with lineage recorded per the Artifact model (parent artifact, session, blueprint).
- Record the final sim run: rosbag captured during
SIMULATING, converted to.mcap(and optionally Rerun.rrd), written to the public artifacts bucket under<tenant>/<app>/<run>. - Write the
artifactsanddeploymentsrows in D1 and mint the share page atartifacts.aegeanai.com/<tenant>/<app>/<run>, which embeds the Foxglove or Rerun web viewer against the recording.
The share page is the static deliverable, playing the role a deployed Worker URL plays in
vibesdk for sim runs. It reuses the existing R2 public-viewer pattern but tenant-namespaced;
unlike the current ar4-physical-ai bucket, only the published prefix is world-readable, not
the bucket. Serving shares from artifacts.aegeanai.com rather than the product origin
follows the standard rule that user-generated content never shares an origin with the app
(GitHub's githubusercontent.com, Google's googleusercontent.com); a same-domain subdomain
is acceptable here because the tenant contributes only data files (.mcap, .rrd) while the
page HTML and viewer are platform-authored.
A project (AURA-799) can additionally bind its DATA-artifact writes — the workspace tarball,
git bundle, and recording above — to a bring-your-own S3-compatible target instead of the
platform default, via the projects table's bucket_endpoint/bucket_name/bucket_prefix/
bucket_region/credentials_ref columns. This is a storage-seam config change, not an
architecture change: any S3-compatible target that accepts path-style URLs works. Hugging
Face Buckets are a validated example (https://s3.hf.co/<namespace>, region us-east-1,
path-style, operator-provided HFAK… keys generated in the HF UI — there is no minting API,
and HF bucket creation itself is manual/UI-only). Credentials are never stored raw in D1:
credentials_ref is a name, resolved from the Worker's environment at publish time
(STORAGE_CRED_<REF>_ACCESS_KEY_ID/_SECRET_ACCESS_KEY). The share page above stays on the
platform artifacts bucket regardless of a project's binding — public serving directly from a
bring-your-own bucket (which for HF Buckets means following a GET's 302 redirect to its CDN)
is deferred; only the write path is wired today.
Companion web apps are the second deliverable, and they use the reference architecture's
deploy path unmodified. app.deploy builds the app in the workspace and deploys it into a
Workers-for-Platforms dispatch namespace as an isolated Worker at a tenant-scoped URL on a
dedicated registrable domain acquired for tenant apps (the workers.dev analog; name chosen
at Phase 4), never on aegeanai.com or a subdomain of it. Companion apps are arbitrary tenant
code, so the weaker same-site subdomain isolation that suffices for data-only shares does not
suffice here: a separate domain removes shared-cookie and same-site exposure and confines
abuse or blocklisting fallout to the app domain. Its
bindings are the whole of its data reach: a read-only R2 binding on the tenant's recordings
prefix, its own D1 database and KV namespace for app state (annotations land here or back into
tenant R2), and access to lakehouse queries only through a platform data API over the Tunnel,
authenticated per tenant. An annotation UI, a Rerun or Foxglove viewer over stored .rrd and
.mcap files, and an analytics dashboard over run history are all this shape: static assets
plus fetch calls against bindings, which is precisely the workload Workers for Platforms
isolates well. Apps are private to the tenant by default, with Access-gated sharing following
the same pattern as the share page.
10. Tenancy and security
Identity is Cloudflare Access with public IdPs (Google, GitHub, email OTP); first login creates the tenant row in D1. The security posture is the reference architecture's untrusted-code assumption applied end to end: agent-generated code executes only inside the tenant's container, containers get allowlist egress (ROS, apt, and PyPI mirrors only), and platform credentials never enter a workspace; anything the workspace needs is injected by the platform layer from Secrets Store. Calls from the Studio Worker and DOs to the control plane authenticate with Access service tokens over the Tunnel. Storage is tenant-prefixed in R2 and tenant-keyed in D1, and the published-artifact prefix is the only world-readable surface.
The BYO substrate changes who is protected from whom, not the mechanisms. The platform treats a BYO workspace as an untrusted executor: its connector token is scoped to the owning tenant's sessions and R2 prefix, tool results arriving from it are untrusted input to the agent loop, and platform secrets are never sent to it. In the other direction, code executing on the tenant's own hardware is the tenant's own risk, which is the normal posture of any local dev tool; the platform cannot enforce egress allowlists there and does not pretend to. What the tenant runs is the same published, pinned image, so they can audit exactly what the connector executes.
AI Gateway gives every LLM call a tenant- and session-attributed audit record, which is the v1
answer to the reference's DLP requirement. The AgentOps runtime policies already defined in the
control plane design (max_tool_calls, token budgets,
max_duration) are enforced inside the Orchestrator DO. The new surfaces this design creates
(studio.aegeanai.com, the Tunnel, container preview URLs, the tenant-namespaced share
bucket, and at Phase 4 the tenant-app domain) fall under the AURA-733 access-control audit,
and the shared concerns with the Platform Security epic (AURA-730) are linked there rather
than restated. Domain isolation for tenant content follows the split in section 9: data-only
shares on the artifacts.aegeanai.com subdomain, executable tenant apps on a separate
registrable domain.
11. Metering and quotas
Three meters run from day one, each attributable to tenant and session: LLM spend (AI Gateway), compute minutes (Analytics Engine events emitted on container and GPU-session start/stop), and storage bytes (R2). Quotas live in D1 and are checked by the orchestrator before it provisions anything. Free-tier limits are hard: one concurrent hosted workspace, a daily sim-minute cap on hosted compute, no hosted GPU (waitlist). BYO workspaces consume no compute quota, since the tenant supplies the hardware; only their LLM spend and platform storage are metered, which makes the connector the natural unlimited-sim path for free-tier users. Quota exhaustion surfaces as a chat message with an upgrade path, never a stuck session. Stripe checkout is v1.5; the metering schema is designed so that pricing a tier is a query over existing data, not a migration.
12. Error handling
Task failures and infrastructure failures are kept distinct. Build errors and failed sim assertions feed the agent loop (section 7). Infrastructure failures surface as typed events and degrade the session instead of ending it: a dead container rehydrates from the last R2 snapshot, an exhausted GPU pool queues the request or continues on CPU sim, and a Durable Object eviction is invisible because session state persists in DO storage and the event log is append-only and replayable. Publish failures retry; a partial publish never mints a share page.
13. Testing
Four layers. Container-image CI builds ros2-workspace and runs a colcon plus headless-Gazebo
smoke test on every image change. Orchestrator unit tests exercise the phase machine and tool
dispatch in vitest/miniflare against recorded LLM fixtures. Contract tests pin both sides of
the Tunnel API (DO client, FastAPI server) to a shared schema. A golden-path end-to-end run on
staging scripts a full TurtleBot-maze session from prompt to published share page on every
release. Security tests assert egress denial from a workspace, rejection of cross-tenant R2
access, and the absence of platform secrets inside a container.
Golden-path e2e sequence (as built, AURA-780/790)
The harness (control-plane/studio/e2e/golden-path.ts) drives a deployed Worker through the
full session lifecycle. Every hop below runs against real staging infrastructure: Cloudflare
Access admits the harness via a service token, the Orchestrator Durable Object replays
persisted conversation history into each turn, tool calls execute in the session's
ros2-workspace container, and the published artifact is asserted straight off the public
studio-artifacts.aegeanai.com bucket domain.
Budget guards bound the whole flow: 30 minutes wall clock and a 50-tool-call session budget on
the harness side (mirroring the Orchestrator's own MAX_TOOL_CALLS), 15 LLM steps per turn
server-side, and a 120 req/min rate cap on the studio-gateway AI Gateway. State reads use the
Agents SDK's own WebSocket push protocol (cf_agent_state) because no plain JSON state route
exists — see control-plane/studio/e2e/README.md for the operator runbook.
14. Rollout
| Phase | Scope | Exit criterion |
|---|---|---|
| 0 | Merge this doc; Terraform the new Cloudflare resources (D1, KV, Access app, AI Gateway, Tunnel, containers); build ros2-workspace image | Image passes smoke test; studio.aegeanai.com resolves behind Access |
| 1 | Internal alpha, single tenant: chat → Blueprint → CPU workspace → Gazebo → Foxglove → publish | TurtleBot-maze share page produced end-to-end by the agent |
| 2 | Multi-tenant beta: public signup, metering, free-tier quotas; BYO connector alpha (laptop, CPU) | External user completes the golden path unassisted, on hosted and on BYO |
| 3 | GPU burst tier over the Tunnel (Ray, Isaac Sim), invite-gated; BYO GPU support in the connector | GPU session brokered from a chat session; caps enforced; connector runs the image with GPU runtime |
| 4 | Public launch; companion-app deploy via Workers for Platforms (annotation, visualization, analytics); Stripe in v1.5 | Tenant deploys a working annotation or viz app from a chat session; pricing live on metered data |
All new Cloudflare resources are Terraform-managed in infra/terraform/stacks/cloudflare/ per
the IaC policy; nothing is console-created.
15. Backlog plan
Per the planning policy, Jira issues are created only after this doc merges. Work lands under
the capability-epic spine with a new studio label (Component when available) as the project
facet: the Orchestrator DO, phase machine, and tool surface under Agent Orchestration / Control
(AURA-544), along with the workspace provider interface and the BYO connector protocol;
Terraform, Tunnel, containers, connector packaging, D1/KV, and observability under Platform
Infrastructure (AURA-670); Access, egress, and tenancy isolation under Security (AURA-730),
linked to AURA-733; the artifact and metering schemas under Data & Lakehouse (AURA-176).
AURA-743 closes on the merge of this doc, with its system-architecture.mdx update
requirement satisfied by the cross-reference added there.
16. What this does not cover
Deploy-to-robot is out of v1 by decision, not omission; the actuation-gating and scheduling design it needs stays in the user-plane doc. Stripe payment flows are v1.5. Fine-tuned domain-specific coding agents (the second agent type in the system architecture) plug into this platform later as alternative session-agent harnesses; nothing here precludes them, but their training and evaluation are separate work. Multi-region and Workers VPC are revisited when tenant load justifies them.