As the spatial cognition workspace expanded, running query handling, reasoning projection, and spatial math directly inside the client Unity codebase became untenable. The headset needed to focus its compute budget strictly on OpenXR frame timing, physics simulation, and passthrough compositing. Meanwhile, downstream services, companion dashboards, and automated verification suites all required a shared, authoritative view of room state.
In this window, we split out the workspace layer into scp-plane-service,
a dedicated .NET 10 microservice, and cut its initial v0.1.0 release (v0.1.0).
The service acts as the central spatial clearinghouse: it ingests agent reasoning
steps, maintains append-only session snapshots (#20), and broadcasts
deterministic plane deltas (#6) to connected clients over streaming WebSocket
connections.
Packaging and deployment were built to be hermetic from day one (#13). The
service utilizes a multi-stage Docker build producing a non-root aspnet:10.0
container. Rather than rebuilding container images from scratch when tagging a
release, the release pipeline performs a registry-side retag of the manifest
previously built and scanned on main. This guarantees that the binary tagged
for production is bit-for-bit identical to the artifact that passed integration
tests.
With the standalone service established, development moved rapidly to v0.2.0
(#19, v0.2.0), introducing the durable command channel. Operating an agent
workspace inside VR means network drops and controller disconnections are normal
occurrences. To prevent interrupted gestures from repeating destructive actions,
commands are executed via a two-phase authorize -> arm -> commit sequence
backed by server-side idempotency tracking.
Finally, the service added explicit contract negotiation (#68) and authorized
sandbox handoff runners (#93), leading directly into the v0.3.0 milestone
(v0.3.0).
Lessons learned
- Retag existing CI-tested image manifests for releases rather than rebuilding.
Rebuilding a container image during a release workflow introduces non-determinism:
transient upstream package restores or build-runner toolchain drift can alter
the final output. Building and testing on
main, then performing a registry-side manifest retag on tag push ensures you ship what you tested. - Implement two-phase arm-and-commit semantics for XR WebSocket command links. Headset wireless links drop frequently during physical movement. If command dispatch is modeled as a single fire-and-forget message, packet re-transmits or rapid user re-clicks will spawn duplicate jobs. Arming a command with a unique idempotency token before committing guarantees execution happens exactly once.
- Decouple spatial delta math from headset rendering loops. Offloading plane merging, history serialization, and reasoning projection to a standalone backend protects the XR client’s 90Hz frame budget. The headset only renders the deltas it receives instead of churning CPU cycles on graph maintenance.
- Use runtime contract negotiation before opening high-frequency streams.
Providing
POST /contract/negotiateandGET /contract/surfaceendpoints lets clients interrogate backend capabilities before subscribing to binary WebSocket feeds. Protocol incompatibilities are flagged cleanly with HTTP 400s rather than crashing socket deserializers mid-stream.