Runtime, Networking, And Shell Backlog
Detailed decompositions for runtime, networking, shell, agent, and web shell
work. docs/tasks/README.md links here but should not inline these subtasks.
Scheduler/Park Measurement
Pre-thread dispatch instrumentation and compact-vs-generic ParkBench comparison are historical context. In-process threading later closed the first blocked/resume measurement path with QEMU samples for private ParkSpace wait/wake. Future measurement work should be tied to a concrete runtime or SMP change, especially per-thread/per-CPU ring behavior.
In-Process Threading Implementation
Current implementation subgates recorded in the old workplan were all marked
complete, but the parent task still appeared unchecked. Before starting
follow-up work, reconcile this status against code, docs/roadmap.md, and
docs/changelog.md.
Completed subgates retained for context:
- Add
Threadstate with per-thread kernel stack, registers, and FS base. - Change scheduling from process-level to thread-level while preserving process-owned address spaces and cap tables.
- Add
ThreadSpawner/ThreadHandleand basic join/exit smoke. - Implement the first park authority capability and contended-path measurements.
Runtime Ring Reactor Bridge
The current kernel ABI still exposes one process-owned capability ring. A multithreaded runtime therefore needs a compatibility bridge until per-thread kernel rings land.
Ordered gates:
- Add one runtime-owned process-ring CQ drainer.
- Map
user_datacompletions back to ParkSpace-backed per-thread wait records. - Prove sibling threads can issue ordinary calls and receive out-of-order completions without both draining the process CQ.
- Retire the bridge when per-thread capability rings and completion routing
by generation-checked
ThreadRefbecome the kernel ABI.
Telnet Shell Demo
Historical, fully retired track (2026-06-10). The visible outcome below was
delivered and later retired together with the qemu-only kernel TCP listener
and socket owner: make run-telnet and its sibling kernel-socket smokes now
exit with retirement diagnostics, the telnet-gateway /
ssh-gateway-terminal-host / network-client demos and their manifests are
removed, the kernel SocketTerminalSession is deleted, and
TcpSocket.intoTerminalSession fails closed in every dispatch path. Remote
shell access belongs to the in-guest login surface (web UI over the Phase C
userspace network stack) and the future SSH Shell Gateway
(docs/proposals/ssh-shell-proposal.md); a network-backed TerminalSession
must be re-built as a userspace terminal-session service over the userspace
TCP stack if a byte-stream terminal transport is needed again.
Original visible outcome: make run-telnet boots capOS in QEMU with
hostfwd=tcp:127.0.0.1:2323-:23, a telnet-gateway boot service listens on
guest port 23 through the kernel TCP capability surface, and a scripted host
smoke runs telnet 127.0.0.1 2323, logs in through the existing credential
flow, issues one shell command, and sees a clean disconnect.
Ordered gates:
- Add the Phase B TCP interfaces to the canonical shared schema:
NetworkManager,TcpListener, andTcpSocket. Keep this milestone TCP-only;UdpSocket,DeviceMmio,DMAPool, andInterruptare decomposed-NIC / userspace-driver scope. - Replace the synthetic 10 ms smoltcp clock with scheduler-driven polling
on real
TICK_COUNT; the HTTP proof now persists as a retained smoltcp runtime polled from scheduler ticks. Depends onTimer. - Close the delegated endpoint relabeling gap before exposing shell launch
over Telnet. A remote shell user must not be able to type an arbitrary
endpoint identity such as
badge 200and spawn a child that acts as a different chat/adventure participant. Omitted shell syntax now preserves the delegated source identity, and the low-level spawn hardening proof keeps the legacy badge-zero encoding covered. The containment gates indocs/backlog/stage-6-capability-semantics.mdare complete; do not expose Telnet shell launch to any future badge-selection regression. Normal shell help and smoke-help expectations no longer advertise badge syntax. - Implement
NetworkManager,TcpListener, andTcpSocketas kernelCapObjects wrapping the existing smoltcp smoke path. Reuse ring dispatch; do not add syscalls.acceptandrecvmay be blocking calls for this milestone, with bounded result buffers and explicit close behavior. Initial implementation landed in commit7446e04at2026-04-25 14:48 UTC; follow-up review fixes removed timer-path allocation from deferred completion, hardened result-cap cleanup, and addedmake qemu-network-client-harnesscoverage for userspaceNetworkManagerClient,TcpListenerClient.accept, andTcpSocketClientsend/recv/close. - Complete the next endpoint-identity containment transition before unrelated Telnet gateway work: Gate 1 representation plus the minimum trusted mint path landed as the historical service-object routing proof. The selected follow-on is now Session-Bound Invocation Context: keep production remote shell launch blocked until one-session-per-process, privacy-preserving endpoint caller-session metadata, and shared-service migration settle.
- Add the socket-backed terminal handoff needed by the demo.
capos-shellmust still receive a cap namedterminalwithTerminalSessioninterface id, backed by the accepted TCP socket. Do not pass rawTcpSocket,ByteStream, orStdIOas a replacement for the login terminal boundary. Satisfy this either by adding typed service-export / grant support so a userspacetelnet-gatewayendpoint can be presented as aTerminalSession, or by implementing a real kernel socket-backedTerminalSessionCapObject. Implemented asTcpSocket.intoTerminalSession, which consumed a connected socket cap and returned a move-onlyTerminalSessionresult cap, backed by the kernelSocketTerminalSessioncooked-mode line-discipline shim. Retired 2026-06-10: the kernel socket owner behind it was removed by the Phase C userspace network-stack migration, so the shim and its handoff were deleted;TcpSocket.intoTerminalSessionnow fails closed with a retirement error in every dispatch path, and the consumer smokes (qemu-network-client-harness,run-telnet,run-ssh-gateway-terminal-host) exit with retirement diagnostics. - Add a
telnet-gatewaydemo binary andsystem-telnet.cuemanifest. The trusted demo gateway gets bootstrapNetworkManagerandProcessSpawnerauthority, plus pass-throughcreds,sessions,audit, andbrokercaps needed to spawncapos-shellwith the same login/session semantics as the UART shell. The spawned shell must not receive raw network or broad process-spawn authority. - Add
make run-telnetand a scriptedqemu-telnet-harnesshost smoke that drives the full login/command/exit sequence and requires a proof line. - Document in
docs/proposals/networking-proposal.mdanddocs/proposals/shell-proposal.mdthat telnet is demo-only plaintext, binds only to host loopback in the QEMU harness, preserves theTerminalSessionboundary, and will be replaced by the SSH gateway once host-key, user-key, account, audit, and persistence prerequisites land. Implemented by branch commit5d11b12at2026-04-25 20:06 UTC.make qemu-telnet-harnessproves127.0.0.1:2323 -> guest :23, password login,caps, thesessioncommand, and clean exit with no password, rawNetworkManager, rawProcessSpawner, raw TCP, or unknown-cap leakage in the host transcript. Replacing the gateway’s factory network/spawn authority with scoped listener and shell-launch caps is tracked in task records; it is not required for the host-local visible demo.
Telnet Over TLS Optional Track
Telnet over TLS is not a default main access interface. Keep it as an optional future transport for service terminals or certificate-heavy deployments after the certificate/TLS, durable identity, session lifecycle, audit, and scoped listener-authority prerequisites exist. SSH remains the main production operator CLI track, and WebShellGateway remains the main browser/agent access track.
Ordered gates before this can be considered production-shaped:
- Certificate/TLS server configuration, private-key custody, trust-store, and rotation primitives exist outside the kernel TCB.
- Client identity maps through durable account/session policy, preferably mTLS client certificates with password fallback only by explicit policy.
- Session lifecycle close propagation exists for terminal disconnect, process-tree exit, explicit logout, and administrator revocation.
- The gateway receives only scoped listener, TLS config, terminal-factory, session, broker, audit, and restricted-launch grants; no raw broad network or process-spawner authority.
- QEMU and host-network harnesses prove TLS handshake, failed client-auth behavior, terminal login, disconnect cleanup, and transcript redaction.
Remote Session CapSet Clients
Programmatic and GUI remote clients are a sibling track to terminal shells. A
regular host app – CLI, native GUI, Tauri backend, webapp gateway, desktop
tool, service client, or agent runner – should authenticate through the capOS
session/admission path, obtain a broker-issued remote CapSet view in its
trusted backend, and call provided capabilities over Cap’n Proto RPC. It should
not be forced to spawn capos-shell, and it should not be reduced to a
special-purpose chat proxy.
The first implementation slice exposes this path as a host-local development
endpoint. Default make run starts remote-session-capset-gateway and forwards
guest port 2327 to a loopback host port, preferring 127.0.0.1:2327 while
falling back to a free port when another QEMU run is already using it. The
focused make run-remote-session-capset-interop harness runs the Linux Rust
client, authenticates through SessionManager, lists a broker-shaped remote
CapSet, calls session/system-info DTO operations, and proves denial/stale
paths. This slice uses schema-framed Cap’n Proto DTOs; standard capnp-rpc
proxy transport and endpoint-backed service calls remain the next gates.
Detailed decomposition lives in Remote Session CapSet Client. Keep this track coordinated with SSH/WebShell work:
- SSH remains the production operator CLI terminal transport.
- WebShellGateway remains the browser/agent terminal and tool-proxy surface.
- Remote session CapSet clients are the programmatic and UI API surface for Linux host tools, desktop/Tauri apps, webapp gateways, service clients, and server-side agent runners.
- Optional UI-composition caps let capOS-side services and agents propose bounded panes, command palettes, visualizations, layout hints, and theme tokens through host-validated surfaces instead of treating “remote GUI” as only a window or terminal frame.
- All three paths consume the same
SessionManagerandAuthorityBrokermodel and must support non-password admission methods where policy enables them. - Browser JavaScript and model providers must not receive raw capOS caps; gateway-side workers hold the session CapSet and expose only terminal frames, command metadata, or bounded tool requests.
SSH Shell Gateway
Visible outcome: make run-ssh-shell boots capOS in QEMU with a host-local
forward to guest SSH, an ssh-gateway service authenticates a normal OpenSSH
client with a configured public key, launches capos-shell with an
SSH-backed TerminalSession, runs one shell command, and disconnects cleanly.
The shell must see the same terminal/session/broker boundary as the Telnet
demo, not raw TCP or SSH protocol authority.
Blocked by: Telnet Shell Demo for socket-backed TerminalSession,
cryptography/key-management for sign-only host keys, local account/key records
for authorized SSH keys, audit records for remote authentication decisions,
and persistent storage before production host or authorized keys are treated
as durable.
Closeout prerequisite: before this milestone closes, reconcile its target
name and host-harness placement with the run-target/init-mandate policy in
docs/backlog/run-targets-and-init-policy.md (Gate A naming split, Gate B
init mandate, Gate C test split, Gate D default-make run integration).
The current make run-ssh-shell working name and any scripted host harness
may need to become test-ssh-shell and be relocated, and default-run
exposure has to be addressed there, not as another run-ssh-* recipe.
Ordered gates:
- Document the first SSH gateway contract in
docs/proposals/ssh-shell-proposal.md: gateway authority, host-key custody, authorized-key mapping, accepted channel set, denied SSH features, terminal handoff, audit, resource limits, and teardown. - Close or explicitly preserve the scoped gateway authority gap for SSH
before implementation: the gateway must receive a manifest-declared
scoped listener or listener factory for only the configured SSH port, and
the spawned shell must receive no raw
NetworkManager,TcpListener,TcpSocket, or transport protocol authority. A temporary host-local demo compromise must stay documented in a task record and the harness must prove the child boundary withcaps. - [x] Scoped listener authority sub-slice:tcp_listen_authoritymanifest grants use the cap badge as a validated TCP port and mint a one-shotTcpListenAuthoritythat can create only that listener;make run-tcp-listen-authorityproves generic init can forward the scoped cap to a child without rawNetworkManager. - Terminal-host wiring sub-slice:
ssh-gateway-terminal-hostused manifest-scopedTcpListenAuthorityon the SSH development port andRestrictedShellLauncherto hand a socket-backedTerminalSessiontocapos-shellwhile proving the child lacked raw network, TCP, spawn, key-store, host-key, SSH gateway, terminal-factory, and launcher authority. This closed the scoped gateway authority gap for the bounded host-local proof. The demo and its smoke were retired 2026-06-10 with the kernel socket owner andSocketTerminalSession; the final OpenSSH transport must be rebuilt as a terminal host over the userspace network stack. - Add manifest-declared shell launch authority for the gateway. Prefer a
shell-only launcher or supervisor grant that can start only
capos-shellwith reviewed pass-through caps; do not grant broadProcessSpawnerauthority to the SSH gateway unless it is explicitly recorded as a host-local development compromise. - [x] Restricted shell launcher sub-slice:restricted_shell_launchermanifest grants forward an init-heldRestrictedShellLaunchercap to a child service.make run-restricted-shell-launcherproves the child service has no rawProcessSpawner,launchShellhas no binary selector and launches onlycapos-shell, session/profile mismatch and dangerous grant attempts fail closed, and the spawned shell uses the supplied session while lacking raw network, TCP, host-key, authorized-key-store, SSH gateway, and restricted-shell-launcher authority. - Add schema/design stubs for the minimum SSH support objects:
SshGatewayor equivalent service contract, sign-onlySshHostKeywrapper around aKeyVault/PrivateKey,AuthorizedKeyStore, and SSH-backedTerminalSessionconstruction. Do not expose private-key bytes, raw authorized-key storage, or vault administration to the spawned shell. Implemented as schema/type-surface stubs forSshGateway,SshHostKey,AuthorizedKeyStore,SshTerminalFactory,TcpListenAuthority, andRestrictedShellLauncher; no bootable kernel or userspace implementation is implied by this gate. - Add a development host-key path. Manifest-seeded keys may be used only
for QEMU proof and must be labeled non-production; production host keys
require the key-management and storage path. Implemented as
kernelParams.sshDevelopmentHostKeyplus the narrowssh_development_host_keykernel source. The focused proof ismake run-ssh-host-key; the development cap signs boundedssh-ed25519exchange hashes from the manifest seed, verifies against the configured public key in QEMU, denies wrong algorithms, and remains explicitly non-production. Persistent production host-key storage, rotation, and key management remain future work. - Add public-key user authentication. Accepted SSH keys map to principals
and allowed shell profiles;
SessionManagermints the session only after signature verification, andAuthorityBrokerstill decides the actual shell bundle. - [x] Public-key session bridge sub-slice:SessionManager.sshPublicKeychecks a configuredAuthorizedKeyStorerecord plus bounded fixture auth bytes/signature, mints aUserSessionwith the accepted principal/profile andpublicKeyauth strength, andmake run-ssh-public-key-authproves unknown, disabled, unsupported, and bad-signature paths fail closed before broker bundle minting. This is not full SSH transport authentication or shell launch wiring. - [x] AccountStore-bound session sub-slice:SessionManager.sshPublicKeyconsults the bootstrapRamAccountStoreafter signature verification (lookup_by_principal), so non-Activeaccount statuses (Disabled, Locked, RecoveryOnly) and missing principals fail closed before a session is minted. Each denial cause maps to a stable, principal-blankedauth=audit code (ssh-key-unknown,ssh-key-disabled,ssh-key-profile-not-allowed,ssh-bad-signature,ssh-account-missing,ssh-account-disabled,ssh-account-locked,ssh-account-recovery-only,ssh-account-lookup-failed,ssh-profile-kind-invalid,ssh-profile-not-interactive,ssh-auth-bytes-invalid).make run-ssh-public-key-authcovers the non-account-status codes; thessh-account-*codes need anAccountStoreManagerCapkernel cap source for runtime-mutated QEMU proofs (tracked indocs/backlog/local-users-management.mdGate 2). - Reject unsupported SSH features with protocol failures and audit reason
codes: password auth when disabled,
exec, SFTP/subsystems, port forwarding, agent forwarding, X11 forwarding, arbitrary environment import, and multiple active shell channels. - [x] Policy-surface sub-slice:capos-config::ssh_policyreturns allowed/denied decisions, SSH protocol failure classes, and stable audit reason codes for the narrow allowed path and the denied feature set, including second session-channel opens before any shell request. Password auth remains fail-closed until a real verifier/backoff path is part of the gateway policy.make run-ssh-feature-policyproves the table in QEMU. The full gateway item remains open until this policy is invoked byssh-gateway. - Implement the gateway as a terminal host. It owns SSH packet/channel
state and gives
capos-shellonly a cap namedterminalplus the normal scoped launch grants. The child must not receive raw network, host-key, authorized-key-store, key-vault, or broad spawn authority. - [x] Bounded terminal-host wiring sub-slice (retired 2026-06-10 with the kernel socket owner andSocketTerminalSession; the smoke now exits with a retirement diagnostic and a future terminal host must target the userspace network stack):make run-ssh-gateway-terminal-hostproved a generic-init child service can combine scopedTcpListenAuthority,AuthorizedKeyStore,SessionManager,AuthorityBroker, andRestrictedShellLaunchergrants to deny an unknown key, mint apublicKeysession from a configured key, reject a mismatched broker profile, accept the matching broker profile, convert one host-local TCP socket into aTerminalSession, and launchcapos-shellwithout giving the shell raw network, process-spawner, TCP listener/socket, host-key, authorized-key-store, SSH gateway, SSH terminal-factory, or restricted-shell-launcher authority. The proof keeps the listener service-live across shell exits, proves a second host TCP connection succeeds, and externally stops QEMU through the harness pidfile instead of treating service exit as success. This remains a bounded plain-TCP proof and does not complete full SSH packet/channel ownership or the OpenSSH harness gate. - Add
system-ssh-shell.cue,make run-ssh-shell, and a host harness usingsshagainst the forwarded port. The harness must prove one successful public-key login, one shell command, clean exit, unknown-key denial, disabled-password denial, denied forwarding/subsystem requests, and cleanup after client disconnect. - [ ] OpenSSH version-exchange slice: add a realssh-gatewayservice andsystem-ssh-shell.cueskeleton that accepts one host-local OpenSSH TCP connection, exchanges RFC 4253 identification strings, records the client software/version in bounded audit/proof output, and disconnects before key exchange without launching a shell. The normal compatibility harness should use/usr/bin/ssh; a separate low-level hostile TCP/banner fixture should prove malformed banners plus overlong identification strings fail closed. - [ ] KEXINIT and algorithm-selection slice: parse the unencrypted KEXINIT binary-packet exchange far enough to negotiate a pinned development algorithm set, reject unsupported algorithms with SSH disconnects, and keep the negotiated algorithm names out of any authority decision. The initial reviewed set should be exactly one modern KEX,ssh-ed25519host keys, one AEAD cipher/MAC pair, andnonecompression until rekey and broader algorithm policy exist. - [ ] Development key-exchange slice: complete the negotiated KEX, derive traffic keys from the shared secret, exchange hash, and session id per RFC 4253, callSshHostKey.signExchangeHashfor the SSH exchange hash, and complete the OpenSSH handshake without exposing private host-key bytes or raw entropy to the gateway’s child shell. Entropy is input for ephemeral KEX material, padding, and challenges; this remains non-production until host keys are durable and the entropy source has a reviewed production-quality policy. - [ ] OpenSSH public-key userauth slice: bind the OpenSSH userauth transcript toSessionManager.sshPublicKeyso the accepted key maps to the configured principal/profile, unknown keys are denied generically, and disabled password auth returns the expected SSH failure without invokingCredentialStore. - [ ] Channel policy slice: invokecapos-config::ssh_policyfor session-channel open, PTY, window-change, shell, exec, subsystem, forwarding, agent, X11, environment, and second-channel requests. The harness must prove the allowed shell path plus the denied feature requests with protocol-visible failures and sanitized audit reason codes. - [ ] SSH terminal launch slice: replace the plain-TCP terminal-host driver with the SSH channel-backed terminal path, launchcapos-shellthroughRestrictedShellLauncher, runsession,caps, andexitover OpenSSH, and prove disconnect cleanup for both client-close-before-shell and shell-exit-before-client-close. - Update
docs/proposals/shell-proposal.md,docs/proposals/boot-to-shell-proposal.md,docs/security/trust-boundaries.md, anddocs/proposals/index.mdwhen implementation begins so remote SSH login policy, terminal authority, and audit records stay aligned with the code.
Decomposed NIC Milestone
Move the NIC driver and TCP/IP stack out of the kernel into dedicated
userspace processes after the Telnet Shell Demo made the socket interfaces
capability-shaped. The Phase C userspace NIC driver and smoltcp network-stack
process have since landed and own the production socket path; make run-telnet and the other kernel-socket consumer smokes are retired rather
than preserved end-to-end, because the qemu-only kernel TCP listener and
socket owner were removed with that migration.
- Define first
DeviceMmio,DMAPool, andInterruptschemas (landed with the DDF capability surface). - Move virtio-net ownership into a userspace driver process holding only
DeviceMmio,Interrupt, andDMAPoolcaps (Phase C userspace NIC driver slices). - Split smoltcp into a separate userspace network-stack process that holds
the
Niccap from the driver and re-exports the Phase B socket interfaces (Phase C userspace network-stack process). - The kernel no longer depends on
smoltcp, and the userspace network-stack process re-exports the socket interfaces. Themake run-telnetend-to-end confirmation was retired instead of re-proven: the gateway demos sat on the removed kernel socket owner, and remote-shell coverage moved to the in-guest login surface and the future SSH gateway over the userspace stack.
Agent Shell / Agent Runner
The native shell’s agent mode must land before exposing the shell through a browser. The shell remains the trusted runner and session-cap holder. The model service receives prompts and returns structured tool calls, but never receives session caps, terminal caps, launcher authority, raw tokens, or secrets. Use a deterministic test model for the first proof.
Visible outcome: make run-agent-shell boots capOS in QEMU, grants
capos-shell a broker-issued LanguageModel cap plus per-tool permission map,
enters agent mode, exposes the current session bundle as typed tool
descriptors, executes one read-only tool call automatically, requires consent
or step-up for a mutating/admin-shaped call, handles user cancellation, and
records redacted audit output.
Ordered gates:
- Add the first agent-runner schema/interfaces:
LanguageModel,ModelInfo,ToolDescriptor,ToolCall,ToolResult, permission mode metadata, and bounded streaming/cancel semantics. Keep tool calls structured; do not parse model text as shell commands. - Extend
AuthorityBrokersession profiles so an operator shell can receive aLanguageModelcap and a per-tool permission map without receiving model-admin, model-catalog, or provider-token authority. - Add a deterministic in-tree
LanguageModeltest service that emits scripted tool calls for QEMU proofs. Do not block this milestone on large local model weights, remote providers, GPU, or storage. - Implement native shell agent mode: build the tool table from granted
session caps and schema metadata, stream model turns, gate each tool call
through
auto/consent/stepUp/forbidden, invoke only the capabilities held by the shell runner, and feed outcomes back into the loop. - Wire consent, step-up, cancellation, timeout, quota, and audit behavior. User interrupts beat model momentum; denied or cancelled tool calls become ordinary tool outcomes instead of hidden control flow.
- Add
make run-agent-shelland a scripted QEMU harness that proves read-only auto execution, denied forbidden/admin tool exposure, one consent or step-up prompt, cancellation, and redacted audit records. - Update
docs/proposals/llm-and-agent-proposal.md,docs/proposals/shell-proposal.md, anddocs/tasks/README.mdto record that WebShellGateway hosts this agent-capable shell/runner instead of defining a separate browser-side agent authority model.
WebShellGateway
Add the browser-hosted terminal and authentication gateway after both remote
TerminalSession proof and agent shell are in place. The gateway owns
HTTP/WebSocket or equivalent transport, TLS/origin/RP-ID validation, WebAuthn
challenge/response, terminal rendering, and session teardown. It launches the
same agent-capable native shell with the same broker-issued session profile.
Blocked by: Telnet Shell Demo for socket-backed TerminalSession, Agent
Shell / Agent Runner, passkey challenge/credential support in auth/session
services, and TLS/origin/RP-ID policy. OIDC is a follow-up path on the same
gateway, not a prerequisite for the first WebAuthn shell.
Visible outcome: make run-webshell boots capOS in QEMU with host-local
forwarding to the web gateway, a headless browser harness opens the terminal
UI with a virtual WebAuthn authenticator, authenticates, runs one shell or
agent command, logs out or closes the tab, and verifies clean
shell/process/session teardown plus a recorded transcript/proof line.
Ordered gates:
- Define the web terminal stream protocol over WebSocket or an equivalent browser transport: input, output, resize, paste, close, cancellation, flow control, session IDs, and bounded buffering.
- Add WebAuthn/passkey credential and challenge support: public-credential records, single-use bounded challenges, entropy fail-closed behavior, origin/RP-ID binding, user-presence/user-verification policy, sign-count handling, rate limiting, and redacted audit events.
- Add TLS and browser origin policy for QEMU and deployment modes. The first harness may use a local development trust path, but the gateway must have explicit Host/Origin/RP-ID checks and no production plaintext mode.
- Implement
WebShellGatewayas a terminal host service: accept browser sessions, authenticate, request the narrow shell/agent bundle fromAuthorityBroker, create or wrap a web-backedTerminalSession, spawncapos-shell, proxy terminal events, and release all session resources on logout, tab close, timeout, or shell exit. - Add
system-webshell.cueand manifest/grant wiring. The gateway gets only listen/TLS/auth/session/broker/restricted-launch grants needed for the job; the spawned shell does not receive raw network, raw auth material, model-provider tokens, or broad process-spawn authority. - Add
make run-webshellandqemu-webshell-harnesswith a headless browser virtual authenticator, transcript capture, login/command proof, logout/close proof, and assertions that failed auth and stale browser sessions do not leave a live shell. - Add optional OIDC authorization-code + PKCE login on the same gateway
after the OAuth/OIDC service exists. ID-token verification and
acr/amrmapping feedSessionManager/AuthorityBroker; raw tokens do not enter the shell or browser terminal transcript. - Update
docs/proposals/boot-to-shell-proposal.md,docs/proposals/shell-proposal.md,docs/proposals/llm-and-agent-proposal.md, and security trust-boundary docs with WebShellGateway authority, auth, terminal, audit, and teardown rules.