# 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:
- [x] MVP `Chat` endpoint interface and event variants. The original
      receiver-selector identity MVP has since been replaced by
      service-scoped caller-session keys for normal chat membership.
- [x] Public chat lobby stays `#lobby`; adventure room speech uses
      hierarchical `#room/<world>/<room>` channels, with the demo world under
      `#room/demo/<room>`.
- [x] Client `poll()` is used for MVP event delivery; foreground client drains
      queued events before prompting again.
- [x] `demos/chat-server/` scaffold with capos-rt entry and bounded
      per-channel history ring.
- [x] `join`/`leave`/`send`/`who` plus fan-out for the legacy endpoint-metadata
      MVP.
- [x] `demos/chat-client/` over explicit capos-rt `StdIO` plus chat endpoint
      client.
- [x] Chat stays out of native shell builtins and runs as a spawned command
      with omitted-badge `stdio: client @stdio` and `chat: client @chat`
      grants.
- [x] `make run-chat` smoke: shell-spawned client sends a line through the
      resident service, resident bot observes it and replies, foreground
      client prints the reply.

Remaining:
- [x] Migrate chat from legacy endpoint receiver-metadata identity to
      service-scoped caller-session keys. `ChatRoot` possession 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 `Subscription` interface until federation or native
      command surfaces need a separate event authority object.

Client-server interface sync audit (2026-05-03 19:02 UTC):
- [x] Walk the recent chat-server interface and behavior changes against the
      demo chat clients to confirm no drift. Audit covered six commits
      (`5dc0e8ca` `/exit` banner alignment, `e7d0e00d` `[history]` text label
      plus `EventKind::History`, `45384fa0` server-assigned `member-N` sender
      labels in place of the caller-supplied join handle, `7bb90528`
      idempotent re-join, `dc7ece49` membership keyed by caller session, and
      `f5eab276` `EndpointUserData` rename) and confirmed
      `demos/chat-client/`, `demos/capos-chat/`, `demos/chat-bot/`, and
      `demos/chat-observer/` already track each one. The chat-client banner
      lists `/exit` and accepts both `/exit` and `/quit`; `ChatEventKind`
      decodes all five schema variants and renders the server's
      `[history] <text>` prefix verbatim while the chat-observer reports
      `kind=history` vs `kind=live` separately; `event.sender` is always
      taken from the server response so server-assigned member labels are
      shown without modification; re-join goes through `leave_wait` followed
      by `join_wait` with no stale "already joined" assertion; chat-server
      session keying and the neutral endpoint user-data name are entirely
      server-side. Verified live with `make 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
      `/exit` banner, server-assigned `member-N` labels, and pass-through of
      message text all behave as expected. The `[history]` label path is
      not exercised by `make run-chat` (chat smoke joins fresh) but is
      covered by `make run-adventure` via
      `assert_adventure_npc_chat_history_actor` in `tools/qemu-shell-smoke.sh`.
- [x] Latent `demos/chat-bot/` self-echo filter resolved in `7b9c5993` by
      skipping `ChatEventKind::History` events so replayed `[history] [chat-bot] ...`
      messages no longer slip past the prefix-only check.

## Adventure Follow-Ups

Completed context:
- [x] MVP `Adventure` interface for non-speech verbs and room views.
- [x] Legacy receiver-selector layout distinguishes player from NPC authority
      on both a future `PlayerSession` and room chat channels. MVP manifests
      reserve low selectors for shell players (`chat=1`, `adventure=2`) and
      service/NPC authority at `100+`.
- [x] Rooms map to chat channels as `#room/<world>/<room-id>`, with the demo
      world under `demo`.
- [x] `demos/adventure-server/` scaffold with a small room graph, typed world
      verbs, live caller-session keyed player state, and chat channel metadata.
- [x] `demos/adventure-client/` as a spawned command over explicit `StdIO`,
      `adventure`, and `chat` endpoint grants.
- [x] Adventure `StdIO` parser remains prototype-scoped and should later be
      replaced with a command surface exposing nested paths such as `go`,
      `take`, `drop`, `inventory`, `say`, and `chat join`.
- [x] `make run-adventure` smoke: scripted player moves rooms, completes one
      state-changing world action, and exits cleanly through the shell-spawned
      client.
- [x] NPC-as-process fleet: one process per NPC, each holding manifest-issued
      legacy player/adventure receiver metadata plus chat endpoint authority
      for room dialog.
- [x] At least two concrete NPCs ship with liveness asserted in the adventure
      smoke.
- [x] NPC process exit surfaces as `ProcessHandle` completion on the server
      side.

Game-depth follow-up:
- [x] Decompose the Aurelian Frontier proposal through
      `docs/backlog/aurelian-frontier.md` rather than expanding this shared
      service harness backlog with content, combat, economy, and multiplayer
      details.

Session-bound identity follow-up:
- [x] 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:
- [x] Extract duplicated legacy endpoint receive/release/return loop used by
      chat and adventure resident services into `demos/service-common/`.
- [x] Defer a shared bounded event queue until chat history/inbox and
      adventure/NPC event needs converge. Current evidence: only
      `chat-server` has bounded history/inbox queues; adventure room state and
      NPC polling do not expose a matching queue abstraction.
- [x] Extract bot/NPC client scaffolding shared by chat bot and adventure NPC
      processes.
- [x] 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.
- [x] Extract shared chat actor bootstrap for required `console` and `chat`
      caps 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.
