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-luarunner 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 pinnedcapnp convertpath. - 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:
-
Define a bounded Cap’n Proto root struct for the content slice rather than extending
SystemManifestor encoding ad hoc JSON. -
Author the source as CUE in package mode, with the same id/text/list bounds documented here and with build-time variation supplied through
--tagorCAPOS_CUE_TAGSonly when the generated output is intentionally tagged. -
Convert with the pinned tools:
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 -
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.
-
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
StdIOadapter: 256 bytes; - typed object ids, actor ids, mob ids, writ ids, directions, spell names, and
skill names: 64 bytes, ASCII alphanumeric plus
_and-; - chat
saytext 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:
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:
- Extend the first authority-attacking enemy behavior beyond the bounded forged route/custody claim into broader authority-bearing enemy variants.
- Generalize writ-affix and delegation-buildcraft proofs beyond the single
bounded
ward-writ/Livia cases into more writs and companions. - Extend base/rank reach unlocks beyond the bounded Archive evidence unlock without starting a general construction/base-management system.
- 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.
- Keep proofs deterministic: pure Rust tests for new rules and one
adventure-scenario-testpath 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.
- Define a bounded
AdventureContentmodel for sites, exits, visible items, actors, mobs, aliases, objectives, leads, and scripted proof-path metadata. - Add host validation for content graph integrity: unique ids, valid exits, valid aliases, referenced actor/item/mob ids, bounded text length, and deterministic ordering.
- Generate or embed a compact static Rust representation for userspace;
keep runtime parsing out of the
no_stdservice unless explicitly justified. - 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.
- Move current
square,tavern,garden,cellar,map,coin,key,scout-marker, andward-wraithdescriptors into content data. - Keep all state-changing behavior in Rust handlers; content may select text and ids but must not bypass authority checks.
- Extend
AdventureRoomViewor status text solookpresents objective, visible interactables, actors, active mobs, exits, and one lead line. - Add canonical-id display for objects, actors, mobs, writs, and exits.
- Add alias resolution for common casing and titles, with responses that name the resolved canonical id.
- Add near-miss suggestions for known ids, starting with common failures
such as
ward->ward-writ,wraith->ward-wraith, andliviacasing. - Improve invalid
orderresults so they name plausible next actions when player knowledge allows it. - Split status text into survival state, mission state, held/delegated authority, evidence/effects, and lead.
- Add host tests for rejecting malformed content graphs.
- Keep
make run-adventuretranscript 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.mdas 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.mdfor 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
CommandSessioninterface and should not duplicate full parser logic in theStdIOadapter.
Phase 2: Aurelian Expedition Map
Visible outcome: the playable mission uses the proposed frontier expedition locations rather than the four-room prototype.
- Replace prototype content with a small
Sitegraph:fort_aurelian,gate_yard,ashen_road,signal_tower, andunder_vault. - Model site metadata: region, threat level, exits, visible items, actors, active wards, and optional required route authority.
- Implement the first mission objective: recover
eagle-standardfrom the ruined signal tower. - Add complications: unstable tower gate, wounded legionary behind a ward, guild scout route information, and temple witness custody requirements.
- Provide at least two acceptable good outcomes, such as recovered standard plus sealed gate, or recovered standard plus survivor evacuation.
- Update
make run-adventureto 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.
- Split inventory/status output into
Items,Writs,Relics,Marks, andEvidence. - Keep
takeanddropfor physical items only. - Keep
request,accept,delegate, andrevokefor authorities. - Add
relic custodystate foreagle-standard, including a failure path when the player lacks temple or rank authority. - Add
temple-sealor equivalent witness-certified custody proof. - Ensure relic failures distinguish missing location, missing authority, unsafe state, and witness refusal.
- Add QEMU assertions for relic custody denial, successful custody, and
audit/evidence status output. Complex custody coverage runs in the capOS
adventure-scenario-testuserspace process through realAdventurecap calls; the shell-drivenadventure-clienttranscript 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.
- Define bounded Cap’n Proto records for
AdventureProfile,AdventureExpeditionCheckpoint, andAdventureLedgerRecord, including schema version, content hash or release id, profile id, record/checkpoint version, size limits, and migration policy. - 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.
- Add the
AdventureProfileServicesummary 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. - Connect
AdventureProfileServicereward and title mutations to ledger-backed authorization onceAdventureLedgerexists, so rank marks, faction standing, cosmetics, contributor badges, and title choices are applied from auditable mission facts rather than direct summary edits. - Add
AdventureLedgeras append-only mission evidence: debrief records, relic custody, forbidden-rite use, witness certifications, reward mints, market/trade receipts, and revocations. - Add
AdventureExpeditionServicefor active expedition checkpoints: current site, objective state, player state, party state, mob state, pending events, and turn ordering. - Add
AdventureSaveStoreas the only persistence adapter used by the profile, ledger, and expedition services. It may target RAM, local disk-backedStore/Namespace, or a futureCloudGameStore, but gameplay services should not call provider-specific APIs directly. - 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.
- Keep
run adventure-clientfresh by default. Add an explicitresumecommand or profile option before loading active expedition state. - 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.
- Define
CloudGameStoreas a narrow bridge with save/load/append operations matching the localAdventureSaveStoresemantics. - Keep the GCP bridge outside the game authority boundary: the bridge stores
records, but
AdventureProfileService,AdventureLedger, andAdventureExpeditionServicedecide which mutations are valid. - Use Firestore Native mode only for mutable profile/index documents and transactional compare-and-set style updates.
- Use Cloud Storage for versioned snapshots and larger evidence blobs, with object versioning and lifecycle policy so old snapshots do not accumulate without bounds.
- 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.
- 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.
- 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
CloudGameStorecapability 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
allUsersor 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 theCloudGameStorecapability 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
CloudGameStorevalidation 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-clientoradventure-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
AdventureSaveStoreandCloudGameStore. 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.
- Define
UserSaveCapsulewith 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. - Define the save-vault key-boundary policy model for local capOS-host key material, GCP game-world Cloud KMS authority, and browser transport authority.
- 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,
SymmetricKeycaps,KeySourcecaps, KMS decrypt/unwrap grants, or provider-independent plaintext authority. - Prefer Google Drive
appDataFolderwith the narrowdrive.appdatascope for personal backup files that the user should not edit directly. - 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. - 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.
- Add restore validation in
AdventureSaveStore: signature, content hash, schema version, profile id, previous hash, monotonic version, size bounds, and wrong-profile rejection. - 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.
- Add host tests for tampered ciphertext, wrong signing key, wrong profile, stale version, unknown content hash, oversized capsule, and replayed old capsule.
- 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.
- Keep
adventure-serveras the authority owner until direct NPC mutation needs are explicit. - Add actor content and chat behavior for Centurion Varro, Magister Livia, Acolyte Iunia, Maro the Guild Scout, Wounded Legionary, and Gate Echo.
- Give chat-only NPC processes only
consoleand the narrowest available chat authority. The focused manifest uses selector-freechatgrants; 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
AdventureNpcfacet or equivalent session-bound service authority. Do not use receiver-selector compatibility grants as NPC mutation authority. - Route NPC offers and refusals through player-visible commands and chat events rather than hidden server side effects.
- 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
AdventureNpcfacet 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.
- Add a bounded mob model with hp, armor, ward, attack, morale, traits, intent, and threat level.
- Keep
ward-wraith; add at least two ofimp-scout,ash-ghoul,gate-hound, andecho-centurion. - Implement command-level turns: player action, eligible ally action, hostile action, deterministic transcript.
- Add visible intent when scout or wizard support makes it available.
- Add
retreatand at least one blocked-retreat failure. - Extend
guardto protect an ally when one is present. - 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 Game Mechanics Prior Art. 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-servertemplates 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). - Extend
adventure-contentpure 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-genbeyond 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.
- Update
AdventureRoomView/status output for inspected vs rough mob intel. - Keep
adventure-serveras the authoritative combat state owner. Durable alert state, broader limb persistence, and pending multi-turn interruption remain future work. - Add targeted attacks with a small fixed zone set:
head,hands,legs,core, with deterministic zone effects. - Add damage-type and mitigation metadata for weapons, spells, armor, ward state, and zone armor, with explicit result text.
- 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.
- Add stealth-opening support for ambush/backstab-style advantages.
- Add a bounded pull/alert behavior for the ward-wraith to gate-hound path.
- Add a bounded imp-scout warning path.
- Generalize alert-source resolution across ward-wraith alarm, imp-scout warning, and escaping-scout paths.
- Add bounded failed-stealth gameplay integration for route-supported imp-scout attacks lacking scout-track evidence.
- Add bounded noisy-movement gameplay for recovered relic movement.
- 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-wallcloak,bronze-gladiusweapon, andember-dartfocus have landed; broader equipment handling, construction jobs, and durable runtime inventory semantics remain open. - Add a bounded sustained-magic fatigue refusal for the
shield-bindpath. - 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.
- Add QEMU scenario coverage through
adventure-scenario-testfor inspected targeted attack, damage/armor explanation, stealth/scout opening, alert/pull response, cast interruption/fatigue refusal, and retreat/blocked-retreat. - 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.
- Model player rank labels:
tiro,signifer,centurion, andlegate. - Keep warrior stars and wizard circles visible in status, but make them policy inputs for brokered authorities.
- Add missing skills from the proposal as needed by the first mission:
shield-wall,counter,rally, or narrowed equivalents. - Add missing spells as needed by the first mission:
mend-woundandstabilize-gatebefore higher-circle spells. - Add explicit failure text when rank, stars, or circles block an action.
- Add debrief outcomes that update rank marks, faction standing, and evidence records from auditable mission facts.
- 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.rallyremains 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.
- Add typed verbs for
quote,buy,sell,trade, andrepairbefore accepting them as implemented gameplay. - Define bounded market roles: quartermaster, guild scout, temple annex, and field engineer.
- Implement one deterministic route purchase or favor exchange with Maro.
- 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.
- Ensure prices and blocked authority are named in failure text.
- Add QEMU assertions for one quote, one successful exchange, and one rejected trade explaining the gate.
Planning input, grounded by Game Mechanics Prior Art: 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.
- 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.
- 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.
- Add scenario assertion for seed and variant metadata through real
Adventurecap calls.
Phase 11a: Calendar, Seasons, And Resource Cycles
Visible outcome: the frontier feels alive across repeated sessions without making proof transcripts nondeterministic.
- Add an
AdventureCalendarmodel with four 28-day seasons as the initial default, explicit day advancement rules, and debug output for the fixed smoke seed. - 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-rationsquotes read the fixed-smoke seasonal shop-stock table;Adventure.statusforecasts carried seasonal crops expiring and fish/forage degrading at the next season change; theseason-transitionask path applies the next-season transition to actual player inventory (crops expire, fish/forage become-degradedtokens); and thefield-rationsbuy 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. - 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.
- 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.
- 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.
- Model more than one settlement:
fort_aurelianremains the proof settlement, while later content can add at least one civilian city, one temple-administered site, one guild waystation, and multiple resource outposts. - 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.
- 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.
- 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.
- 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_farmfield-rationstock once, accrues service-owned regional market fees once, credits service-ownedash_farmseller 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.
- 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 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.
- Add deterministic property-derivation primitives as a bounded result of base blueprint, material, facility quality, and paid cost. Full crafting job integration remains open.
- 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.
- Add enchantment slot metadata and validation bounds. The constrained post-process gameplay remains open until construction jobs exist.
- 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 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.
- Use
docs/proposals/llm-and-agent-proposal.md,docs/proposals/hosted-agent-swarm-proposal.md,docs/proposals/capos-repo-harness-engineering-proposal.md, anddocs/research/hosted-agent-harnesses.mdas grounding before any implementation. - 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.
- Add an
NpcAgentBudgetor equivalent service-owned quota: per actor, session, day, and model profile; input/output token limits; tool-call limits; cooldown; and exhaustion behavior. - 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 as fake-agent dialogue/proposed-action data only.
- 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. - 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.
- 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.
- 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.
- Add
Expeditionor equivalent shared state only when the singleAdventureservice cannot cleanly model party authority. The first bounded slice keeps deterministic party state insideAdventurebecause no cross-service coordinator is needed for local create/invite/accept/ leave/delegate/assist records. - 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. - Add
assist <player> with <task>for deterministic cooperative action. Implemented for the firstdetect-wardassist record, requiring party membership plus delegatedward-writ; it records scoped service-owned state and grants no unrelated inventory authority. - Route first player-to-player physical-item transfer through a
single-owner atomic mutation path inside
Adventure. Implemented astransfer <item> to <player>for service-local player labels: both players must be in the same party,eagle-standardrelic 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.
- 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
CloudGameStorecarries 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
WorldlineSeedmodel 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, andWorldlineAuditservice 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-standardtransfer 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.mdas 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-clientas the text/QEMU proof client and compatibility adapter. Do not route the rich browser UI throughStdIOcommand 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
CapIds, badge selectors, provider credentials, shell spawn authority, game-world keys, or broad network capability. - Prefer narrow game-session objects such as
AdventurePlayerandChatParticipantwith methods forlook, movement, inventory, status, combat actions, orders, delegation, chat send/history, and bounded event polling. A genericCommandSessionmay 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/tilemapfor 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-checkwhen 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-adventurewith 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 pinnedCAPOS_CUEandCAPOS_CAPNP, decode or validate the produced Cap’n Proto message, and include the freshness check inmake generated-code-check. -
make run-adventuremust 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.