Shared-Service Demo Backlog
Detailed decompositions and design notes for chat, adventure, and federated
service demos. docs/tasks/README.md links here but should not inline these subtasks.
Design Notes
Multi-process userspace applications exercise the resident-server plus
shell-spawned-client pattern on top of the completed boot-to-shell, Endpoint,
ProcessSpawner, and session-bound invocation substrate. Chat has migrated to
service-scoped caller-session identity, and Aurelian ordinary player state is
also keyed by live caller-session metadata. The focused text adventure manifest
uses session-bound service grants for player, NPC, Adventure, and chat paths.
Reuse is extracted after the second service lands, not speculatively.
Federation is blocked on future
network-transparency proof work.
The authoritative migration gates for removing caller-selected shared-service
identity now live in docs/backlog/session-bound-invocation-context.md under
Gate 4. The older service-object migration backlog is historical background
only unless the selected milestone changes again.
The first slice keeps chat and adventure usable as ordinary spawned commands
over generic Endpoint grants plus explicit StdIO for terminal I/O. The
shared demos/capos-chat crate owns typed request/response DTOs for the
prototype bridge, while the top-level shell/ crate owns generic process
commands such as spawn, blocking run, wait, and grant parsing. The
StdIO clients are a smoke harness and compatibility path, not the target
capOS-native command boundary; native interactive apps should later expose
command surfaces as described in
docs/proposals/interactive-command-surface-proposal.md.
Room-scoped MUD speech (say, tell) maps naturally onto chat channels, so
adventure should consume the chat service rather than reimplementing pub/sub.
Keep the Adventure schema for world state and verbs that are not speech;
route say/tell/NPC dialog through Chat subscriptions scoped to room
channels.
Chat Follow-Ups
Completed context:
- MVP
Chatendpoint interface and event variants. The original receiver-selector identity MVP has since been replaced by service-scoped caller-session keys for normal chat membership. - Public chat lobby stays
#lobby; adventure room speech uses hierarchical#room/<world>/<room>channels, with the demo world under#room/demo/<room>. - Client
poll()is used for MVP event delivery; foreground client drains queued events before prompting again. -
demos/chat-server/scaffold with capos-rt entry and bounded per-channel history ring. -
join/leave/send/whoplus fan-out for the legacy endpoint-metadata MVP. -
demos/chat-client/over explicit capos-rtStdIOplus chat endpoint client. - Chat stays out of native shell builtins and runs as a spawned command
with omitted-badge
stdio: client @stdioandchat: client @chatgrants. -
make run-chatsmoke: shell-spawned client sends a line through the resident service, resident bot observes it and replies, foreground client prints the reply.
Remaining:
- Migrate chat from legacy endpoint receiver-metadata identity to
service-scoped caller-session keys.
ChatRootpossession authorizes join attempts; membership, channels, sends, leaves, and polls key off the live opaque caller-session reference instead of a caller-selected selector. - Add per-principal state keyed by
UserSession.info, admin-only verbs, typed denial results, and redacted audit records per join/leave/send. - Defer a distinct
Subscriptioninterface until federation or native command surfaces need a separate event authority object.
Client-server interface sync audit (2026-05-03 19:02 UTC):
- Walk the recent chat-server interface and behavior changes against the
demo chat clients to confirm no drift. Audit covered six commits
(
5dc0e8ca/exitbanner alignment,e7d0e00d[history]text label plusEventKind::History,45384fa0server-assignedmember-Nsender labels in place of the caller-supplied join handle,7bb90528idempotent re-join,dc7ece49membership keyed by caller session, andf5eab276EndpointUserDatarename) and confirmeddemos/chat-client/,demos/capos-chat/,demos/chat-bot/, anddemos/chat-observer/already track each one. The chat-client banner lists/exitand accepts both/exitand/quit;ChatEventKinddecodes all five schema variants and renders the server’s[history] <text>prefix verbatim while the chat-observer reportskind=historyvskind=liveseparately;event.senderis always taken from the server response so server-assigned member labels are shown without modification; re-join goes throughleave_waitfollowed byjoin_waitwith no stale “already joined” assertion; chat-server session keying and the neutral endpoint user-data name are entirely server-side. Verified live withmake run-chat(exit 0): the smoke transcript shows[chat] /join <channel>, /leave, /who, /exit, or plain text,[chat] #lobby <member-2> hello from shell, and[chat] #lobby <member-1> [chat-bot] echo-bot heard you.— i.e. the/exitbanner, server-assignedmember-Nlabels, and pass-through of message text all behave as expected. The[history]label path is not exercised bymake run-chat(chat smoke joins fresh) but is covered bymake run-adventureviaassert_adventure_npc_chat_history_actorintools/qemu-shell-smoke.sh. - Latent
demos/chat-bot/self-echo filter resolved in7b9c5993by skippingChatEventKind::Historyevents so replayed[history] [chat-bot] ...messages no longer slip past the prefix-only check.
Adventure Follow-Ups
Completed context:
- MVP
Adventureinterface for non-speech verbs and room views. - Legacy receiver-selector layout distinguishes player from NPC authority
on both a future
PlayerSessionand room chat channels. MVP manifests reserve low selectors for shell players (chat=1,adventure=2) and service/NPC authority at100+. - Rooms map to chat channels as
#room/<world>/<room-id>, with the demo world underdemo. -
demos/adventure-server/scaffold with a small room graph, typed world verbs, live caller-session keyed player state, and chat channel metadata. -
demos/adventure-client/as a spawned command over explicitStdIO,adventure, andchatendpoint grants. - Adventure
StdIOparser remains prototype-scoped and should later be replaced with a command surface exposing nested paths such asgo,take,drop,inventory,say, andchat join. -
make run-adventuresmoke: scripted player moves rooms, completes one state-changing world action, and exits cleanly through the shell-spawned client. - NPC-as-process fleet: one process per NPC, each holding manifest-issued legacy player/adventure receiver metadata plus chat endpoint authority for room dialog.
- At least two concrete NPCs ship with liveness asserted in the adventure smoke.
- NPC process exit surfaces as
ProcessHandlecompletion on the server side.
Game-depth follow-up:
- Decompose the Aurelian Frontier proposal through
docs/backlog/aurelian-frontier.mdrather than expanding this shared service harness backlog with content, combat, economy, and multiplayer details.
Session-bound identity follow-up:
- Finish adventure NPC and service-authority cleanup for the focused shared-service proof now that ordinary player state is keyed by live caller-session metadata. NPC service authority is broker/manifest-issued rather than caller-chosen, and the focused adventure manifest uses the already session-keyed chat service through ordinary chat authority.
Shared Harness Extraction
Completed context:
- Extract duplicated legacy endpoint receive/release/return loop used by
chat and adventure resident services into
demos/service-common/. - Defer a shared bounded event queue until chat history/inbox and
adventure/NPC event needs converge. Current evidence: only
chat-serverhas bounded history/inbox queues; adventure room state and NPC polling do not expose a matching queue abstraction. - Extract bot/NPC client scaffolding shared by chat bot and adventure NPC processes.
- Extract shared chat actor polling loop used by chat-bot, wanderer, and shopkeeper while keeping each actor’s cap validation, join/greeting, reply text, and exit logging local.
- Extract shared chat actor bootstrap for required
consoleandchatcaps plus the single-owner ring client, while preserving actor-specific failure text and behavior setup.
Federated Chat Milestone
Blocked on future network transparency.
Extend chat across hosts after a separate proof shows cap transport crossing machines. This integration test exercises networking, TLS, OIDC, key-management, and audit proposals together.
- Define cross-host addressing (
@user@host,#room@host) and record it in schema. - First cross-VM channel smoke: two QEMU instances, one message delivered across TLS.
- Federated audit: per-host records plus signed cross-host event trail.