How the properties connect, where contracts live, and which protocols cross each boundary. Rendered as the system will look after Feature #7 (Gateway Extraction) lands — i.e. once ace_supervisor has been split into robot-supervisor-service, robot-gateway-service, and shared-gateway-protocols.
Containers = where the code runs. Boxes = repos. Arrows = runtime traffic with protocol labels.
ace binary · :8090/log · /healthz"]
end
subgraph CJ["Capture Jetson — v0-ace00-capture"]
direction TB
RCS["robot-capture-serviceThick double lines (==>) are the Phase 3+4 phone-to-Gateway path that Feature #7 introduces. Dotted orange arrows mark where contract source-of-truth lives. Dashed nodes are owned outside Valeron but run on our hardware: ace_devel (Jimmy's nav stack, Robot Jetson) and golfer (Brandon + Marius's capture pipeline, Capture Jetson).
Colors used in the diagram + in the contract table below.
new_shot)Every contract that crosses a process or host boundary, where it lives, which surfaces it joins.
| Contract | Boundary | Protocol | Auth | Source of truth |
|---|---|---|---|---|
| Cloud edge functions pair · start-session · end-session · end-my-session · active-device-for-user · users-by-device · sessions · courses · connect |
Client (phone, web, robot, ferry) ↔ Cloud | HTTPS | Supabase JWT (user) or service-role (robot, ferry) | docs-platform/apis/cloud/edge-functions/*.yaml |
| Capture → Gateway webhook enrollment_complete |
Capture Jetson → Robot Jetson (Gateway) | HTTP (LAN) | Bearer CAPTURE_WEBHOOK_SECRET |
docs-platform/apis/webhooks/capture-to-gateway/enrollment_complete.md |
| Capture → Janice webhook shot_complete |
Capture Jetson → Robot Jetson (Janice) | HTTP (LAN) | Bearer CAPTURE_WEBHOOK_SECRET |
docs-platform/apis/webhooks/capture-to-janice/shot_complete.md |
| Janice → Gateway shot_complete forward POST /capture/shot_complete |
Loopback on Robot Jetson | HTTP loopback | Bearer GATEWAY_INTERNAL_SECRET |
shared-gateway-protocols (ACL-104) |
| Phone → Gateway live feed GET /ws · GET /shots · GET /shots/:id/{video,thumbnail} |
Golfer phone (LAN / AP) ↔ Gateway | WS + HTTP | Session token (?session=… on WS; Authorization on HTTP) |
shared-gateway-protocols (ACL-104) |
| Capture Jetson internal pipeline ↔ capture service (Contract 1 + 2) |
Two processes, same host | HTTP loopback + Unix sockets | HMAC-shared-secret (Contract 1) / bearer (Contract 2) | docs-platform/apis/capture/{internal-http,unix-sockets}.md |
| Robot onboarding | Field-tester / operator phone ↔ Robot Jetson | HTTP | Bluetooth-provisioned creds (future) | docs-platform/apis/robot/ONBOARD.md |
| Gateway → Cloud cloud_sync batched shot uploads |
Robot Jetson (Gateway) → Cloud | HTTPS | Service-role key (SUPABASE_SERVICE_ROLE_KEY) |
Reuses apis/cloud/edge-functions/sessions.yaml |
| Operator ↔ Robot desktop-ferry-app + desktop-tuner-app |
Operator laptop ↔ Robot Jetson | Tailscale | Tailscale identity (mesh VPN) | Per-tool README (no cross-surface contract) |
| Field app ↔ ace_dashboard (planned) forthcoming transport swap from today's HTTP :9000 → :8090 |
mobile-field-app ↔ ace_dashboard (Robot Jetson) | WS | TBD | TBD · JSON-over-WS (proto later) per Jimmy · not yet ticketed |
| Supervisor ↔ ace_dashboard (planned) forthcoming transport swap from today's HTTP :8090 |
robot-supervisor-service ↔ ace_dashboard (Robot Jetson) | WS | TBD | TBD · same JSON-over-WS shape as MFA · not yet ticketed · confirmed by Jimmy 2026-04-19 ("you don't need to go to 8090 anymore") |
| Cloud → Robot push | Cloud → Robot | none | n/a | docs-platform/apis/webhooks/cloud-to-robot/README.md — explicitly documents the pull-only policy |
Every Valeron-maintained repo + external-owned repos we consume, colored by surface. Names per ADR-022 post-Feature-#7 projection.
ace_supervisor). Target flipped from robot-sequencer-service → robot-supervisor-service on 2026-04-20 per ADR-022 Amendment 2026-04-20.ace-pilot) intentionally deferred.course_features publish flowapis/cloud/edge-functions/sessions.yamlnav2.yaml tuning tool for on-robot nav params.robot-capture-service, owned outside Valeron.mobile-field-app will swap its transport from direct HTTP to the Supervisor (:9000 → :8090) for a WS connection against ace_dashboard once it ships.ace binary · :8090What's different from today. The diagram shows post-Feature-#7 wiring: mobile-golfer-app talks to Gateway directly, the golfer web app that used to live at ace_supervisor/ui/golfer/ is retired (not drawn), and Janice's shot_complete branch is a pure loopback forward to Gateway — it no longer owns shot_store, cloud_sync, or the phone WS channel. Today, most of those paths still run through Janice.
What's deliberately absent. No cloud-to-robot push exists, by design (robots are NAT'd, connectivity-variable). The apis/webhooks/cloud-to-robot/ doc exists to enshrine the pull-only policy. Observer UI / Sequencer UI for operators is elided — per ADR-021 it migrates cloud-hosted, framework TBD, not yet a standalone repo.
ace_dashboard — planned, not shipped. Jimmy's forthcoming service on the Robot Jetson that fronts HAL + nav (and presumably other robot-services) behind one boundary. Dashed node in the Robot Jetson subgraph. Both Robot-Jetson clients of nav today migrate through it: (1) the Field-app transport swap (HTTP :9000 → RSS :8090 becomes WS → ace_dashboard), a one-file change in mobile-field-app/src/lib/stores/transport.js bundled with ACL-108 (Svelte+TS migration); (2) the Sequencer's own nav-stack calls (today RSS → :8090 on the C++ ace binary) also move to WS via ace_dashboard — confirmed by Jimmy 2026-04-19 ("you don't need to go to 8090 anymore"). Neither migration is ticketed yet — both wait on ace_dashboard shipping. Feature #7 Phase 5 Step 5 (relocating mobile-field-app into Gateway) was cancelled 2026-04-19: same-origin collapse was a golfer-phone / Safari-HTTPS driver, and Field Control runs over Tailscale so the constraint doesn't apply. mobile-field-app stays in its own repo, own port, own systemd unit.
HAL surfaced as its own node. Per Jimmy's framing, ace_dashboard "encapsulates all calls to robot services (HAL / nav / etc)" — HAL is a named upstream by definition, so surfacing it separately from the nav stack keeps the diagram honest about what ace_dashboard is fronting. Today HAL has no external callers (it's accessed intra-binary inside ace_devel); the only inbound edges on the diagram are the dashed planned edges from ace_dashboard. This is the right state: HAL becomes reachable from outside the ace binary exactly when ace_dashboard ships.
Identity axes to remember. Repo name ≠ Supabase project name ≠ env-var key. cloud-platform-service (the repo) drives the ace_cloud Supabase project (preserved), which is addressed in consumer repos via ACE_CLOUD_* env vars (preserved). See ECOSYSTEM.md §Repository Index for the three-axis carve-out pattern.
Ground truth: docs-platform/architecture/ECOSYSTEM.md (repo enumeration),
docs-platform/apis/ (contract sources),
cloud-platform-service/docs/plans/2026-04-16-gateway-extraction.md (Feature #7 design doc).
When this diagram and those sources disagree, the sources win — this file is a snapshot.