# Aurelian Frontier Backlog

Detailed decomposition for growing the current deterministic mission slice
into the Aurelian Frontier game described in
`docs/proposals/aurelian-frontier-proposal.md`.

This track is **low priority and currently dormant** (deprioritized in
`docs/roadmap.md` under "Game/demo plans ... are deprioritized"). It is a
forward decomposition reservoir, not a landed-history log: completed-phase
milestone chronology lives in `docs/roadmap.md` (the dated Aurelian Phase 9-12
entries) and in git history. This file keeps the forward-looking plan, the
unstarted gates/themes, and one-line orientation for why current shapes exist.
Promote it into `docs/tasks/state.toml` and root task records only when the
selected visible outcome changes to a game-depth milestone.

## Current Baseline

The deterministic Aurelian expedition slice is landed: a shell-spawned
`adventure-client` with explicit `StdIO`/`Adventure`/`Chat` grants drives a
session-keyed `adventure-server` that owns room, inventory, combat, writ,
evidence, and effect state. Typed Adventure methods cover `look`, movement,
inventory, `inspect`, `use`, status, combat, authority verbs, delegation,
`order`, `seal`, `leave`, and the market/repair verbs. The expedition mission
proves `ward-writ`, route evidence, `ward-wraith` combat, delegation, effects,
`eagle-standard` recovery, witness-certified custody, evacuation, gate sealing,
downed-state refusal, and leave cleanup. `adventure-content` owns the pure
deterministic combat/zone/profile foundation and bounded construction-job state.
Inventory/status splits into `Items`, `Writs`, `Relics`, `Marks`, `Evidence`.

Phase-level done/not-done state is encoded in the checkbox lists below; the
dated landed milestones for each phase are in `docs/roadmap.md` and git.

Known limitations (still open):
- Most state-transition/failure text still lives in Rust handlers. Authored
      item, spell, and use text has moved into generated content for the named
      slices; broader text migration is open.
- NPCs that matter to world state are mostly server text, not separate actors
      holding scoped game authority. Aurelian chat-only boot NPCs share init's
      system session under session-bound chat membership, so the smoke proof
      treats them as one session-keyed chat member (all greetings visible,
      Centurion Varro the single deterministic polling reply actor). Distinct
      concurrent NPC chat memberships need distinct spawned session contexts.
- Combat profiles are generated and proven for the current mobs, but broad
      weapon parsing, durable alert groups, pending interruption state,
      generalized stealth openings beyond the imp-scout route slice, and broader
      authority-combat verbs remain open.
- Rank, faction, debrief, market, party, and item-transfer logic are bounded
      proof slices, not durable profile/ledger subsystems. PvP consent and
      two-client multiplayer proofs are not present.
- Construction jobs are bounded to one service-owned field-repair proof. They
      do not yet persist durable stock ledgers, replenish from outposts, update
      output/currency inventories, advance job time, persist crash-recovery
      state, or expose a general crafting API.

## Implementation Posture

The kernel capability model remains the authority boundary. Game code should
not be trusted because it is written in Rust or Lua; it should be trusted only
to the extent that it holds narrow caps and correctly uses typed capOS
interfaces. A useful game demo should eventually show both Rust and Lua code
using the capability model properly.

Rust remains the right implementation language for bounded state, no-std
userspace services, typed Cap'n Proto calls, deterministic QEMU proofs, and
resource validation.

Do not let Rust become the long-term content authoring language. Larger room
graphs, mission beats, item descriptions, dialogue hints, aliases, shop
catalogs, and debrief text should move into a bounded data-driven mission
format before the Aurelian content grows materially.

Keep this split:
- The kernel owns authority enforcement through capabilities, while Rust
      services own simulation rules, combat resolution, object limits, schema
      encoding, and failure behavior.
- Mission content owns room/site data, visible descriptions, actor dialogue,
      aliases, lead text, deterministic encounter placement, and debrief
      records.
- Lua can later own deterministic scenario glue and NPC behavior when the
      `capos-lua` runner exists: mission beats, state-machine dialogue,
      debrief variants, quest-board text, and scripted reactions that still
      call typed capOS/game interfaces through granted caps.
- Runtime loading may stay compile-time embedded at first, but the content must
      pass the same validator used by host tests and QEMU smoke setup.

Candidate content formats:
- CUE plus `mkmanifest cue-to-capnp`: preferred for new schema-rooted data
      messages now that host-side CUE evaluation can feed a caller-specified
      Cap'n Proto struct through the pinned `capnp convert` path.
- RON: compact Rust-native authoring, but adds another format and tooling
      convention.
- TOML: familiar for simple data, weaker for graph validation and nested
      mission rules.

Prefer CUE if the implementation can reuse existing host-side validation and
generate a bounded Rust data blob. Avoid runtime parsing in the game service
until there is a concrete reason.

New Aurelian content migrations should use the `cue-to-capnp` flow when the
data has, or needs, a stable schema boundary:

1. Define a bounded Cap'n Proto root struct for the content slice rather than
   extending `SystemManifest` or encoding ad hoc JSON.
2. Author the source as CUE in package mode, with the same id/text/list bounds
   documented here and with build-time variation supplied through `--tag` or
   `CAPOS_CUE_TAGS` only when the generated output is intentionally tagged.
3. Convert with the pinned tools:

   ```bash
   make cue-ensure capnp-ensure
   CAPOS_CUE="$(make -s cue-path)" \
   CAPOS_CAPNP="$(make -s capnp-path)" \
   cargo run --manifest-path tools/mkmanifest/Cargo.toml --target "$(rustc -vV | awk '/^host:/ {print $2}')" -- \
       cue-to-capnp --package adventure_content --import-path schema \
       demos/adventure-content/content/prototype.cue schema/adventure-content.capnp \
       AdventureContent target/generated-adventure-content.bin
   ```

4. Feed the converted data into the existing host validator/generator or a
   reviewed no-std decode path, then check in only deterministic generated
   artifacts required by the current build.
5. Keep live capOS authority out of content files. Writs, grants, NPC roles,
   and future service references may be represented as ids or policy records,
   but actual capability transfer stays in runtime IPC and service logic.

The existing `tools/adventure-content-gen` JSON-to-Rust path may remain for
already implemented slices. When a new content family needs a schema or a
larger migration touches generator boundaries, prefer moving that family to
`cue-to-capnp` instead of growing bespoke JSON parsing.

## Near-Phase Gates

The first game-depth milestone must produce a player-visible improvement. A
branch that only moves the existing hardcoded room data into a generated blob is
technical prep, not completion of the near phase. The first complete near-phase
slice must keep the current Aurelian expedition mechanically stable while also making
the path discoverable through canonical ids, aliases, lead text, and specific
failure messages.

Legacy endpoint badges are not part of the Aurelian authority model. New
Aurelian phases must keep player, party, NPC, and chat participation keyed by
session-bound invocation context or by future broker-granted service facets,
not by manifest-assigned or user-selected receiver selectors. The focused
`run-adventure` gate rejects `system-adventure.cue` if `badge:` fields are
reintroduced.

Input and content bounds for the near phase:

- command lines accepted through the current `StdIO` adapter: 256 bytes;
- typed object ids, actor ids, mob ids, writ ids, directions, spell names, and
  skill names: 64 bytes, ASCII alphanumeric plus `_` and `-`;
- chat `say` text and future free-form command text: 256 bytes after trimming,
  with no semantic parsing beyond the declared text field;
- generated content ids and aliases: same 64-byte id rule unless a reviewed
  schema/runtime change raises it;
- room/site titles: 80 bytes; descriptions: 320 bytes; lead and failure hint
  lines: 160 bytes; actor dialogue and debrief lines: 320 bytes;
- content lists must use the explicit per-player, per-site, and per-room caps in
  this file, not unbounded vectors.

If generated mission content is checked in, every branch that changes content or
the generator must provide a freshness check equivalent to
`make generated-code-check`; stale generated Rust blobs are a review finding.

## Authority-RPG Direction

The next design target is a compact expedition RPG where rare authority is RPG
power fantasy, not paperwork. The core loop is:

```text
accept mission
choose writs / companions / relics
enter dangerous site
discover authority conflicts
fight / negotiate / delegate / revoke
extract with loot, survivors, evidence, or consequences
upgrade rank, base, companions, and future authority
```

Design rules for subsequent backlog slices:

- Writs are loot: gear, skill tree, access key, social status, and sometimes
      curse. A good writ changes what the player can do, carries inspectable
      issuer/scope/expiry/delegation/revocation rules, and may have bounded
      affixes or drawbacks under the mission seed.
- Classes are authority archetypes: Warden, Marshal, Archivist, Custodian,
      Factor, and Heretic/Renegade. Differences come from legal, social, and
      supernatural verbs, not generic damage numbers.
- Delegation is buildcraft. Companion loyalty, ambition, competence,
      reputation, fear, and doctrine should affect how delegated authority
      behaves under pressure.
- Combat attacks authority as well as HP. Forgers, null-priests, bandit
      captains, corrupt magistrates, spies, oathbreakers, and wraiths should
      threaten writs, custody, witnesses, route grants, and legal control.
- Denial should reward with leads: a missing witness, hidden jurisdiction,
      forged seal, rival claim, corrupt actor, unsafe state, rank gate, or
      alternate route.
- Progression unlocks reach: new jurisdictions, deputy appointment, remote
      revocation, relic custody capacity, hostile negotiation, disputed shrine
      access, and operating without a local witness in constrained cases.
- Base modules unlock verbs. Archive, Temple vault, Barracks, Court, Market
      hall, Signal tower, and Sanctuary should affect future expeditions
      through explicit actions, not passive percentage bonuses.
- Controlled randomness covers mission complications, route hazards, faction
      demands, companion behavior, relic side effects, enemy authority tricks,
      optional objectives, and loot/writ modifiers. The legal model remains
      deterministic and auditable under a seed.
- Multiplayer stays scoped to cooperative expedition pressure first. Defer MMO
      scale, open economies, broad construction seasons, LLM-critical NPCs,
      federation, and worldlines until the compact expedition loop is excellent.

The pure combat-targeting foundation, generated combat profiles, server
integration, and the bounded authority-challenge / writ-affix / delegation /
Archive-reach proofs have landed (see the Phase 8/9 checkboxes). Remaining
forward sequence:

1. Extend the first authority-attacking enemy behavior beyond the bounded
      forged route/custody claim into broader authority-bearing enemy variants.
2. Generalize writ-affix and delegation-buildcraft proofs beyond the single
      bounded `ward-writ`/Livia cases into more writs and companions.
3. Extend base/rank reach unlocks beyond the bounded Archive evidence unlock
      without starting a general construction/base-management system.
4. Extend construction jobs only after a visible gameplay need appears:
      durable stock ledgers, job-time advancement, artifact custody outputs,
      and facility slot capacity remain future work.
5. Keep proofs deterministic: pure Rust tests for new rules and one
      `adventure-scenario-test` path per new cross-service behavior; keep the
      shell transcript to representative parser coverage.

## Phase 1: Player-Visible Mission Substrate

Visible outcome: a first-time player can complete the current Aurelian expedition
without reading source or memorizing hidden ids, and the read-only mission
content comes from a validated generated blob instead of hardcoded room tables
and scattered text. The mission path and existing QEMU transcript outcomes stay
stable, but `look`, `status`, inspection, and failures become clearer.

- [x] Define a bounded `AdventureContent` model for sites, exits, visible
      items, actors, mobs, aliases, objectives, leads, and scripted proof-path
      metadata.
- [x] Add host validation for content graph integrity: unique ids, valid exits,
      valid aliases, referenced actor/item/mob ids, bounded text length, and
      deterministic ordering.
- [x] Generate or embed a compact static Rust representation for userspace;
      keep runtime parsing out of the `no_std` service unless explicitly
      justified.
- [x] Add a generated-content freshness check and wire it into the relevant
      branch verification so checked-in content blobs cannot drift from source
      mission data.
- [x] Move current `square`, `tavern`, `garden`, `cellar`, `map`, `coin`,
      `key`, `scout-marker`, and `ward-wraith` descriptors into content data.
- [x] Keep all state-changing behavior in Rust handlers; content may select
      text and ids but must not bypass authority checks.
- [x] Extend `AdventureRoomView` or status text so `look` presents objective,
      visible interactables, actors, active mobs, exits, and one lead line.
- [x] Add canonical-id display for objects, actors, mobs, writs, and exits.
- [x] Add alias resolution for common casing and titles, with responses that
      name the resolved canonical id.
- [x] Add near-miss suggestions for known ids, starting with common failures
      such as `ward` -> `ward-writ`, `wraith` -> `ward-wraith`, and `livia`
      casing.
- [x] Improve invalid `order` results so they name plausible next actions when
      player knowledge allows it.
- [x] Split status text into survival state, mission state, held/delegated
      authority, evidence/effects, and lead.
- [x] Add host tests for rejecting malformed content graphs.
- [x] Keep `make run-adventure` transcript stable after the migration and add
      assertions for at least one canonical-id suggestion and one improved
      actor-task hint.

Implementation notes:
- Start with read-only content fields. Do not introduce a general scripting
      engine for mission logic in this phase.
- Keep object ids ASCII, stable, and bounded by the near-phase limits above
      unless a reviewed schema/runtime change raises those limits.
- Lua scripting belongs after the data model exists. Do not use Lua to bypass
      the content validator or make transcript-critical behavior depend on an
      unbounded script.

## Phase 1b: Deterministic Scenario Scripting

Visible outcome: once `capos-lua` can run scripts with exact grants, selected
scenario and NPC behaviors can move from Rust match branches into deterministic
Lua scripts without changing the authority boundary.

- [ ] Use `docs/proposals/lua-scripting-proposal.md` as the scripting design
      source.
- [ ] Expose only narrow game host APIs to scripts, such as read current
      mission state, choose a dialogue branch, emit a debrief line, or request
      a typed game action through a granted object cap.
- [ ] Keep mission authority, inventory mutation, relic custody, combat damage,
      and cap transfer in kernel-enforced capability calls and Rust service
      handlers.
- [ ] Add deterministic script fixture tests for NPC state machines and
      scenario beats.
- [ ] Add QEMU transcript coverage showing one Lua-scripted NPC or scenario
      reaction using a granted cap and one denied ungranted path.
- [ ] Keep Rust and Lua examples side by side so the demo proves capability
      discipline is language-independent.

Cut scope:
- No dynamic native Lua modules, no broad `ProcessSpawner`, no raw CapIds in
      scripts, and no script-owned authority beyond the runner's CapSet.

## Phase 1c: Non-Deterministic NPC Brains

Visible outcome: non-transcript-critical NPC flavor can later use the
language-model/agent proposals without weakening deterministic proofs.

- [ ] Use `docs/proposals/llm-and-agent-proposal.md` for any LLM-backed NPC
      implementation.
- [ ] Keep LLM NPCs behind narrow caps and treat model outputs as suggestions
      or dialogue data, not authority.
- [ ] Restrict LLM use to ambient tavern chatter, optional hints, flavor
      summaries, or player-facing explanation when exact transcript output is
      not part of the proof.
- [ ] Keep main mission success paths, combat outcomes, custody decisions,
      policy denials, and QEMU smoke assertions deterministic.

Deferred from Phase 1:
- Dynamic completions belong with the future `CommandSession` interface and
      should not duplicate full parser logic in the `StdIO` adapter.

## Phase 2: Aurelian Expedition Map

Visible outcome: the playable mission uses the proposed frontier expedition
locations rather than the four-room prototype.

- [x] Replace prototype content with a small `Site` graph:
      `fort_aurelian`, `gate_yard`, `ashen_road`, `signal_tower`, and
      `under_vault`.
- [x] Model site metadata: region, threat level, exits, visible items, actors,
      active wards, and optional required route authority.
- [x] Implement the first mission objective: recover `eagle-standard` from the
      ruined signal tower.
- [x] Add complications: unstable tower gate, wounded legionary behind a ward,
      guild scout route information, and temple witness custody requirements.
- [x] Provide at least two acceptable good outcomes, such as recovered standard
      plus sealed gate, or recovered standard plus survivor evacuation.
- [x] Update `make run-adventure` to drive the new mission path with stable
      assertions.

Cut scope:
- Do not add random mission variants in this phase.
- Do not split mission state into a new service until the single-server model
      blocks explicit authority or proof coverage.

## Phase 3: Authority Inventory And Relic Custody

Visible outcome: player-facing inventory makes authority, evidence, and relic
custody visible without implying every entry is a pick-up item.

- [x] Split inventory/status output into `Items`, `Writs`, `Relics`, `Marks`,
      and `Evidence`.
- [x] Keep `take` and `drop` for physical items only.
- [x] Keep `request`, `accept`, `delegate`, and `revoke` for authorities.
- [x] Add `relic custody` state for `eagle-standard`, including a failure path
      when the player lacks temple or rank authority.
- [x] Add `temple-seal` or equivalent witness-certified custody proof.
- [x] Ensure relic failures distinguish missing location, missing authority,
      unsafe state, and witness refusal.
- [x] Add QEMU assertions for relic custody denial, successful custody, and
      audit/evidence status output. Complex custody coverage runs in the capOS
      `adventure-scenario-test` userspace process through real `Adventure` cap
      calls; the shell-driven `adventure-client` transcript remains
      representative interactive client coverage.

## Phase 4: Persistent Profile And Ledger Substrate

Visible outcome: player profile data and mission evidence have bounded save/load
semantics, while ordinary client launches remain fresh unless the player
explicitly resumes an expedition.

- [x] Define bounded Cap'n Proto records for `AdventureProfile`,
      `AdventureExpeditionCheckpoint`, and `AdventureLedgerRecord`, including
      schema version, content hash or release id, profile id, record/checkpoint
      version, size limits, and migration policy.
- [x] Add host tests for save-record encode/decode, first schema-version
      acceptance, unknown-content rejection, over-limit rejection, stale-version
      rejection, and wrong-profile rejection.
- [x] Add the `AdventureProfileService` summary substrate for bounded
      create/load/save, local non-reward settings and progression updates, and
      validation of rank marks, warrior stars, wizard circles, faction
      standing, cosmetics, contributor badges, title choices, and settings.
- [x] Connect `AdventureProfileService` reward and title mutations to
      ledger-backed authorization once `AdventureLedger` exists, so rank marks,
      faction standing, cosmetics, contributor badges, and title choices are
      applied from auditable mission facts rather than direct summary edits.
- [x] Add `AdventureLedger` as append-only mission evidence: debrief records,
      relic custody, forbidden-rite use, witness certifications, reward mints,
      market/trade receipts, and revocations.
- [x] Add `AdventureExpeditionService` for active expedition checkpoints:
      current site, objective state, player state, party state, mob state,
      pending events, and turn ordering.
- [x] Add `AdventureSaveStore` as the only persistence adapter used by the
      profile, ledger, and expedition services. It may target RAM, local
      disk-backed `Store`/`Namespace`, or a future `CloudGameStore`, but gameplay
      services should not call provider-specific APIs directly.
- [x] Prove the local baseline first: save and reload a profile, append and replay
      one ledger record, and explicitly checkpoint/resume one expedition through
      RAM-backed or disk-backed store semantics.
- [x] Keep `run adventure-client` fresh by default. Add an explicit `resume`
      command or profile option before loading active expedition state.
- [x] Add proof coverage for one rejected stale checkpoint write and one rejected
      wrong-profile load.

Cut scope:
- Do not make the kernel persist process memory or the live capability graph.
- Do not merge divergent combat checkpoints automatically; reject stale writes
      and require the player or service to pick a checkpoint.
- Do not require GCP to pass the local QEMU proof path.

## Phase 5: Cloud Persistence Bridge

Visible outcome: the same profile, ledger, and expedition records can be stored
through an optional cloud-backed capability without changing game service logic.

- [x] Define `CloudGameStore` as a narrow bridge with save/load/append operations
      matching the local `AdventureSaveStore` semantics.
- [x] Keep the GCP bridge outside the game authority boundary: the bridge stores
      records, but `AdventureProfileService`, `AdventureLedger`, and
      `AdventureExpeditionService` decide which mutations are valid.
- [x] Use Firestore Native mode only for mutable profile/index documents and
      transactional compare-and-set style updates.
- [x] Use Cloud Storage for versioned snapshots and larger evidence blobs, with
      object versioning and lifecycle policy so old snapshots do not accumulate
      without bounds.
- [x] Use Cloud Run or an equivalent narrow service endpoint for the bridge and
      Secret Manager for bridge-side service credentials. Do not expose those
      credentials inside ordinary game clients.
- [x] Add local fake-cloud tests that enforce the same stale-write,
      wrong-profile, append-only-ledger, and size-bound behavior before using
      real GCP services.
- [x] Add an operational note for project, region, IAM service account, retention,
      backup/export, and cost controls before any real deployment.

Operational note:
- The first real deployment must use a dedicated Google Cloud project per
      game-world environment, or an equivalently isolated folder/project split
      for development, staging, and production. Record the project id, numeric
      project number, billing account owner, support contact, and break-glass
      owner in the deployment runbook before enabling writes.
- Choose one primary region for the Cloud Run bridge, Firestore database, Cloud
      Storage buckets, Secret Manager secrets, and Cloud KMS keys unless a
      reviewed multi-region design exists. The runbook must name the region and
      the data-residency reason; cross-region replication is a separate design
      decision because it affects latency, cost, and recovery semantics.
- Cloud Run is the only provider-facing bridge endpoint in this phase. Ordinary
      capOS game clients see only the `CloudGameStore` capability and never
      receive Firestore document names, bucket names, OAuth tokens, service
      account keys, Secret Manager secret names, or broad network/provider
      authority.
- The bridge must not be public. Launch requires authenticated invocation,
      no `allUsers` or disabled-invoker-IAM setting, an explicit Cloud Run
      ingress mode, and a named invoker identity for the capOS bridge path.
      Public HTTPS exposure or unauthenticated browser calls would bypass the
      `CloudGameStore` capability boundary even if provider credentials remain
      hidden.
- The bridge runs as a dedicated service account. Isolate Firestore by database
      or project boundary, then enforce adventure collection/document path
      allowlists in bridge code before issuing provider calls; do not rely on
      Firestore security rules or collection-scoped IAM for server-side access.
      Grant only the database-level Firestore role needed by the isolated
      database, Cloud Storage object access for the configured adventure
      buckets, Secret Manager secret access for named bridge secrets, and KMS
      encrypt/decrypt authority for the configured game-world key. Do not grant
      project owner/editor, wildcard bucket admin, or user-browser OAuth
      authority to the bridge.
- Firestore Native mode holds mutable profile/index documents and version/CAS
      records only. Every mutable write must read the current document version
      and commit inside a transaction or equivalent preconditioned update; stale
      writes fail closed and preserve the current document.
- Cloud Storage holds immutable or versioned records: expedition snapshots,
      larger evidence blobs, exports, and content-addressed objects. Buckets
      must enable object versioning before production writes and must have a
      lifecycle policy bounding noncurrent versions and abandoned exports.
      Versioning is recovery, not immutability: create-only evidence and
      content-addressed writes must use generation-match preconditions, and
      audit evidence that must resist replacement or deletion needs an explicit
      retention policy or hold gate before launch.
- Retention policy belongs in the runbook before launch: profile/index
      documents keep only the current mutable summary plus required audit
      references; ledger/evidence objects retain enough noncurrent versions for
      recovery and audit; debug exports and test objects have a short TTL.
      Legal hold, public world audit, or contributor-reward evidence retention
      needs separate approval before becoming indefinite.
- Backup/export is explicit. Schedule Firestore exports and Cloud Storage
      inventory or backup jobs to a separate restricted bucket, record restore
      drills, and verify restore through `CloudGameStore` validation rather than
      accepting provider bytes as authoritative.
- Cost controls are launch gates: configure budgets and alerts for Cloud Run
      requests/egress, Firestore reads/writes/storage, Cloud Storage live and
      noncurrent object bytes, KMS operations, and Secret Manager access. Add
      lifecycle rules before enabling object versioning so stale snapshots do
      not grow without bounds.
- Provider credentials stay bridge-side. Prefer service account identity and
      Secret Manager references over static keys. If a static credential is
      unavoidable for a development bridge, record its rotation owner, expiry,
      allowed environment, and revocation procedure; never put it in manifests,
      game save records, browser JavaScript, or QEMU transcripts.

Cut scope:
- No direct Firestore/Cloud Storage calls from `adventure-client` or
      `adventure-server`.

Sequencing note:
- Cross-device multiplayer through GCP is on the roadmap, but it must wait
      until local multiplayer authority, session-bound invocation context, and
      stale-write rejection are already correct behind `AdventureSaveStore`
      and `CloudGameStore`. The cut is sequencing, not a permanent scope
      exclusion.

## Phase 6: User-Owned Browser Save Vault

Visible outcome: private player data can be exported and imported as signed,
encrypted save capsules through a browser using user-granted Google Drive or
Firebase authority, without making those blobs authoritative for shared world
state.

- [x] Define `UserSaveCapsule` with schema version, capsule version, profile
      id, device id, content hash, migration policy, record kind/version,
      previous capsule hash, plaintext hash, ciphertext, AEAD algorithm,
      signature algorithm, signer public key id, signature, and timestamp.
- [x] Define the save-vault key-boundary policy model for local capOS-host key
      material, GCP game-world Cloud KMS authority, and browser transport
      authority.
- [x] Use storage-domain encryption keys: local capOS-host key material for
      local storage and GCP Cloud KMS envelope encryption for GCP-backed data,
      with a per-world or per-shard KMS KEK wrapping service-owned DEKs. The
      browser transports ciphertext and provider handles; it must not receive
      DEKs, `SymmetricKey` caps, `KeySource` caps, KMS decrypt/unwrap grants, or
      provider-independent plaintext authority.
- [x] Prefer Google Drive `appDataFolder` with the narrow `drive.appdata` scope
      for personal backup files that the user should not edit directly.
- [x] Allow Firebase/Firestore user documents only as a transport/cache for
      encrypted capsules. Firestore/Firebase rules can bind access to the
      authenticated user through an explicit `{request.auth.uid}` path template,
      but cannot validate encrypted game semantics.
- [x] Add KMS/IAM design notes for the GCP path: one key ring/key per game-world
      instance or shard, narrow decrypt authority for the game-world service, key
      rotation policy, and revocation behavior for retired worlds.
- [x] Add restore validation in `AdventureSaveStore`: signature, content hash,
      schema version, profile id, previous hash, monotonic version, size bounds,
      and wrong-profile rejection.
- [x] Add rollback policy: importing an older private checkpoint may restore an
      explicit local expedition snapshot, but it must not erase append-only
      ledger facts, contributor rewards, market receipts, or public multiplayer
      outcomes.
- [x] Add host tests for tampered ciphertext, wrong signing key, wrong profile,
      stale version, unknown content hash, oversized capsule, and replayed old
      capsule.
- [x] Add a web-terminal or browser-companion fixture path with fake Drive and
      fake Firebase adapters before using real Google APIs.

Cut scope:
- No authoritative public world state from user-owned blobs.
- No direct provider SDKs inside `adventure-server`.
- No mandatory Google account for local QEMU adventure proof.
- No silent cloud sync; export/import or sync must be visible user action or
      profile setting.
- No browser-held game-world key capabilities, KMS decrypt/unwrap grants, or
      provider-independent plaintext authority.

## Phase 7: Actors As Capability-Bounded Processes

Visible outcome: important NPCs have process identity and only the capabilities
their role needs.

- [x] Keep `adventure-server` as the authority owner until direct NPC mutation
      needs are explicit.
- [x] Add actor content and chat behavior for Centurion Varro, Magister Livia,
      Acolyte Iunia, Maro the Guild Scout, Wounded Legionary, and Gate Echo.
- [x] Give chat-only NPC processes only `console` and the narrowest available
      chat authority. The focused manifest uses selector-free `chat` grants;
      user-selectable or manifest-assigned receiver selectors must not be part
      of this proof.
- [ ] For any NPC that can affect world state, add a separate scoped
      broker-granted `AdventureNpc` facet or equivalent session-bound service
      authority. Do not use receiver-selector compatibility grants as NPC
      mutation authority.
- [x] Route NPC offers and refusals through player-visible commands and chat
      events rather than hidden server side effects.
- [x] Add focused smoke assertions proving each resident chat-only NPC process
      launches and contributes visible room chat history under session-bound
      chat membership.
- [ ] Add distinct service sessions, chat participant ids, or a scoped
      `AdventureNpc` facet before requiring every boot-launched NPC process to
      act as an independently polling chat participant.

Current shape: `system-adventure.cue` launches the six named actor processes
with only `console` plus selector-free `chat` grants. Because boot-launched
actors inherit init's system session, chat membership intentionally collapses
to the service-scoped caller-session key, and `make run-adventure` proves each
named actor published visible room history with Centurion Varro as the single
deterministic polling reply. Independent per-NPC chat participants and direct
world-mutation NPC authority remain the open `[ ]` items above.

## Phase 8: Tactical Combat And Mob State

Visible outcome: combat remains deterministic and bounded, but offers more
than repeating `attack`.

- [x] Add a bounded mob model with hp, armor, ward, attack, morale, traits,
      intent, and threat level.
- [x] Keep `ward-wraith`; add at least two of `imp-scout`, `ash-ghoul`,
      `gate-hound`, and `echo-centurion`.
- [x] Implement command-level turns: player action, eligible ally action,
      hostile action, deterministic transcript.
- [x] Add visible intent when scout or wizard support makes it available.
- [x] Add `retreat` and at least one blocked-retreat failure.
- [x] Extend `guard` to protect an ally when one is present.
- [x] Add QEMU assertions for one intent line, one ally-related combat action,
      and one deterministic hostile response.

Cut scope:
- No random combat outcomes until seeded mission variants land.
- No hidden dice rolls that make QEMU transcript assertions fragile.

Follow-up combat architecture, grounded by
[`docs/research/game-mechanics-prior-art.md`](../research/game-mechanics-prior-art.md).
Most of this is landed (deterministic target-zone damage, fatigue, interrupt,
recognition disclosure, stealth openings, alert-source generalization,
construction-fed weapon/focus/cloak combat, sustained-magic fatigue refusal, and
scenario coverage); the open forward items are:

- [ ] Use Evil Islands as planning input for tactical fight shape (targeted
      body zones, damage-type/armor matchups, stealth openings,
      visibility-dependent recognition, fatigue/retreat pressure, cast
      interruption, equipment-derived effects). Not a clone target; Aurelian
      keeps command-level turns, capability-gated authority, deterministic smoke
      coverage, and service-owned outcomes.
- [ ] Move mob combat definitions out of hard-coded `adventure-server` templates
      into validated generated content once the next combat slice needs more
      than the current generated profile fields (damage affinities, zone armor,
      alert groups, recognition thresholds, stealth-opening permissions,
      cast-interrupt vulnerability).
- [x] Extend `adventure-content` pure logic before server integration:
      `CombatZone`, `DamageKind`, `CombatAttackProfile`, `MobCombatProfile`,
      deterministic target-zone damage, fatigue cost, interrupt outcome,
      recognition level, and alert propagation helpers.
- [ ] Extend CUE content and `tools/adventure-content-gen` beyond the current
      generated mob combat profiles when alert groups, stealth openings, or
      richer profile references land.
- [ ] Add typed Adventure surface only where the existing text target cannot
      stay unambiguous (e.g. structured target/zone/weapon fields for the
      browser client); current explicit-zone parsing already covers the proof
      commands.
- [x] Update `AdventureRoomView`/status output for inspected vs rough mob intel.
- [x] Keep `adventure-server` as the authoritative combat state owner. Durable
      alert state, broader limb persistence, and pending multi-turn interruption
      remain future work.
- [x] Add targeted attacks with a small fixed zone set: `head`, `hands`,
      `legs`, `core`, with deterministic zone effects.
- [x] Add damage-type and mitigation metadata for weapons, spells, armor, ward
      state, and zone armor, with explicit result text.
- [x] Make enemy recognition depend on scout/wizard support, distance, direct
      inspection, and prior codex evidence.
- [ ] Add height and route-position inputs to enemy recognition once room
      topology and browser-client world positioning expose those facts as
      structured state rather than server-local command context.
- [x] Add stealth-opening support for ambush/backstab-style advantages.
- [x] Add a bounded pull/alert behavior for the ward-wraith to gate-hound path.
- [x] Add a bounded imp-scout warning path.
- [x] Generalize alert-source resolution across ward-wraith alarm, imp-scout
      warning, and escaping-scout paths.
- [x] Add bounded failed-stealth gameplay integration for route-supported
      imp-scout attacks lacking scout-track evidence.
- [x] Add bounded noisy-movement gameplay for recovered relic movement.
- [x] Add broader noisy-movement integration beyond the current relic movement,
      ward-wraith, and imp-scout paths.
- [ ] Tie combat output to equipment construction inputs from Phase 11c:
      weapon/shield/focus/cloak object type, material, facility quality,
      warrior stars, wizard circles, and remaining enchantment budget affect
      bounded damage, guard, fatigue, interruption, and resistances. Bounded
      slices for `shield-wall` cloak, `bronze-gladius` weapon, and `ember-dart`
      focus have landed; broader equipment handling, construction jobs, and
      durable runtime inventory semantics remain open.
- [x] Add a bounded sustained-magic fatigue refusal for the `shield-bind` path.
- [ ] Generalize explicit fatigue and cast-interruption rules for heavy
      equipment, running, retreat, additional sustained magic, and monster
      fatigue, creating meaningful retreat/guard choices rather than hidden
      penalties, and without unfair infinite-fatigue monster behavior.
- [x] Add QEMU scenario coverage through `adventure-scenario-test` for inspected
      targeted attack, damage/armor explanation, stealth/scout opening,
      alert/pull response, cast interruption/fatigue refusal, and
      retreat/blocked-retreat.
- [x] Keep rewards mission-audited. Do not add enemy grinding as a rank,
      warrior-star, wizard-circle, or faction-standing source.

## Phase 9: Skills, Spells, Ranks, And Reputation

Visible outcome: player competence affects available actions and future grants
without becoming a grind.

- [x] Model player rank labels: `tiro`, `signifer`, `centurion`, and `legate`.
- [x] Keep warrior stars and wizard circles visible in status, but make them
      policy inputs for brokered authorities.
- [x] Add missing skills from the proposal as needed by the first mission:
      `shield-wall`, `counter`, `rally`, or narrowed equivalents.
- [x] Add missing spells as needed by the first mission: `mend-wound` and
      `stabilize-gate` before higher-circle spells.
- [x] Add explicit failure text when rank, stars, or circles block an action.
- [x] Add debrief outcomes that update rank marks, faction standing, and
      evidence records from auditable mission facts.
- [x] Add QEMU assertions for one rank/circle denial and one debrief reward.

Deferred:
- `dome-shield`, `demon-brand`, and high-circle gate rewriting are later
      campaign scope unless a focused proof needs them. `rally` remains
      explicitly reserved for later centurion command authority.

## Phase 10: Market And Logistics

Visible outcome: the shopkeeper becomes a small capability-shaped economy proof
instead of flavor chat.

- [x] Add typed verbs for `quote`, `buy`, `sell`, `trade`, and `repair` before
      accepting them as implemented gameplay.
- [x] Define bounded market roles: quartermaster, guild scout, temple annex,
      and field engineer.
- [x] Implement one deterministic route purchase or favor exchange with Maro.
- [x] Implement one authority-gated refusal, such as focus equipment requiring
      wizard circle 1 or temple certification requiring clean custody.
- [ ] Define trade/custody transfer as a service-mediated transaction protocol,
      not two save-file edits: reserve or escrow both sides, commit or release
      with idempotency keys, reject stale versions, record one ordered ledger
      receipt, and specify cancellation, retry, and crash-recovery behavior.
- [x] Ensure prices and blocked authority are named in failure text.
- [x] Add QEMU assertions for one quote, one successful exchange, and one
      rejected trade explaining the gate.

Planning input, grounded by
[`docs/research/game-mechanics-prior-art.md`](../research/game-mechanics-prior-art.md):
use external game-mechanics research as planning input only, not a clone
target. Stardew Valley is useful for calendar pressure, seasonal resource
tables, festivals, routine changes, quests, gifts, affection, and season-bound
crops. EVE Online is useful for regional markets, market-eligible item classes,
brokered buy/sell orders, immediate matching, and blueprint/material/facility
manufacturing constraints. Evil Islands is useful for equipment construction and
the targeted combat model. The capOS translation turns these stable mechanics
into the capability-shaped tasks in Phases 11-12: seasonal cycles, regional
settlements/outposts, service-owned order books, blueprint/artifact
construction, targeted deterministic combat, token-budgeted agent NPCs, and a
rich tilemap client.

## Phase 11: Seeded Variation

Visible outcome: repeated runs vary content meaningfully across normal play,
while the smoke transcript stays reproducible under a fixed seed.

Current shape: live adventure player state is keyed by endpoint caller-session
scoped refs, and generated mission content carries fixed smoke seed/variant
metadata printed in status and asserted by the scenario cap-call path. This is
the deterministic seed-metadata foundation only; seeded gameplay variation,
production per-run seeds, festivals, NPC routines, and full seasonal economy
behavior remain open.

- [x] Add generated mission content fields for a fixed smoke seed label and
      selected variant metadata.
- [ ] Add manifest or mission setup field for a fixed mission seed and a
      separate per-run seed for production play.
- [x] Print seed and selected variant metadata in transcript/debug mode.
- [ ] Seed mob placement, optional hazards, shop inventory, rumor lines, loot
      cache locations, debrief complications, and ambient encounter timing.
- [ ] Seed seasonal state for normal play: season, day, weather/hazard class,
      seasonal resources, festival/event hooks, and NPC routine variants. The
      deterministic smoke seed forces a stable generated calendar state, but
      normal-play seed selection remains open.
- [ ] Keep season-sensitive resource tables bounded: crops, forage, fish,
      shop stock, route hazards, and outpost production all have explicit
      per-site caps and stable sorted output under a fixed seed.
- [ ] Keep combat outcomes reproducible under a fixed seed; production play
      may add bounded variance per turn as long as the smoke seed reproduces
      the recorded transcript.
- [x] Add scenario assertion for seed and variant metadata through real
      `Adventure` cap calls.

## Phase 11a: Calendar, Seasons, And Resource Cycles

Visible outcome: the frontier feels alive across repeated sessions without
making proof transcripts nondeterministic.

- [x] Add an `AdventureCalendar` model with four 28-day seasons as the initial
      default, explicit day advancement rules, and debug output for the fixed
      smoke seed.
- [x] Attach bounded fixed-smoke seasonal availability primitives to generated
      content for crops, forage, fish, shop inventory, route hazards, and
      repair/material production. Multi-season resources must be declared
      explicitly.
- [ ] Apply seasonal availability to gameplay systems. Bounded slices have
      landed: quartermaster `field-rations` quotes read the fixed-smoke seasonal
      shop-stock table; `Adventure.status` forecasts carried seasonal crops
      expiring and fish/forage degrading at the next season change; the
      `season-transition` ask path applies the next-season transition to actual
      player inventory (crops expire, fish/forage become `-degraded` tokens);
      and the `field-rations` buy path spends audited Aurelian standing and
      records per-expedition seasonal stock usage. Broader season advancement,
      economy, persistence, market orders, seeded normal-play calendars, and
      automatic world mutation remain open.
- [x] Add festival and military-event records that can temporarily expose
      actor-location, shop, witness, route, and rumor metadata. This is
      metadata/status only; actual gameplay mutation remains open.
- [x] Give named actors bounded routine variants by season, festival, mission
      beat, and local emergency, visible as structured actor presence/state.
      This is metadata/status selection only; it does not move actors or mutate
      authority.
- [ ] Add simple quest/gift/affection hooks only after profile and ledger facts
      can record them. Daily interactions and gifts should affect actor
      standing through auditable records, not client-owned counters.
- [x] Add pure Rust unit tests for calendar rollover, season/day bounds,
      seasonal resource eligibility, multi-season exceptions, and stable
      fixed-seed ordering.
- [x] Add pure Rust unit tests for festival scheduling once festival records
      exist.

## Phase 11b: Regional Settlements, Outposts, And Trade Routes

Visible outcome: Aurelian is one settlement in a wider frontier economy with
multiple cities, outposts, production sites, and routes.

- [x] Model more than one settlement: `fort_aurelian` remains the proof
      settlement, while later content can add at least one civilian city, one
      temple-administered site, one guild waystation, and multiple resource
      outposts.
- [x] Define outpost roles such as mine, farm, timber camp, shrine, gate-yard,
      salvage yard, and repair yard. Each role produces bounded resources,
      consumes supplies, exposes route risks, and may require specific writs.
- [x] Add region and route metadata: distance, hazard, faction control, route
      authority, cargo limits, seasonal closure, and known-safe/unknown states.
- [ ] Extend markets from actor-local deterministic handlers toward a
      service-owned regional market with market-eligible item classes, brokered
      buy orders, sell orders, price/time priority, immediate matching when
      price crosses, expiry, fees, and ordered ledger receipts.
- [x] Add the bounded generated-content order-book foundation for regional
      markets: market book id/location/settlement, buy/sell side, item id,
      price, quantity, expiry day/duration, fee, owner actor/faction/outpost,
      receipt ledger id, pure validation, and deterministic non-mutating
      price-cross matching.
- [x] Add the first bounded service-mediated transaction proof on top of the
      generated regional order books: reserve one crossed match, commit or
      release it with idempotency keys, reject stale versions, record ordered
      receipt facts, and keep the server as the owner of live transaction state.
- [ ] Route real player, NPC, and outpost inventory/currency transfers through
      the Phase 10 service-mediated transaction protocol. The current proof is
      one regional market match: on fresh commit it debits player-local Aurelian
      chits once, decrements seller `ash_farm` `field-ration` stock once,
      accrues service-owned regional market fees once, credits service-owned
      `ash_farm` seller proceeds once, and delivers the committed quantity into
      the player inventory only when ordinary capacity can accept it. It does not
      yet move NPC stores, broader outpost inventories, durable currency/proceeds
      ledgers, profile ledger balances, or durable save records.
- [ ] Add broader scenario coverage for crash-recovery state, receipt replay
      after restart, multi-client settlement, and player/NPC/outpost transfer
      effects. The current scenario path covers quote, reserve, idempotent retry,
      commit replay, stale-version rejection, no-cross partial release, explicit
      cancellation/release, fee withdrawal, bounded receipt-snapshot restore, and
      a bounded settlement side-effect snapshot-view replay. These are bounded
      recovery proofs, not durable persistence or a restart harness.

## Phase 11c: Blueprint And Artifact Construction

Visible outcome: equipment and artifacts become authored constructions with
traceable materials, skills, facilities, and enchantment limits.

- [x] Add blueprint records for craftable equipment, repair jobs, gate parts,
      relic containers, focus items, and lawful wards. Blueprints name required
      materials, facility class, skill/rank/circle gates, expected duration,
      cost, and output bounds.
- [x] Keep the first construction job proof service-mediated. The field-engineer
      gate repair job reserves materials at a generated facility, validates
      blueprint/facility/rank constraints, records ordered job facts, and either
      completes or releases the reservation. Currency escrow, job-time
      advancement, output inventory, and general crafting remain future work.
- [x] Add deterministic property-derivation primitives as a bounded result of
      base blueprint, material, facility quality, and paid cost. Full crafting
      job integration remains open.
- [x] Add artifact construction metadata for rare pieces whose authority matters:
      witness-sealed relic cases, warded cloaks, focus rings, route compasses,
      golem cores, and gate-stabilizer parts.
- [x] Add enchantment slot metadata and validation bounds. The constrained
      post-process gameplay remains open until construction jobs exist.
- [x] Add pure Rust unit tests for blueprint validation, material/property
      derivation, enchantment slot limits, facility/rank/circle gates, and
      missing or retired authority references.
- [x] Add service-side material reservation and stale construction job rejection
      for the bounded field-repair proof. The server owns per-session
      construction material stock, mutates holds/restores only for fresh
      outcomes, and keeps stale/version and idempotent replay behavior in the
      pure job-state model. Durable stock ledgers and broad crafting remain
      future work.

## Phase 11d: Token-Budgeted Agent NPCs

Visible outcome: optional agent-controlled NPCs can feel reactive while staying
bounded, auditable, and outside transcript-critical authority.

- [x] Use `docs/proposals/llm-and-agent-proposal.md`,
      `docs/proposals/hosted-agent-swarm-proposal.md`,
      `docs/proposals/capos-repo-harness-engineering-proposal.md`, and
      `docs/research/hosted-agent-harnesses.md` as grounding before any
      implementation.
- [x] Treat model output as dialogue or proposed action data. Mission-critical
      authority, custody, combat, market commits, rank rewards, and policy
      denials stay in deterministic services.
- [x] Add an `NpcAgentBudget` or equivalent service-owned quota: per actor,
      session, day, and model profile; input/output token limits; tool-call
      limits; cooldown; and exhaustion behavior.
- [x] Let NPCs spend quota on bounded chatter, optional hints, and outpost
      status summaries. Spending must be visible in logs/debug output for
      review.
- [x] Extend token-budgeted NPCs to personal routines, shop negotiation flavor,
      and festival reactions as fake-agent dialogue/proposed-action data only.
- [x] On quota exhaustion, fatigue, sleep schedule, or policy denial, the NPC
      should refuse in-world, for example: `I'm tired. Going to sleep.` The
      refusal must not be a hidden transport error.
- [x] Keep hosted-agent memory separate from authority. Long-lived NPC memory
      can record bounded facts and reflections, but only reviewed/compiled
      facts influence deterministic game services.
- [x] Add tests with a deterministic fake model that proves quota decrement,
      quota exhaustion refusal, no authority mutation from free text, and
      stable transcript output when agent NPCs are disabled.

Current shape: agent NPC budget metadata is disabled-by-default for Iunia,
Livia, and Maro; a deterministic fake-model turn function drives bounded
chatter/hints/outpost-summaries plus routine/shop/festival flavor, decrements
quota, and refuses in-world for quota/fatigue/sleep/cooldown/policy blocks. Live
LLM calls, hosted-agent service execution, durable memory service, autonomous
NPC actions, and any transcript-critical model gameplay remain open.

## Phase 12: Multiplayer, Parties, And Lawful PvP

Visible outcome: shared multiplayer authority works correctly across local
multi-client play first, with cross-device play following on the same
service-mediated boundaries. Players can party up, delegate scoped authority,
assist each other, and engage in lawful PvP without leaking private inventory
or allowing ambient harm.

- [x] Do not start this phase until Adventure and chat authority use
      session-bound caller identity, or future broker-granted service facets,
      rather than receiver-selector identity. The first bounded slices key local
      player labels from live caller-session metadata.
- [x] Add `Expedition` or equivalent shared state only when the single
      `Adventure` service cannot cleanly model party authority. The first
      bounded slice keeps deterministic party state inside `Adventure` because
      no cross-service coordinator is needed for local create/invite/accept/
      leave/delegate/assist records.
- [x] Add party verbs: create, invite, accept, leave, and delegate. Implemented
      for service-created local labels (e.g. `player-1`) derived from live
      caller-session keys, not caller-selected badges or global session data.
- [x] Add `assist <player> with <task>` for deterministic cooperative action.
      Implemented for the first `detect-ward` assist record, requiring party
      membership plus delegated `ward-writ`; it records scoped service-owned
      state and grants no unrelated inventory authority.
- [x] Route first player-to-player physical-item transfer through a
      single-owner atomic mutation path inside `Adventure`. Implemented as
      `transfer <item> to <player>` for service-local player labels: both
      players must be in the same party, `eagle-standard` relic custody is
      refused, and source/target inventories mutate atomically.
- [ ] Add currency escrow and broader two-party trade/custody transfer protocol
      only after the economy model and multi-client proof harness justify it;
      user-owned backup capsules must not be transfer authority.
- [ ] Add a two-client QEMU proof with two service-created player objects, one
      shared party, one delegated writ, and one assist. The proof must use two
      distinct live caller-session keys for Adventure cap calls, not manifest
      receiver selectors or user-chosen identity. Still open: the focused
      Adventure manifest does not yet provide a reliable two-client
      launcher/session harness, so real cap-client assertions stay at one-client
      party surface coverage and complex transitions are covered in pure Rust.
- [ ] Keep PvP opt-in: duel, spar, contest, or bounty authority must exist
      before harmful verbs can target another player.
- [x] Add denial text for unauthorized player harm that names the missing
      lawful conflict authority. `attack <player-label>` refuses known local
      player labels with text naming the missing duel/contested-yard authority.
      Duel/spar/contest/bounty authority remains future work.

Sequencing note:
- The first slice is local multi-client (two clients on one capOS instance)
      because that is the cheapest deterministic proof. Cross-device
      multiplayer is on-roadmap and lands once the local authority model is
      correct and `CloudGameStore` carries shared expedition/ledger state.
- Network-transparent multiplayer (full federation across capOS instances)
      stays separate from this phase and follows the broader networking work.

## Future Phase: Parallel Universes And Worldline Federation

Visible outcome: separate capOS-hosted Aurelian worlds can expose alternate
seeded worldlines and limited cross-world interaction without making remote
instances trusted authorities for local inventory, relic custody, profile
standing, or market settlement.

This is deliberately after local multiplayer, durable ledger/profile state,
service-owned market/escrow, and basic networking. The near-term shape is not a
single shared MMO world. It is a federation of sovereign worldlines, each with
its own content release, worldline id, seed epoch, generated overlays, ledger
head, market policy, and profile-import rules.

- [ ] Add a `WorldlineSeed` model whose outputs are deterministic artifacts:
      generated regional overlays, seasonal economy tables, event schedules,
      market starts, outpost production, route hazards, optional encounters,
      loot caches, and bounded NPC routine variants.
- [ ] Keep authored anchors static: factions, core law, major sites, named
      relics, capability interfaces, canonical proof missions, and security
      policy. Seeded generation may vary conditions around those anchors, but
      must not mint new authority classes or bypass service-owned validation.
- [ ] Store provenance for every admitted generated artifact: content release
      id, worldline id, seed epoch, generator version, scope label, provenance
      hash, and bounded output size.
- [ ] Add pure deterministic generator tests before gameplay integration:
      same seed produces the same artifacts, different seeds produce bounded
      variation, invalid generated references are rejected, and generated
      outputs remain sorted/stable for proof transcripts.
- [ ] Add fixed-seed QEMU proof once the generator exists. The smoke path should
      still use pinned selections until generator coverage is strong enough.
- [ ] Define `WorldlineDirectory`, `WorldlineVisit`, `WorldlineExpedition`,
      `WorldlineTransfer`, and `WorldlineAudit` service surfaces as local facade
      caps over remote protocol messages. Do not serialize raw cap slots,
      endpoint generations, global session ids, or local player labels as
      portable authority.
- [ ] Start with echo-only federation: list a remote or second local worldline,
      inspect content/seed/ledger metadata, and view public state without
      mutation authority.
- [ ] Add a denial proof for cross-world relic transfer before implementing
      successful transfer: `eagle-standard` transfer must fail until custody
      escrow, remote policy, dual-ledger receipts, content compatibility, and
      replay protection exist.
- [ ] Later, add envoy visits and expedition bridges. Projected remote
      characters may observe, chat, or perform explicitly granted low-risk
      actions; spending home-world inventory or importing rewards requires a
      transfer/settlement receipt.
- [ ] Treat cross-world markets and migration as receipt-verified claims.
      Remote order views, faction standing, rank, contributor rewards, and
      custody history require local policy gates before they affect local
      authority.

Feasibility note: this is feasible if it is built as capability federation plus
deterministic worldline generation. It is not feasible as "trust another capOS
instance's save file" or "transfer local caps over the network." Cross-world
state changes need the same reserve/escrow, commit/release, stale-version
rejection, idempotency, and ledger receipt discipline already planned for local
markets and trades.

## Phase 13: Contributor Quest Mechanics

Visible outcome: after the base Aurelian game has stable profiles, evidence,
debriefs, and cosmetic rewards, the game can recognize real capOS development
work through maintainer-witnessed outer-world quests.

- [ ] Use `docs/proposals/contributor-quest-mechanics-proposal.md` as the
      design source for this phase.
- [ ] Keep all rewards cosmetic, narrative, reputational, or bounded
      game-only perks unless a separate reviewed security design grants
      authority.
- [ ] Use full GitHub issue and PR URLs, commit hashes, issuer identity, and
      timestamps in contribution evidence records.
- [ ] Add manual quest and witness records before any read-only forge
      connector.
- [ ] Add QEMU proof that witnessed contribution evidence mints a badge or
      decoration, while an unwitnessed claim does not.

Cut scope:
- No automatic GitHub mutation, no token handling in the game client, no public
      leaderboard that pressures maintainers or security reviewers, and no
      reward that grants repository or OS authority.

## Phase 14: Rich Browser Adventure Client

Visible outcome: after WebShellGateway, session-bound game authority, profiles,
persistence, and the core game loop are stable, a browser-hosted
adventure client presents the same game as a pixel-art interface with animated
characters, location art, inventory panels, combat affordances, and chat/event
feeds. The browser client should feel like a native game client, not a terminal
skin.

- [ ] Treat `adventure-client` as the text/QEMU proof client and compatibility
      adapter. Do not route the rich browser UI through `StdIO` command lines.
- [ ] Implement the web shell or WebShellGateway side as a capability-call proxy
      for the authenticated session. The gateway holds the real capOS caps and
      invokes only the allowed adventure/chat methods for that web session.
- [ ] Keep the browser authority opaque: browser JavaScript receives web-session
      handles and typed DTOs, never raw capOS `CapId`s, badge selectors,
      provider credentials, shell spawn authority, game-world keys, or broad
      network capability.
- [ ] Prefer narrow game-session objects such as `AdventurePlayer` and
      `ChatParticipant` with methods for `look`, movement, inventory, status,
      combat actions, orders, delegation, chat send/history, and bounded event
      polling. A generic `CommandSession` may coexist for terminal-style
      front ends, but it is not the required ABI for a purpose-built game UI.
- [ ] Return structured view state and events suitable for rendering:
      current site, exits, actors, mobs, visible items, held/delegated
      authority, evidence, effects, party state, combat state, animation/event
      cues, and chat history cursors.
- [ ] Represent the world as a 2D tilemap data model for browser presentation:
      maps, tilesets, tile layers, object layers, collision/interaction zones,
      spawn points, actor paths, region/outpost markers, and event triggers.
      Tiled JSON is an acceptable authoring/export candidate if validation
      rejects oversized maps, missing tiles, unknown layer types, and invalid
      object references.
- [ ] Evaluate PixiJS plus `@pixi/tilemap` for the first rich client because
      it gives a WebGL-oriented 2D renderer and rectangular tilemap path with
      a canvas fallback. This is a client rendering choice, not game authority.
- [ ] Keep all semantic validation in game services. Browser-side disabled
      buttons, command palettes, targeting hints, and animations are
      presentation only; the server still rejects missing authority, invalid
      location, stale state, bad custody, unsafe combat, and oversized input.
- [ ] Use explicit asset manifests for pixel art, sprite sheets, portraits,
      tiles, VFX, UI sounds, and animation ids. Asset lookup must not grant
      game authority, and missing or mismatched assets must fail as presentation
      errors rather than game-state mutations.
- [ ] Add a headless browser harness that authenticates through the web gateway,
      opens the rich client, drives one deterministic mission slice using UI
      actions, verifies rendered state transitions/events, and checks logout or
      tab-close teardown.
- [ ] Add browser rendering checks for tilemap layer order, actor placement,
      viewport/camera bounds, collision affordance display, event feed updates,
      and no browser-side mutation of authoritative adventure state.

Blocked by:
- WebShellGateway authentication, origin/TLS policy, session teardown, and
      bounded browser transport.
- Broker-granted Adventure/chat authority or gateway-owned live caller-session
      mapping so web sessions do not depend on caller-selected receiver
      identity.
- Persistent profile/ledger/checkpoint semantics for save/resume UX.
- Stable core gameplay phases through at least authority inventory, relic
      custody, actor roles, combat, and debrief rewards.

Cut scope:
- Do not make browser-rendered state authoritative.
- Do not let browser UI bypass game service methods or mutate save records
      directly.
- Do not require the rich browser client for QEMU proof coverage; the text
      client remains the deterministic low-dependency proof path.

## Service Split Gates

Keep one `adventure-server` until there is a concrete proof value in splitting
state. Split services only at these gates:

- Mission service: when multiple clients or NPCs need shared expedition state
      independent of private player profiles.
- Profile service: when rank marks, cosmetics, contributor badges, or settings
      must persist beyond one process lifetime.
- Audit/Witness service: when relic custody, forbidden rites, and debrief
      evidence need a separate authority boundary.
- Save store: when profile, ledger, or expedition state needs a shared adapter
      over RAM, local disk, or cloud backing.
- Cloud bridge: only after local save/load semantics and stale-write rejection
      are proved behind `AdventureSaveStore`.
- User-owned save vault: when private profile/export data should sync through a
      user's browser or Google account without granting provider credentials to
      game services.
- Market/Trade service: when two-party exchange or shop inventory becomes
      more than a deterministic local handler.
- Expedition service: when parties, assists, duels, or contested sites need
      shared state and explicit consent capabilities.

Every new service split must include manifest grants and QEMU assertions for
both allowed behavior and at least one rejected overbroad action.

## Verification Gates

For each phase that changes behavior:
- [ ] `make fmt-check`
- [ ] `make generated-code-check` when schema or generated bindings change.
- [ ] Generated content freshness check when mission source data or content
      generation changes.
- [ ] Relevant host tests for content validation or pure logic.
- [ ] Prefer pure Rust unit tests for complex deterministic game logic:
      calendar/season rules, resource tables, blueprint validation, market
      matching, escrow state machines, route constraints, and agent quota
      accounting.
- [ ] Use a real Rust test client process calling game caps for complex
      scenario tests that cross service boundaries: custody, construction,
      market transactions, party assists, and regional economy flows.
- [ ] Keep the current command-client transcript focused on basic command and
      client functionality: parsing, rendering, representative success/failure
      calls, and stable QEMU smoke proof. Do not make it the only coverage for
      complex game state machines.
- [ ] Save-record encode/decode and migration tests when profile, expedition,
      ledger, or cloud-bridge persistence changes.
- [ ] User-save capsule tamper/replay/wrong-profile tests when browser-mediated
      backup or restore changes.
- [ ] `make run-adventure` with deterministic transcript assertions for the
      new behavior.

For content-only changes:
- [ ] Content validator tests must pass.
- [ ] Generated content freshness check must pass when content blobs are checked
      in.
- [ ] If the content family uses `mkmanifest cue-to-capnp`, rerun the conversion
      with pinned `CAPOS_CUE` and `CAPOS_CAPNP`, decode or validate the produced
      Cap'n Proto message, and include the freshness check in
      `make generated-code-check`.
- [ ] `make run-adventure` must still prove the visible mission path.

Do not claim the full adventure proposal is implemented until the Aurelian
mission, authority inventory, actor roles, relic custody, debrief, and
deterministic proof path all land.
