Status: repo-side v0.1.0 release hardening now includes a packaged in-app updater, local update-manifest support, an installed /Applications app bundle, and a freshly packaged THORApp.app that was rechecked against both live Docker Jetson sims; remaining blockers are external sign-off items (physical AGX Thor bring-up rehearsal and a real Developer ID/notarized tag release)
- 100+ files, 19,800+ lines
- Current no-Docker release gate passes locally across database, pipeline, registry, quick-start, readiness, and CLI smoke coverage
- Docker-backed simulator integration has been rerun successfully again via
make test - Registry trust, setup wizard/doctor, readiness gating, ROS2 workbench, Sensor Cockpit, typed recipes, diagnostics bundles, and simulator parity are now present across app, agent, CLI, and tests
- All features implemented and tested
- README with install instructions
- CHANGELOG.md
- CONTRIBUTING.md
- LICENSE (MIT)
- Homebrew formula
- Install script (curl)
- GitHub Actions CI/CD
- Issue templates
- PR template
- CLAUDE.md with development rules
- .claude/ settings and rules
- Repo description and topics set
- Code review (/code-review)
- Security review (/security-review)
- Git tag v0.1.0
- GitHub Release
- Repo-side install/update/release/docs paths are green locally
- Live launched-app inspection now confirms the packaged app reconnects to both local sims and repopulates the data-heavy pages after relaunch
- External release sign-off is still pending on physical hardware rehearsal and Apple-notarized distribution
- Added an operator-facing workspace preference layer so Docker can be muted instead of treated like a mandatory part of every THOR session:
Settings > General > Workspacenow includesShow Docker and simulator tools- disabling that preference removes the Docker tab from the device sidebar, hides Docker capability/readiness noise from the main operator surfaces, and drops the simulator-first suggested flow from onboarding/setup
- the underlying Docker functionality still exists and can be re-enabled instantly from settings when simulator or container-runtime work is needed again
- Added built-in tab help so operators can understand what each page is for without guessing:
- every
DetailTabnow carries centralized help metadata with a short summary, aStart Herechecklist, and aLook Forchecklist - device pages now expose a reusable in-app help card plus a toolbar
Show Help/Hide Helpcontrol Settings > General > Workspacenow includesOpen tabs with help visibleso teams can decide whether help should appear by default or only on demand
- every
- Added regression coverage for the new operator preferences/help surface:
- default Docker visibility preference
- default tab-guidance preference
- completeness coverage to ensure every device tab continues to ship with help content
- Performed a real launched-app inspection against the live Docker Jetson sims on ports
8470and8471and found a relaunch regression:- persisted
.connectedstate survived app relaunch, but the in-memoryAgentClientcache did not - that left Overview looking connected while System, Docker, ROS2, and downstream gated pages could come up stale or empty until a manual reconnect happened
- persisted
- Fixed the relaunch path in
AppStateso devices that were previously connected, or are marked auto-connect, restore a liveAgentClienton load using the configured simulator/local agent port - Added targeted regression coverage for the reconnect behavior in
Tests/THORTests/AppStateConnectionRestoreTests.swift - Replaced the invalid SF Symbol name
gpuwithmemorychipso the GPU pages stop emitting the runtime symbol-resolution error during live navigation - Repackaged
THORApp.appand re-verified the live UI after the fix:- full Thor device tab sweep completed in the launched app
- key Orin tabs (
Overview,System,Docker,ROS2) also verified in the launched app - the packaged app now repopulates System, Docker, ROS2, ANIMA gating, storage, and readiness data immediately after relaunch
- Sensor Cockpit image preview in the simulator still renders as a white tile because the current
camera-frontstream payload is a blank 2×2 JPEG placeholder from the sim, not because the app failed to decode or display the image
- Tightened the registry profile workspace so the flow is easier to understand during real operator use:
- replaced the dense setup checklist with a readiness summary grid and a single next-action card
- clarified that custom CA import is optional for normal HTTPS registries instead of treating it like a required step
- split the workspace into clearer operator-facing sections for connection, TLS trust, Mac validation, and Jetson rollout
- upgraded the saved-profile sidebar rows with validation/auth/namespace cues so profiles are easier to scan
- moved transient registry errors into a visible detail-banner instead of leaving them buried in the sidebar
- Closed the add-device onboarding gap for brand-new hardware:
Add Devicenow starts with an explicit staged choice betweenBrand-New DeviceandAlready Reachableinstead of assuming the target is already initialized and reachable- the brand-new flow now tells the operator to start on the USB console, complete OEM-config, record the real username, and then choose the first network handoff
- the first network handoff is now explicit inside the sheet: either
USB Tetherfor the common192.168.55.1path orEthernet Laterfor wired enrollment after bring-up - the sheet exposes the built-in AGX Thor first-boot guide, host-detection status for setup devices/keys, and path-specific shortcuts for USB-tether defaults or Ethernet enrollment prep
- Polished the runtime operator path after inspecting the live macOS app:
- THOR now reopens or creates the main window on launch instead of sometimes starting as a foreground app with no visible main window
- the AGX Thor quick-start sheet now exposes an explicit
Backbutton so operators can return to the Add Device flow without closing the whole context manually
- Revalidated this pass with:
make buildmake test-unitmake testSIGNING_MODE=adhoc Scripts/package_app.sh releaseScripts/dev/swiftw run thorctl health 8470Scripts/dev/swiftw run thorctl health 8471- live packaged-app inspection across the device pages
- relaunch of the freshly packaged
THORApp.appafter the Docker-visibility/help changes
- Validation still pending after this pass:
- rehearse the guided AGX Thor first-boot flow on physical hardware
- run a real Developer ID + notarization tag release with Apple credentials and published release assets
- Added a seventh production-hardening pass focused on application self-update and install ergonomics:
- new
AppUpdaterservice in THORApp with launch-time update checks, manualCheck for Updates…, and post-quit replacement into/Applications/THORApp.app - local update sources are now first-class via configurable
.app,.zip, orTHORApp-update.jsoninputs, in addition to GitHub latest-release discovery - packaged app bundles now embed
install_update.sh, and release packaging emits adist/THORApp-update.jsonmanifest alongside the zip/tar/checksums artifacts - settings now expose updater controls and local-source configuration, while the menu bar and app menu expose manual update checks
- installed the current
THORApp.appinto/Applicationsand preseeded the app defaults to watch the repo-localdist/THORApp-update.json
- new
- Revalidated the updater/release path after this pass:
Scripts/dev/swiftw buildScripts/dev/swiftw test --filter AppUpdaterTestsSIGNING_MODE=adhoc Scripts/release/package_app.sh releasemake distopen -a /Applications/THORApp.app
- Remaining follow-up after this pass:
- rehearse an end-to-end update prompt against a newer local manifest or release candidate with incremented build metadata
- rerun
make testonce Docker Desktop is available on the host - rehearse the guided AGX Thor first-boot flow on physical hardware
- run a real Developer ID + notarization tag release with Apple credentials and published release assets
- Added a sixth production-hardening pass focused on app-managed storage and release-path correctness:
- Swift build/test/release entrypoints now go through
Scripts/dev/swiftw, which keeps SwiftPM artifacts in repo-owned writable directories instead of assuming unrestricted user-home cache access DatabaseManagernow exposes a THOR support-directory resolver with explicit override support plus a temporary fallback whenApplication Supportis unavailable- registry certificate storage no longer derives from the SQLite file path, and registry cleanup is constrained to THOR-managed certificate files instead of deleting arbitrary paths
- diagnostics bundles now use the same support-directory root as the rest of the app-managed artifacts
- prerequisite checks now report a warning when THOR has to fall back to temporary storage instead of silently assuming durable Application Support access
- release verification now reads
Info.plistwithplutilinstead ofdefaults, fixing false negatives inmake dist Makefilepackage/dist targets now respect caller-suppliedSIGNING_MODE, so Developer ID + notarized CI releases are no longer overridden back to ad-hoc signing- cleaned the remaining selected-suite Swift test warnings in registry/database/pipeline/multi-device/edge-case coverage
- Swift build/test/release entrypoints now go through
- Revalidated the repo-side application/release path after this pass:
Scripts/dev/swiftw buildScripts/dev/swiftw test --filter RegistryFeatureTestsmake test-unitmake dist
- Remaining follow-up after this pass:
- rerun
make testonce Docker Desktop is available on the host - rehearse the guided AGX Thor first-boot flow on physical hardware
- run a real Developer ID + notarization tag release with Apple credentials
- continue app-quality polish around artifact/export path consistency and deeper storage-root separation if we keep tightening the operator UX
- rerun
- Added a real Jetson AGX Thor first-boot/operator path to THOR:
- shared
JetsonThorQuickStartSupportfor Mac-side serial port, USB tether, and SSH key detection JetsonThorQuickStartViewembedded in onboarding and setup surfacesthorctl quickstartfor the CLI equivalent- repo-owned
Scripts/jetson-thor/helpers and public setup runbook indocs/setup/
- shared
- Hardened the real-device setup flow so THOR stops assuming the demo defaults:
- file transfer and terminal launch now use the saved SSH username and Keychain identity
AgentInstallerresolves the configured username plus bundled/repo agent payloads instead of hardcodingjetson- guided-flow progress now persists through app state/database helpers
- Reorganized the repository for a public release surface:
- canonical scripts grouped under
Scripts/dev,Scripts/release,Scripts/setup, andScripts/jetson-thor - compatibility wrappers kept at the legacy root script paths so existing automation does not break
- documentation indexed via
docs/README.md, with PRDs moved underdocs/product/and release guidance underdocs/release/ - release packaging upgraded with
make dist,Scripts/release/create_dist.sh, SHA-256 checksums, and.github/workflows/release.yml
- canonical scripts grouped under
- Validated the new public-facing paths:
make dist→dist/THORApp-0.1.0-macos-arm64.zipmake dist→dist/thorctl-0.1.0-macos-arm64.tar.gzswift test --filter JetsonThorQuickStartSupportTests
- Remaining follow-up after this session:
- rehearse the new guided first-boot flow on a real AGX Thor devkit
- remove remaining build warnings in shared/app services before public release
- decide whether v0.1 public releases will stay ad-hoc signed or move to notarized builds
- Added a second production-hardening pass on top of the pushed baseline:
SECURITY.mdfor private vulnerability disclosure and supported-version policy.github/CODEOWNERSand.editorconfigfor clearer repo governance and consistency- notarization-capable release script at
Scripts/release/notarize_app.sh - release workflow now attempts universal Developer ID signed + notarized artifacts when Apple secrets are configured, while preserving ad-hoc fallback builds for contributors
- release docs updated to cover notarization inputs and behavior
- Revalidated production packaging after the hardening pass:
bash -n Scripts/release/notarize_app.sh Scripts/release/create_dist.sh Scripts/release/package_app.shmake dist
- Added a third release-hardening pass focused on production operator/release ergonomics:
- quick-start support now emits TTY-aware SSH commands with timeouts/keepalive plus a safe SSH-key generation fallback
- onboarding/setup/CLI copy now exposes clearer first-boot guidance, troubleshooting, and helper discovery for AGX Thor headless bring-up
- repo-owned serial/bootstrap helpers were hardened for clearer failure modes and safer sudo/bootstrap behavior
Scripts/dev/run_tests.shnow owns the split between Docker-backed integration tests and the non-Docker release gate used bymake test-unitScripts/release/verify_release.shnow validates archive integrity, version metadata, checksums, and code signing as part ofmake dist- the Homebrew formula now installs a
thorapplauncher instead of mutating/Applications
- Revalidated the current local production path:
swift buildmake test-unitbash -n Scripts/jetson-thor/bootstrap_ssh.sh Scripts/jetson-thor/thor_serial.sh Scripts/release/create_dist.sh Scripts/release/notarize_app.sh Scripts/release/verify_release.sh./.build/debug/thorctl quickstart nvidiaruby -c Formula/thorapp.rbmake dist
- Remaining follow-up after this pass:
- run the full Docker-backed integration suite again once Docker Desktop is available
- rehearse the end-to-end guided bring-up flow on a physical AGX Thor devkit
- exercise the full Developer ID + notarization path with real Apple credentials
- prove the Homebrew/tap install flow from a published tap, not only local formula syntax and packaging
- Added a fourth production-hardening pass focused on release trust, install ergonomics, and reproducible smoke validation:
Scripts/release/tap_smoke.shnow packages a local source archive from the current checkout and rewrites the temporary tap formula to install that archive, somake tap-smokevalidates the actual worktree instead of the stalev0.1.0tag- Homebrew launcher validation now checks that
thorapppoints at a real installed app bundle instead of assuming a specificoptpath shape Scripts/setup/install.shnow supports writable fallback install locations plusINSTALL_BIN_DIR/INSTALL_APP_DIRoverrides, making non-root install smoke reproducibleFormula/thorapp.rbnow uses the correct Homebrewsystemform for environment-scoped package builds and no longer implies the bottled install contains Docker simulator assets.github/workflows/release.ymlnow refuses to publish tagged releases without Apple signing/notarization secrets, while preservingworkflow_dispatchad-hoc smoke artifacts for contributorsScripts/dev/run_tests.sh unitand.github/workflows/ci.ymlnow include the offline CLI smoke coverage in the default no-Docker release gate
- Revalidated the updated repo-side release path:
make test-unitswift test --filter versionSmokeswift test --filter helpSmoke- temp-dir installer smoke via
INSTALL_BIN_DIR/INSTALL_APP_DIR Scripts/release/tap_smoke.shmake dist
- Remaining follow-up after this pass:
- rerun
make testonce Docker Desktop is available on the host - rehearse the guided AGX Thor first-boot flow on physical hardware
- run a real Developer ID + notarization tag release with Apple secrets
- rerun
- Added a fifth production-hardening pass focused on operator clarity and test-suite hygiene:
- split offline
thorctlsmoke coverage intoTests/THORTests/CLISmokeTests.swift, leavingTests/THORTests/CLITests.swiftas live-agent integration coverage only - simplified
Scripts/dev/run_tests.sh unitso the no-Docker release gate targets the dedicatedCLISmokeTestssuite instead of mixing in live-agent API tests - removed the last always-true assertion warnings from the live CLI integration suite so local build/test output stays clean
- tightened the public AGX Thor bring-up docs in
README.mdanddocs/setup/jetson-agx-thor-headless-quickstart.mdwith explicit OEM-config username substitution, per-phase success criteria, and a real-device-safe explanation ofthorctl doctor <local-agent-port>
- split offline
- Revalidated this pass with:
make test-unit
- Remaining follow-up after this pass:
- rerun
make testonce Docker Desktop is available on the host - rehearse the guided AGX Thor first-boot flow on physical hardware
- run a real Developer ID + notarization tag release with Apple secrets
- rerun
- Implemented the THOR v0.2 foundation plan end-to-end:
- setup wizard with
Use SimulatorandConnect Real Jetsonpaths - setup/doctor surface with readiness-classified remediation actions
- capability-driven gating and readiness board in device detail
- expanded ROS2 Workbench with graph, params, actions, launches, bags, and topic stats
- device-centric
Sensorstab with image/LaserScan previews, stream health, snapshots, and bounded bag capture - typed deploy recipes with prerequisites, rollback hints, and structured run history
- diagnostics bundle collection in app, agent, and CLI
- simulator parity for new ROS2, stream, and diagnostics routes
- setup wizard with
- Added shared v0.2 models and persistence:
CapabilityMatrix,ReadinessReport, ROS2/stream/recipe/diagnostics/guided-flow models- database tables for launch profiles, deploy recipes, recipe runs, diagnostic runs, and guided flow progress
- Added new agent routes:
/v1/ros2/graph/v1/ros2/parameters/v1/ros2/parameters/set/v1/ros2/actions/v1/ros2/action/send_goal/v1/ros2/topic-stats/v1/streams/catalog/v1/streams/health/{sourceID}/v1/streams/image/{sourceID}/latest.jpg/v1/streams/scan/{sourceID}/latest/v1/diagnostics/archive
- Added thorctl parity commands for the new workflow:
discoverdoctorros2 graphros2 paramsros2 actionsstreamsstream-statsrecipe rundiagnostics collect
- Validated the v0.2 baseline:
make builddocker compose up -d --build --force-recreate./.build/debug/thorctl discover./.build/debug/thorctl doctor 8470./.build/debug/thorctl ros2 graph 8470./.build/debug/thorctl streams 8470./.build/debug/thorctl diagnostics collect 8470 /tmp/thor-v02-diag.zipmake test→ 89 tests passing across 9 suites
- Reviewed the live THOR codebase for Docker, ANIMA deploy, Keychain, settings, trust, and simulator behavior.
- Confirmed current gaps for secure local OCI registry workflows:
- no registry profiles
- no TLS certificate import/trust management
- no registry auth in THOR
- no Jetson-side registry trust distribution
- no deploy-time registry preflight
- Created a repo-grounded PRD for the Shenzhen feature track:
docs/product/PRD-OCI-Registry-Trust-Manager.md
- Implemented the first shipping slice of OCI Registry Trust Manager:
registry_profilespersistence + migration- Keychain-backed registry password storage
- macOS certificate import, parsing, and trust install service
- registry validation service for config, trust, and
/v2/reachability - new registry workspace in the app shell
thorctl registriesandthorctl registry-validate- registry-focused regression tests
- Extended the feature from foundation to end-to-end Jetson rollout:
- new agent registry router for device status, apply, and preflight
- simulator-backed registry trust/auth state
AgentClientdevice registry models + methodsAppStatehelpers to apply/validate registry profiles on selected Jetsons- ANIMA deploy preflight against saved registry profiles
thorctl registry-device-status,registry-device-apply, andregistry-device-preflight- upgraded registry workspace with setup checklist, Jetson rollout, and preflight visibility
- additional integration tests for device-side registry apply + preflight
- Created a separate robotics-facing product PRD:
docs/product/PRD-Robot-Sensor-Cockpit.md- defines THOR’s next differentiation track around live sensor streaming, ROS2 bring-up, and robot readiness
- Implemented the first Sensor Cockpit camera slice for demo use on macOS:
- new
Camera Studioworkspace for host camera preview and bridge controls - host-to-sim camera bridge service using
AVFoundationon macOS and new agent hardware bridge endpoints - bridged camera snapshot rendering inside the device Hardware panel
thorctl camera-snapshotfor saving the latest agent-served frame- Docker sim restart workflow so new agent routes are picked up during local development
- new end-to-end integration test covering camera bridge ingest, inventory, and snapshot fetch
- new
- Integrated THOR’s Docker sim with the real host-side
docker_mlx_cppMLX daemon:- new agent helper for live
docker_mlx_cppdiscovery overhost.docker.internal - GPU endpoint now reports real Apple Silicon Metal / MLX backend status when available instead of simulated CUDA/TensorRT
- model inventory endpoint now surfaces actual cached MLX models from the host daemon
GPU & ModelsUI andthorctl gpunow label MLX / Metal explicitly and stop implying TensorRT on Mac demos- GPU/model integration tests updated to accept either Jetson-sim or live MLX-backed demo environments
- new agent helper for live
- Verified the implementation against Docker sims:
make docker-up./.build/debug/thorctl health 8470thorctl registry-device-apply 8470 registry.demo.local:5443 /tmp/thor-demo-registry.crt demo secretthorctl registry-device-preflight 8470 registry.demo.local:5443 registry.demo.local:5443/hello-world:latestdocker compose restart jetson-sim jetson-orin-simafter adding new agent routes./.build/debug/thorctl gpu 8470→ livedocker_mlx_cppbackend detected through the sim agentmake test→ 78 tests passing across 9 suites- rebuilt, packaged, and relaunched local
THORApp.appwithCamera Studio
- Tightened the Camera Studio demo path so it behaves like a real app flow instead of a detached prototype:
- moved camera bridge ownership into shared app state so it survives workspace switches
- wired
Hardware→Camera StudioandCamera Studio→Hardwarenavigation around the selected Thor device - kept simulated cameras visible even when a bridged host camera is active
- Hardened the host MLX probe so Mac demo endpoints degrade cleanly when
docker_mlx_cppdrops a connection:- capabilities, GPU, and model endpoints now fall back instead of returning HTTP 500
- reran
swift testafter container restart and restored the full 78/78 passing baseline
- M4 — v0.2 robotics foundation shipped on Docker sims; real-device onboarding rehearsal, UI polish, and adapter/deeper sensor work next
- Zero-to-first-device setup wizard
- Connection doctor with staged remediation
- Capability-driven UI and readiness board
- ROS2 Workbench
- Sensor Cockpit v1
- Typed deploy recipes
- Diagnostics bundle
- Simulator parity for v0.2 routes and flows
- thorctl parity for discover, doctor, ROS2, streams, recipes, and diagnostics
- Real Jetson enrollment rehearsal against physical hardware
- UI copy/polish pass on setup/degraded-state guidance
- Persist and resume guided flow progress from the app surfaces
- Feature PRD for OCI Registry Trust Manager
- Expand PRD with wizard, preflight board, recovery UX, and demo-safe flow
- Review and approve v1 scope
- Add registry profile data model + persistence
- Add macOS certificate import/trust workflow
- Add registry management workspace UI
- Add Jetson trust/auth application workflow
- Add registry validation and demo-ready checks
- Add registry-aware Docker pull and ANIMA deploy preflight
- Add registry browser UI (catalog/tags/repository inspection)
- Add thorctl support for registry inspection/validation
- Add simulator-backed tests for secure registry flows across macOS + Jetson
- Run Shenzhen demo rehearsal on Docker Registry v2
- Run Shenzhen demo rehearsal on Zot
- Need final product decision on whether v1 device-side readiness covers Docker only or Docker plus other OCI clients used in the showcase environment.
- Need confirmation on acceptable service disruption when applying trust to a live device runtime.
- Direct USB passthrough of the physical ZED 2i into Docker Desktop on macOS remains a poor demo dependency; the shipped path is host capture plus sim bridge until Linux/Jetson-native ZED SDK support is added.
- Honest Mac demo path is now split clearly:
- camera input is host-side and bridged into the sim
- AI compute is host-side Apple Silicon Metal via
docker_mlx_cpp
- Separate PRD for robotics-facing differentiation
- Review and approve Sensor Cockpit v1 scope
- Add live camera preview workspace
- Add host-to-sim camera bridge for demoable real-camera inventory
- Add ROS2 LaserScan visualization
- Add stream health overlays and bounded bag capture
- Expand ROS2 UI beyond list-only inspection
- Add robot readiness board tying sensors, ROS2, deploy, and runtime together
- Add typed deploy recipe workflow with preflight and rollback hints
- Add diagnostics bundle collection for support and regressions
- Run end-to-end rehearsal on a real Jetson with agent install/upgrade path
- Harden real-hardware host-key trust and unsupported/degraded compatibility copy from first field feedback