feat(demo): close the OTA loop for the rep demo - #16
Closed
mrangelmarino wants to merge 1 commit into
Closed
Conversation
Three-change YOLO branch that takes the closed-loop demo from "agent receives MQTT cmd then dies" to "operator triggers rollout, robot's path in Gazebo changes live within 6 seconds." Verified end-to-end on Apple Silicon: drive-circle auto-starts, `make demo-swap` triggers PHASE_PULLED → PHASE_SWAPPED → PHASE_HEALTHY, robot-app container swaps to figure-eight-v1, rover path changes in noVNC. 1. **Install docker-ce-cli in the agent container.** Bookworm's stock `docker.io` ships CLI API 1.41; Docker Desktop's daemon is on 1.44+. The mismatch caused every OTA `docker pull` to fail before PHASE_PULLED was acked. We pull docker-ce-cli from Docker's official apt repo at agent startup so the API matches the daemon. 2. **Auto-start a robot-app service running circle-v1.** New compose service with `container_name: robot-app` so the agent's OTA Swap (`docker rm -f robot-app + docker rename robot-app-new robot-app`) replaces it cleanly on the first rollout. Network: `default` (alias for `temporal-hack-lab_default`, same network OTA-spawned containers land on via OTA_RUN_ARGS). Depends on sim started + mqtt healthy so we don't publish Twists into the void during startup. 3. **`make demo-swap` target.** One-line OTA rollout fire to localhost:14050/robot-app:figure-eight-v1. Matches the existing sim-drive-* convention (inline `## ` help comment, no container-check dep since this is just curl to the host). Also wires `DOCKER_DEFAULT_PLATFORM=linux/amd64` on the agent because controller images are built --platform=linux/amd64 (their Humble base is amd64-only), and on Apple Silicon the daemon defaults to arm64 and refuses the amd64-only manifest. What this does NOT do (out of scope for the YOLO demo): - Doesn't clean up an OTA-replaced robot-app container on `make sim-down`. After a swap, the OTA-managed container is left dangling; cycling sim-up/down requires `docker rm -f robot-app` between. - Doesn't merge the partner-track PR #13 (cloudflared broker tunnel). The demo runs locally; an external tunnel only adds risk. Demo path: make sim-down && docker rmi temporal-hack/sim:dev && make sim-up open http://localhost:14680/vnc.html?autoconnect=1&resize=scale # rover starts driving in a circle automatically make demo-swap # rover's path changes to figure-eight; Temporal UI at :14080 shows phases Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Collaborator
Author
|
Superseded by parallel work from @bkearns: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three-change branch that takes the closed-loop demo from "agent receives MQTT cmd then dies" to "operator triggers rollout, robot's path in Gazebo changes live within 6 seconds." Verified end-to-end on Apple Silicon: drive-circle auto-starts, `make demo-swap` triggers `PHASE_PULLED → PHASE_SWAPPED → PHASE_HEALTHY`, robot-app container swaps to figure-eight-v1, rover path changes in noVNC.
Three changes
Install `docker-ce-cli` in the agent container. Bookworm's stock `docker.io` ships CLI API 1.41; Docker Desktop's daemon is on 1.44+. The mismatch caused every OTA `docker pull` to fail before `PHASE_PULLED` was acked. We pull `docker-ce-cli` from Docker's official apt repo at agent startup so the API matches the daemon. (Yak feat(sim): serve Gazebo GUI via noVNC (browser GUI on :14680) #4 closed: agent now has Docker 29.4.2.)
Auto-start a `robot-app` service running `circle-v1`. New compose service with `container_name: robot-app` so the agent's OTA Swap (`docker rm -f robot-app + docker rename robot-app-new robot-app`) replaces it cleanly on the first rollout. Network: `default` (= `temporal-hack-lab_default`, same network OTA-spawned containers land on via `OTA_RUN_ARGS`). `depends_on` sim started + mqtt healthy so we don't publish Twists into the void during startup.
`make demo-swap` target. One-line OTA rollout fire to `localhost:14050/robot-app:figure-eight-v1`. Matches the existing `sim-drive-*` convention (inline `## ` help comment, no `container-check` dep since this is just curl to the host).
Also wires `DOCKER_DEFAULT_PLATFORM=linux/amd64` on the agent because controller images are built `--platform=linux/amd64` (their Humble base is amd64-only), and on Apple Silicon the daemon defaults to arm64 and refuses the amd64-only manifest.
Why this matters for the demo
The closed-loop story is "operator triggers OTA → Temporal phases progress → robot's path in Gazebo changes live." Telemetry alone is data on a dashboard; behavior swap is the orchestration doing something the rep can see with their eyes. With this branch, the rep's path becomes:
```bash
make sim-up # rover spawns, starts circling
open "http://localhost:14680/vnc.html?autoconnect=1&resize=scale"
make demo-swap # ← THE moment
rover's path changes from circle to figure-8 in ~6 seconds;
Temporal UI at :14080 shows phases progressing in parallel
```
(Note: the host-side `./bin/controlplane` and `./bin/ota-worker` still need to be started separately — they're not in compose yet. See "Future work" below.)
Test plan
Out of scope / future work
Architecture
See the [mermaid diagram in the conversation transcript] — three trust boundaries (host / lab compose project / sim container internals), two viewing surfaces (Temporal UI + noVNC), two parallel planes (OTA control via host binaries→Temporal→MQTT→agent→docker, runtime data via robot-app→ROS 2→bridge→Ignition→rover joints).
🤖 Generated with Claude Code