# 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 backlog is not the current selected milestone. It belongs under the
Shared-Service Demos track and should be pulled into `WORKPLAN.md` only when
the selected visible outcome changes to a game-depth milestone.

## Current Baseline

Implemented:
- [x] Shell-spawned `adventure-client` with explicit `StdIO`, `Adventure`, and
      `Chat` endpoint grants.
- [x] `adventure-server` owns per-session-keyed room, inventory, combat, writ,
      evidence, and effect state using the live endpoint caller-session scoped
      ref plus epoch. Normal shell launch/grant commands omit legacy badge and
      receiver-selector syntax, and the focused `system-adventure.cue` manifest
      uses selector-free endpoint grants for Adventure and its chat-backed NPCs.
      Explicit selectors remain only outside Aurelian for low-level
      compatibility and hostile-path fixtures.
- [x] Typed adventure methods exist for `look`, movement, inventory,
      `inspect`, `use`, status, combat, authority verbs, delegation, `order`,
      `seal`, and `leave`.
- [x] Aurelian expedition mission proves `ward-writ`, Maro route evidence,
      `ward-wraith` combat, Livia delegation, spell/skill/guard effects,
      `eagle-standard` recovery, witness-certified temple custody, survivor
      evacuation, gate sealing, downed-state refusal, and leave cleanup.
- [x] `adventure-content` contains the pure targeted-combat foundation from
      commit `f149119`: deterministic combat zones, damage kinds, attack and
      mob profiles, bounded zone damage, fatigue cost, pressure interruption,
      recognition level, and alert propagation helpers.
- [x] Inventory and status output now split player state into `Items`,
      `Writs`, `Relics`, `Marks`, and `Evidence`.
- [x] `chat-server` labels replayed room history and separate NPC processes
      prove chat-only actors with process-exit observation.

Known limitations:
- Item inspection text and most state-transition/failure text still live in
      Rust handlers.
- Relic recovery uses a dedicated typed `recover` cap method; `take` and
      `drop` are reserved for physical inventory items.
- 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. The QEMU smoke proof therefore treats them as one
      session-keyed chat member: all greetings must be visible, Centurion Varro
      is the single deterministic polling reply actor, and independent
      concurrent NPC replies are future work. Distinct concurrent NPC chat
      memberships need distinct spawned session contexts, not raw init-spawned
      boot services.
- Generated combat profiles now reach `adventure-server` for the current mobs
      and are proven through the QEMU scenario process with explicit target-zone
      commands, but broad weapon parsing, durable alert groups, pending
      interruption state, stealth openings, and authority-combat verbs remain
      open.
- Rank, faction, debrief, market, party, and item-transfer logic are still
      bounded proof slices, not durable profile/ledger subsystems. PvP consent
      and two-client multiplayer proofs are not present.

## 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.

Near-term sequence after the pure combat targeting foundation in `f149119`:

1. Generate combat profiles from CUE for the current mobs and reject malformed
      zones, damage kinds, alert groups, recognition thresholds, and stealth
      references through `make generated-code-check`.
2. Integrate those profiles into `adventure-server` so inspected attacks use
      deterministic zone damage, fatigue, interruption, recognition, and alert
      helpers. Keep clients from submitting computed damage.
3. Extend text parsing only as needed for unambiguous proof commands:
      `attack <mob> [zone] [with gladius]`,
      `cast <spell> at <mob> [zone]`, and one authority-combat verb such as
      `inspect seal` or `expose forgery`.
4. Add the first authority-attacking enemy behavior without broad new systems:
      a forged route/custody claim or seal conflict that can be inspected,
      exposed, and resolved during the existing expedition.
5. Add a small writ-affix proof using authored or fixed-seed content: one writ
      modifier with a meaningful drawback, printed in inspect/status output and
      enforced by the service.
6. Add one delegation-buildcraft proof for an existing companion: a trait such
      as loyalty, competence, or doctrine changes the outcome of delegated
      `ward-writ` or custody authority and explains the causality.
7. Add one base/rank reach unlock at debrief, such as Archive evidence
      verification, Temple vault custody upgrade, or Signal tower remote
      revocation, without starting a general construction/base-management
      system.
8. Prove the sequence through pure Rust tests for deterministic rules and one
      `adventure-scenario-test` path covering inspected targeted attack,
      authority threat/lead, writ drawback, delegation consequence, and reach
      unlock. Keep the shell transcript to representative parser coverage.

2026-04-29 09:41 UTC status: generated combat profiles for current mobs landed
in `adventure-content` CUE, generator output, and pure content validation.
Adventure server/client/scenario integration remains open.

2026-04-29 10:23 UTC status: `adventure-server` now fails closed at startup if
any hard-coded runtime mob lacks a generated combat profile. Runtime mob ward
state comes from generated profile metadata, and server-owned attack, skill,
and cast handlers use pure target-zone mitigation plus profile fatigue cost for
the current deterministic proof actions. Ordinary `look`/`status` mob lines
stay rough; exact zone armor, ward value, pressure, focus, alert radius, and
counter details are revealed only after mob inspection or combined scout/wizard
support, while intent remains visible with scout or wizard support. Recognition
and alert helper results are surfaced as readable combat facts, but durable
alert groups, pending interruption state, explicit
weapon/zone targeting, and authority-combat verbs remain open.

2026-04-29 12:05 UTC status: Adventure `attack`, `skill`, and `cast` cap
methods now accept optional target-zone text while preserving empty-zone
callers. `adventure-server` validates `head`, `hands`, `legs`, and `core`,
defaults empty zones to each generated mob combat profile's target zone, and
continues to compute damage, fatigue, interruption, and hostile responses
server-side. The shell client parses representative explicit-zone forms for
attack, strike, and cast, including `attack <mob> [zone] [with gladius]` and
`cast <spell> at <mob> [zone]`. Broad weapon handling and authority-combat
verbs remain open.

## 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 now 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 now 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.

2026-04-26 chat-only actor slice, updated 2026-04-29: `system-adventure.cue`
launches the six named Phase 7 actor processes with only `console` plus
selector-free `chat` grants. After the session-bound invocation-context
migration, those boot-launched actors inherit init's system session, so chat
membership intentionally collapses to the service-scoped caller-session key
instead of legacy per-process receiver selectors. `make run-adventure` now
proves every named actor published visible room history, the designated
Centurion Varro actor produced the single deterministic polling reply, and the
other same-session chat actors exited after greeting. Independent per-NPC chat
participants remain blocked on distinct service sessions, chat participant ids,
or a future broker-granted `AdventureNpc` facet. Direct world-mutation NPC
authority remains unimplemented and intentionally unchecked 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.

2026-04-26 Phase 8 first tactical slice: the `adventure-server` now uses a
bounded deterministic mob model for `ward-wraith`, `gate-hound`, and
`imp-scout`; `gate_yard` and `ashen_road` expose the added mobs through
generated content. Command-level combat turns produce deterministic player,
ally, and hostile transcript lines, `guard livia` protects the next hostile
response, and `retreat` has a blocked `gate-hound` failure plus a successful
pressure retreat. The `adventure-scenario-test` capOS process is the primary
QEMU proof for intent visibility, ally guard/hostile response behavior,
deterministic hostile response, successful retreat, and blocked retreat.

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):
- [ ] Use Evil Islands as planning input for tactical fight shape, especially
      targeted body zones, damage-type/armor matchups, stealth openings,
      visibility-dependent enemy recognition, fatigue/retreat pressure, cast
      interruption, and equipment-derived combat effects. This is 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 and into validated generated content once the first targeted
      combat slice needs more than hp/armor/ward/attack/morale/traits/intent.
      Content should name damage affinities, zone armor, alert groups,
      recognition thresholds, stealth-opening permissions, and 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. Unit tests should cover
      each rule without QEMU.
- [ ] 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. The current generated-code freshness path
      covers profile presence, zones, damage kinds, armor/ward/focus bounds,
      recognition thresholds, and alert radius for current mobs.
- [ ] Add typed Adventure surface only where the existing text target cannot
      stay unambiguous. A likely first step is parsing `attack <mob> [zone]
      [with gladius]` and `cast <spell> at <mob> [zone]` in
      `adventure-client`, while keeping broader weapon handling and structured
      target/zone/weapon fields explicit if they become necessary for the
      browser client.
- [x] Update `AdventureRoomView` or status output only after a structured view
      is needed. Unknown mobs should initially expose rough threat/posture;
      inspected or combined scout/wizard-supported mobs can expose zone armor,
      ward state, alert risk, and likely counters. Intent is visible with scout
      or wizard support.
- [x] Keep `adventure-server` as the authoritative combat state owner for the
      first slice. Server state now tracks per-mob hp/ward/morale, revealed
      knowledge, profile fatigue, and one-shot target-zone side effects for
      current proof actions, and clients do not submit computed damage. 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`, and `core`. Zone effects should be deterministic: head increases
      disruption/critical payoff at higher risk, hands weaken attacks or
      casting, legs weaken pursuit or charge intent, and core remains the
      reliable default.
- [ ] Add damage-type and mitigation metadata for weapons, spells, armor, ward
      state, and zone armor. Keep result text explicit, for example naming why a
      spear, mace, blade, ember spell, or ward spell mattered.
- [ ] Make enemy recognition depend on scout support, wizard support, distance,
      height/route position, and prior codex evidence. Unknown mobs may reveal
      only posture and threat; inspected mobs reveal zone armor, ward state,
      intent, and likely counters.
- [ ] Add stealth-opening support for ambush/backstab-style advantages without
      requiring real-time precision: if the player approaches unseen and has a
      valid weapon/route, the first command can gain bounded damage or
      interruption.
- [ ] Add pull/alert behavior where noisy movement, failed stealth, or an
      escaping scout can wake related mobs. The service must print the
      causality and keep the smoke path deterministic.
- [ ] 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.
- [ ] Add explicit fatigue and cast-interruption rules for sustained magic,
      heavy equipment, running, and retreat. Fatigue should create meaningful
      retreat/guard choices rather than a hidden accuracy penalty, and monsters
      must not get unfair infinite-fatigue behavior.
- [ ] Add QEMU scenario coverage through `adventure-scenario-test` for one
      inspected targeted attack, one damage-type/armor explanation, one stealth
      or scout-enabled opening, one alert/pull response, one cast interruption
      or fatigue-gated refusal, and one deterministic retreat/blocked-retreat
      interaction. Keep shell transcript assertions to representative parser
      behavior and stable smoke output.
- [ ] Keep rewards mission-audited. Do not add enemy grinding as a rank,
      warrior-star, wizard-circle, or faction-standing source.

2026-04-29 09:09 UTC, commit `f149119` first pure targeted-combat foundation:
`adventure-content` now exposes no-std deterministic combat targeting
primitives for zones, damage kinds, attack and mob profiles, bounded zone damage,
fatigue cost, pressure interruption, recognition level, and alert propagation.
Pure Rust tests cover the rules without QEMU. Generated combat profiles,
Adventure command parsing/server integration, and scenario proof remain open.

2026-04-29 10:23 UTC targeted-combat integration update: generated combat
profiles are loaded by `adventure-server` for all runtime mobs and missing
profiles fail closed at startup. The scenario proof covers inspected
profile-backed output and applied profile fatigue through actual `Adventure`
cap calls. Command parsing for explicit zone/weapon targeting, durable
alert/pull state, pending interruption, and authority-combat verbs remain open.

2026-04-29 13:18 UTC targeted-zone side-effect update: `adventure-content`
maps combat interrupt outcomes to pure target-zone side effects with unit
coverage for every mapping and no-effect case. `adventure-server` records
one-shot side effects on surviving mobs and consumes casting interruption,
stagger, attack reduction, pursuit slowing, or charge breaking during the next
hostile response. The QEMU `adventure-scenario-test` path proves a hands-target
ember cast interrupts the ward-wraith's casting and a legs-target ember cast
breaks the gate-hound's charge through real `Adventure` cap calls. Durable alert
groups, broad weapon handling, stealth openings, and authority-combat verbs
remain open.

## 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.

2026-04-28 17:46 UTC, commit `d09243d` Phase 9 first competency slice:
`adventure-content` now carries host-testable `PlayerRank`,
`PlayerCompetence`, skill/spell gate, and debrief promotion policy. The
adventure server exposes rank, rank marks, Aurelian standing, prepared skills,
and prepared spells in `status`; `shield-wall`, `counter`, `mend-wound`, and
`stabilize-gate` use the shared gates while `rally` remains explicitly reserved
for later centurion command authority. The QEMU `adventure-scenario-test`
asserts a pre-debrief `shield-wall` rank denial, validates `mend-wound` target
denial, proves partial temple custody does not suppress a later debrief reward,
then proves the promotion to `signifer`, warrior-star update, standing mark,
and `debrief-aurelian-route` evidence from audited mission facts.

Deferred:
- `dome-shield`, `demon-brand`, and high-circle gate rewriting are later
      campaign scope unless a focused proof needs them.

## 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.

2026-04-28 18:12 UTC, commit `47dbfc5` Phase 10 first market/logistics
slice: Adventure now exposes typed `quote`, `buy`, `sell`, `trade`, and
`repair` methods through the schema, client wrapper, shell client parser, and
adventure server. The deterministic QEMU scenario covers Maro's route purchase,
a quote naming price/gate/receipt, and Iunia's clean-custody trade refusal
naming the `temple-seal` gate. The full service-mediated transaction protocol
remains open.

2026-04-28 planning update, grounded by
[`docs/research/game-mechanics-prior-art.md`](../research/game-mechanics-prior-art.md):
after the first Phase 10 market slice, use external game-mechanics research as
planning input only. Stardew Valley is useful for calendar pressure, seasonal
resource tables, festivals, routine changes, quests, gifts, affection, and
crops that expire at season boundaries except when explicitly multi-season.
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
where item properties come from material, gold, level, skill, object type, and
a limited enchantment budget. Its combat model is also useful for targeted body
zones, damage-type and armor matchups, scouting/visibility, stealth openings,
pull/alert risk, fatigue, and cast interruption. The capOS-specific translation
is not to clone those games; it is to turn the stable mechanics into
capability-shaped tasks below: seasonal cycles, regional settlements and
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.

First slice status: live adventure player state is keyed by endpoint
caller-session scoped refs instead of legacy receiver badges, and generated
mission content now carries fixed smoke seed/variant metadata that is printed
in status output and asserted by the adventure scenario cap-call path. This is
only the deterministic seed metadata foundation. The Phase 11a calendar
foundation adds a fixed smoke calendar state and bounded seasonal resource
availability primitives in generated content; 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 now 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. Quartermaster
      `field-rations` quotes now read the fixed-smoke seasonal shop-stock table,
      and `Adventure.status` now forecasts carried seasonal crops expiring plus
      fish/forage degrading at the next season change. Actual inventory aging
      and removal/replacement of expired or degraded carried goods remain open.
- [ ] Add festival and military-event records that can temporarily change
      actor locations, shops, witness availability, debrief choices, and rumor
      lines.
- [ ] Give named actors bounded routine variants by season, festival, mission
      beat, and local emergency. Routine changes must be visible as structured
      actor presence/state, not hidden text-only flavor.
- [ ] 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.
- [ ] 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.
- [ ] Route player, NPC, and outpost transfers through the open Phase 10
      service-mediated transaction protocol: reserve or escrow both sides,
      commit or release with idempotency keys, reject stale versions, and record
      one ordered receipt.
- [ ] Add scenario tests using a real Rust test client process that calls game
      caps for multi-step market flows: quote, reserve, partial failure,
      cancellation, retry, crash-recovery state, and receipt replay. The
      quartermaster seasonal shop-stock quote now has real `Adventure.quote`
      coverage; reserve/commit/failure flows remain open.

2026-04-28 20:08 UTC, commit `48c62db` Phase 11b foundation: generated
content now includes bounded regional settlement, outpost, and route records.
The foundation covers `fort_aurelian`, a civilian city, a temple-administered
site, a guild waystation, five resource outpost roles, and eight route metadata
records with distance, hazard, faction control, route authority, cargo limits,
seasonal closures, and known-safe state. Adventure status prints a concise
regional frontier summary, and `adventure-scenario-test` asserts it through a
real `Adventure.status` cap call. Service-owned regional market order books,
escrow/transactions, NPC or outpost transfer flows, and full economy behavior
remain open.

## 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.
- [ ] Keep construction service-mediated. A crafting job reserves materials and
      currency at a location, validates blueprint/facility/rank constraints,
      records the job, and either completes or releases the reservation.
- [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.
- [ ] Add service-side material reservation and stale construction job rejection
      once a pure job-state model or construction service exists.

2026-04-28 21:08 UTC, commit `0b7db05` Phase 11c foundation: generated
content now contains bounded construction material, facility, blueprint,
artifact, and enchantment-slot metadata. `adventure-content` validates
blueprint id uniqueness, material references and quantities, facility
class/location references, rank/star/circle gates, cost/duration/output quality
bounds, artifact authority gates, and enchantment slot limits; it also derives
deterministic construction properties from blueprint/material/facility/cost
inputs. Adventure status prints a concise construction summary, and
`adventure-scenario-test` asserts that line through a real `Adventure.status`
cap call. Service-mediated construction jobs, material reservation,
escrow/transactions, completion/release, and full artifact crafting gameplay
remain open.

## 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.
- [ ] Extend token-budgeted NPCs to personal routines, shop negotiation flavor,
      and festival reactions once those deterministic service states exist.
- [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.

2026-04-28 21:36 UTC, commit `f53d044` Phase 11d foundation: generated content
now carries disabled-by-default optional NPC agent budget metadata for Iunia,
Livia, and Maro, including per-session and per-day input/output token limits,
model profile, tool-call limits, cooldown, fatigue, sleep schedule, refusal
line, and audit visibility. `adventure-content` owns a deterministic fake-model
turn function for bounded chatter, hints, and outpost summaries; it decrements
quota, refuses in-world for quota, fatigue, sleep, cooldown, and policy-denial
blocks, and exposes spending as debug/audit-visible data. Pure Rust unit tests
prove quota decrement, quota exhaustion refusal, sleep/fatigue/cooldown/policy
refusal, disabled-agent transcript stability, bounded output counts, budget
validation, and that free text/proposed action data cannot mutate authority
snapshots. Adventure status prints only an aggregate fake-agent budget line, and
`adventure-scenario-test` asserts that line through a real `Adventure.status`
cap call. Live LLM calls, hosted-agent service execution, durable memory
service, autonomous NPC actions, authority mutation from model output,
transcript-critical LLM gameplay, and service-owned construction or market
state 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.
      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 derived from live
      caller-session keys. The labels are local Adventure handles such as
      `player-1`, not caller-selected badges or global principal/session data.
- [x] Add `assist <player> with <task>` for deterministic cooperative action.
      Implemented for the first `detect-ward` assist record. The assist
      requires party membership plus delegated `ward-writ`; it records scoped
      service-owned state and does not grant unrelated inventory authority.
      Commit `335a9ee` at `2026-04-28 22:22 UTC` routes these transitions
      through the unit-tested `adventure-content` party state and asserts the
      one-client cap surface through `adventure-scenario-test`.
- [x] Route first player-to-player physical-item transfer through a
      single-owner atomic mutation path inside `Adventure`.
      Implemented as `transfer <item> to <player>` / `Adventure.transfer` for
      service-local player labels derived from live caller-session keys. The
      first slice requires both players to be in the same party, refuses
      `eagle-standard` relic custody, mutates source and target inventories
      atomically inside the existing service, and covers success/failure
      invariants in pure Rust transfer tests. One-client cap assertions cover
      unknown target, self transfer, missing item, and unchanged status or
      inventory on refusal without faking a second live session.
- [ ] 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 current focused Adventure manifest does not yet provide a
      reliable two-client launcher/session harness with two distinct live
      caller-session keys for Adventure cap calls. This slice therefore keeps
      the real cap-client assertion to one-client party surface coverage and
      covers complex transitions in pure Rust tests.
- [ ] 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>` now 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.
