hero_cockpit — end-user control surface for a Hero OS demo VM (deep spec) #1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
hero_cockpit — end-user control surface for a Hero OS demo VM
Spec for the user-facing UI that ships on every demo VM provisioned by
hero_os_tfgrid_deployer. Pulls together the meeting notes athero_os_tfgrid_deployer#1, the s132 VM-bootstrap groundwork inhero_demodeploy/single-vm/scripts/setup-binaries.sh, and the canonical skills.1. Goal
A simple, lightweight, web-based control surface that an end user reaches via their VM's public gateway URL (e.g.
https://herolab.gent02.grid.tf/). Once authenticated through hero_proxy (OAuth via Forge), the user can:lab updatethrough hero_proc)lhumina_public/feedbackIt is explicitly NOT:
hero_os_tfgrid_deployer, separate repo)2. Architecture
Scaffold from
hero_templateso cockpit follows the canonical Hero service workspace shape. Final crate layout:hero_cockpithero_cockpit--start/--stop/--status/--info)hero_cockpit_serverhero_cockpit_serverhero_cockpit/rpc.sockhero_cockpit_sdkhero_cockpit_adminhero_cockpit_adminhero_cockpit/admin.sock/hero_ui_dashboard_adminskillhero_cockpit_webhero_cockpit_webhero_cockpit/web.sockAll
_admin+_webusehero_admin_libper the/hero_ui_dashboardskill (shared Bootstrap + unpoly + Chart.js + connection-status widget, base_path_middleware, /health + /.well-known/heroservice.json, axum 0.8, Askama templates).hero_cockpit_webintegrates the iframe / postMessage protocols (hero:theme,hero:route) per/web_embedso the cockpit pages embed cleanly inside the Hero OS shell when navigated to/hero_os/ui/cockpit.3. Page inventory (the
_webcrate)3.1 Landing —
//hero_os/ui/<service>via hero_proxy)3.2 Services —
/serviceshero_cockpit_serverRPC → server invokeshero_proc service <action> <name>and the underlyinglab serviceflow3.3 Settings —
/settingshero_cockpit_server→hero_proc secret sethero_cockpit_server→lab update(covered separately in §5)3.4 Feedback —
/feedbackhttps://forge.ourworld.tf/lhumina_public/feedback/issues/new?template=feedback3.5 Manual —
/manualdocs/manual/*.mdin the cockpit crate (we curate this content)hero:theme/hero:routeintegration)3.6 About / Warning —
/abouthero_proc secret export, etc.)4. API surface —
hero_cockpit_server(OpenRPC)The server is the integration point. It owns:
cockpit.list_servicesservice listcockpit.start_service(name)service startcockpit.stop_service(name)service stopcockpit.restart_service(name)service restartcockpit.enable_service(name)cockpit.disable_service(name)cockpit.get_byok_keys()secret getcockpit.set_byok_key(name, value)secret setcockpit.test_byok_key(name)cockpit.upgrade()lab updatefor each installed servicecockpit.system_info()cockpit.submit_feedback(title, body, category)cockpit.expose_service(service, subdomain)domain.addcockpit.unexpose_service(domain_id)domain.delete5. Upgrade flow
User clicks "Upgrade now" on
/settings:hero_cockpit_web→ POSTcockpit.upgradeon cockpit_server[enabled]listhero_proc job submit lab build <name> --download --install --forcehero_proc service restartcockpit.system_info()showing new versions6. Per-user component manifest
The contract between the deployer (which writes it once at provisioning) and cockpit (which reads + edits it).
Path on VM:
~driver/hero/cfg/cockpit/services.tomlFormat:
Default profile = demo:
Lightweight profile: only always-on + hero_books.
Books-only profile: like lightweight + nothing else.
Custom: nothing default-enabled; user picks via cockpit.
The setup-binaries.sh refactor (separate issue) reads this file to pick which
lab build $repo --download --installcalls to make.7. Auth — hero_proxy + Forge OAuth
End-user accesses cockpit via
https://herolab.<node>.grid.tf/→ hits hero_proxy → proxy enforces OAuth-via-Forge → on success, request is forwarded to cockpit_web's web.sock.hero_proxy domain.addis called once at deployer-time:domain = "herolab.<node>.grid.tf"target_type = "socket"target = "/home/driver/hero/var/sockets/hero_cockpit/web.sock"auth_mode = "oauth"oauth_provider = "forge.ourworld.tf"allowed_pubkeys = [<user's forge id>]strip_prefix = falsehttps_redirect = trueCockpit reads the authenticated forge user from request headers (
X-Hero-Claimsperhero_admin_lib::middleware::HeroClaims) and uses that to gate write operations.8. Dynamic URL mapping — "share a service"
From the meeting notes: "user wants to expose a channel on the whiteboard — we have whiteboard — can map url to their proxy — e.g. mik..grid.tf — can invite other people to play with it".
User flow:
hero_whiteboard_webshares a channel publiclycockpit.expose_service(service: "hero_whiteboard", subdomain: "mik")domain.addwithdomain = "mik.herolab.gent02.grid.tf"(or wildcard / dynamic subdomain pattern TBD with hero_proxy)unexposebutton9. Boundary with deployer
~/hero/cfg/cockpit/services.tomlsetup-binaries.sh(from this PR/thehero_demorepo) which reads the manifestcockpit.system_infoover the VM's gateway to surface state in its dashboard)10. Boundary with hero_compute
None. Cockpit lives inside the VM after hero_compute is done. Cockpit has no need to call hero_compute's API.
11. Out of scope (initial)
12. Implementation plan — proposed session map
hero_template. Build empty crates that passcargo check, register service.toml, /health + /.well-known endpoints./services) + cockpit_server RPCs: list_services, start/stop/restart_service./settings) + cockpit_server RPCs: get/set/test_byok_key, system_info.cockpit.expose_service/unexpose_service) + hero_proxy admin integration.13. References
hero_os_tfgrid_deployer#1hero_demodeploy/single-vm/scripts/setup-binaries.sh (s132)hero_template/hero_website·/hero_ui_dashboard·/hero_ui_dashboard_admin·/hero_admin_lib·/web_embed·/hero_proc·/hero_log·/hero_service