Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Plan: Remote Session CapSet Client

Overview

Push the remote host application / CapSet interop track forward without turning it into a kernel-core change. The first trusted local CLI/web bridge already proves login, session summary, CapSet inspection, implemented calls, denials, logout, stale-call proof, redacted transcript export, browser automation, DTO service catalog, service-runner profiles, Adventure launch, worker-backed chat, and worker-backed Adventure status/look/ inventory/bounded go. This plan picks up the remaining direction listed in WORKPLAN.md’s ad-hoc note: standard capnp-rpc transport/object proxy layer, complete transport lifetime and exception behavior, more auth adapters including guest admission, stronger resource/revocation bounds, richer service clients, and Paperclips launch.

Long-form decomposition lives in docs/backlog/remote-session-capset-client.md and docs/backlog/shared-service-demos.md. The session-bound invocation context boundary is recorded in docs/backlog/session-bound-invocation-context.md.

Browser JavaScript must continue to receive only view models, results, and denials. The Rust backend keeps the remote session and capOS caps. Do not expose terminal delegation, shell-runner policy, raw ProcessSpawner/process handles, endpoint owner handles, local cap ids, result-cap slots, browser-held capOS caps, or capOS-driven UI-composition capabilities through this path.

Conflict Surface

Owned by this plan:

  • tools/remote-session-client/ (Rust backend, browser bridge assets, Tauri preflight, scripted CLI harness)
  • capOS-side gateway and worker crates that back the remote-session smokes: demos/remote-session-capset-gateway/, demos/remote-session-chat-worker/, demos/remote-session-adventure-worker/. The Adventure worker boundary is shared with the Aurelian plan – coordinate before changing the worker’s Adventure call shape.
  • system-remote-session-capset-interop.cue, system-remote-session-adventure-interop.cue, and any new system-remote-session-*.cue manifest the new transport requires
  • Remote-session DTO additions in schema/capos.capnp (shared serial surface – see docs/plans/README.md Concurrency Notes; only one plan at a time may change schema/capos.capnp, and make generated-code-check must pass before the next plan picks it up)
  • docs/proposals/remote-session-capset-client-proposal.md, docs/backlog/remote-session-capset-client.md
  • Makefile targets remote-session-ui, remote-session-tauri, run-remote-session-capset-ui, run-remote-session-capset-interop, run-remote-session-adventure-interop

Direction the host UI must preserve while this plan runs (forward from WORKPLAN.md so the constraint travels with the executable surface):

  • Login is a dedicated OS-like screen with a visible username field and no full persistent technical header.
  • Browser login sends username/password only, defaulting the username from CAPOS_REMOTE_SESSION_USER or the host USER so it matches the operator account injected by make run. Resource profile names such as operator are not user-typed system details.
  • For the current legacy DTO protocol, the trusted Rust backend maps an omitted password profile to the default operator profile before calling the gateway. Gateway-side profile policy/picker support (post-auth picker for manifests with multiple user-meaningful profiles) remains future work; do not move that responsibility into the browser or the legacy DTO surface.
  • Authenticated users land in a compact Services-first workspace where Session, CapSet, Diagnostics, and Transcript are separate views. The UI smoke must continue to fail if any visible button is not exercised.

Do not touch from this plan:

  • Kernel-side session-lifecycle changes that are not strictly required to unblock a remote-session DTO change. Production lifecycle changes belong with the session lifecycle work tracked in WORKPLAN.md’s ad-hoc note and REVIEW_FINDINGS.md. Coordinate with the user before extending kernel/src/cap/session_manager.rs or kernel/src/cap/user_session.rs.
  • kernel/src/pci.rs, kernel/src/device_*.rs, IOMMU code (owned by device-driver-foundation plan)
  • demos/paperclips-*, demos/adventure-* (owned by demo plans). Add remote-session DTO entries that consume those servers’ existing surface; do not modify the servers themselves from this plan.

Validation Commands

  • make fmt-check
  • make generated-code-check
  • cargo build --features qemu
  • cargo test-config
  • cargo test-lib
  • cargo check --manifest-path tools/remote-session-client/Cargo.toml --target x86_64-unknown-linux-gnu
  • cargo test --manifest-path tools/remote-session-client/Cargo.toml --target x86_64-unknown-linux-gnu
  • cargo build-demos-capos
  • make run-remote-session-capset-interop
  • make run-remote-session-adventure-interop (required when the iteration changes demos/remote-session-adventure-worker/, system-remote-session-adventure-interop.cue, or any Adventure remote call shape; the capset interop target alone covers Adventure denial, not the positive Adventure path)
  • make run-remote-session-capset-ui

Success Criteria

Each landed iteration must keep both run-remote-session-capset-interop and run-remote-session-capset-ui green, ship one or more of the directions listed below, and refresh WORKPLAN.md’s remote-session ad-hoc bullet to record what is now landed and what is still planned.

Task 1: Standard capnp-rpc transport and object proxy layer

  • Replace the schema-framed bespoke transport with the standard capnp-rpc proxy layer for at least one service surface (chat or Adventure). Keep the kernel-side service the same; the change is in the host backend and DTO bindings.
  • Prove the new transport with run-remote-session-capset-interop and a host-side test in tools/remote-session-client/. Record the transition in docs/proposals/remote-session-capset-client-proposal.md.
  • Document any temporary dual-stack period in docs/backlog/remote-session-capset-client.md so a follow-up plan iteration removes the bespoke path.

Task 2: Transport lifetime and exception behavior

  • Cover gateway disconnect, half-open transport, and exception paths end-to-end. Each path must produce a redacted denial in the transcript and clean state in the backend.
  • Add focused interop assertions for connection-close logout, gateway logout propagation, and post-logout call rejection. Keep session-lifecycle kernel changes out of scope; reuse the existing live/logged_out cells.
  • Record the resulting contract in docs/proposals/remote-session-capset-client-proposal.md so the future capnp-rpc rewrite preserves it.

Task 3: Auth adapter expansion (guest admission included)

  • Add at least one new auth adapter beyond password login, e.g. guest admission with explicit profile mismatch denial, or a stub passkey adapter that exercises the broker without requiring durable storage.
  • Cover the new adapter with the existing CLI/QEMU denial proofs (inactive accounts, unknown principals, missing or retired resource profiles, profile mismatch) and the redacted-transcript export.
  • Update the broker DTO surface, not the kernel session_manager. If the broker exposes new metadata, gate it behind explicit subject disclosure as required by docs/backlog/session-bound-invocation-context.md.

Task 4: Resource and revocation bounds

  • Add explicit per-session bounds on outstanding worker calls, transcript size, gateway connections per principal, and backend-side cap holders. Surface bound exhaustion as a denial, never as a panic.
  • Add focused interop assertions exercising each bound at boundary and over-boundary.
  • Note bound choices in docs/proposals/remote-session-capset-client-proposal.md and docs/backlog/remote-session-capset-client.md so future operators can tune them safely.

Task 5: Richer service clients

  • Add at least one richer service client beyond chat/Adventure. Good candidates: a SystemInfo/MOTD/help/manpage view, a session summary diff, or a service-catalog filter. Landed as the session-summary diff helper in tools/remote-session-client/src/session_diff.rs.
  • Keep browser JavaScript on view models only; richer clients live in the Rust backend. The trusted Rust web bridge holds the raw (SessionInfoSummary, Vec<CapInfo>) snapshots; browser JavaScript receives only the redacted SessionSummaryDiffVm shape (added / removed cap entries by (name, interfaceIdHex), policy/lease changes, redacted session-id changes, and a summary string).
  • Add a corresponding focused proof in run-remote-session-capset-ui and document the new client in docs/proposals/remote-session-capset-client-proposal.md. The browser smoke now clicks the new “Refresh & Show Diff” button twice per session: the first click reports hasBaseline=false while the second click reports a populated diff payload with hasBaseline=true. Two backend host tests cover the baseline + no-change path and the added-cap + expiry-change path.

Task 6: Paperclips launch slice

  • Coordinate with the Paperclips Showcase plan’s Task 4 DTO surface. When that surface is reviewed, wire the remote-session worker and browser bridge to launch and drive Paperclips through the same DTO/service-runner profile path that already drives Adventure.
  • Prove the launch slice with run-remote-session-capset-ui, including a redacted transcript and visible-button automation, and keep raw browser-held capOS caps off the path.
  • Record the milestone in WORKPLAN.md and docs/changelog.md.