> For the complete documentation index, see [llms.txt](https://faction-os.gitbook.io/faction-os-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://faction-os.gitbook.io/faction-os-docs/docs/game-design/10-technical-design-and-game-projection.md).

# Technical Design And Game Projection

**Project:** FactionOS --- The War Effort **Document role:** Technical design document

## 15. How Everything That Exists Connects (second pass)

The connection layer the first pass lacked. Every game mechanic in this document is a *derivation* over modules that already ship. One flow diagram, then the module-by-module wiring table.

```
REAL WORK
  packages/protocol/src/events.ts
  ~90 server events + 11 client verbs
    |
    v
single WS stream / wsEventBatcher
    |
    +-- existing derivations:
    |     missionTags, missionComplexity, heroSpecialization,
    |     heroEfficiency, costProjection, factionStandings,
    |     heroLeaderboard, missionHeatmap
    |
    +-- existing state/UI:
    |     useGameStore / roster, Battlefield.tsx, Quest/Notice Boards,
    |     War Room client/federation, SessionRollup / replay,
    |     ToastTray / achievements, audio, overlayLayers
    |
    +-- one new module:
          gameProjection.ts pure reducer

GAME PRESENTATION reads projection state only:
  camps, fog, banners, XP bars, patrols, bosses, Battle Report
```

**The single proposed new module:** `gameProjection.ts` --- a pure reducer folding the existing event stream + Quest Board model into one derived game state. Nothing else in the game layer owns state; every visual reads the projection. This mirrors how `factionStandings`/`heroLeaderboard` already work (pure functions over roster+events) and keeps the entire design testable the way those modules are tested today.

### Wiring table --- existing module -> game consumer

| Existing module (shipped)                                                                      | Feeds which game system                                                                                    | Section                  |
| ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------ |
| `events.ts` tool/mission/plan events                                                           | Essence income, combat playback, XP triggers                                                               | Sec. 3, Sec. 5A, Sec. 6  |
| `events.ts` dev-health (`test_failure`, `test_pass`, `build_*`, `ts_errors`, `lint_error`)     | Live Legion skirmishers/rams/gremlins                                                                      | Sec. 2, Sec. 3           |
| `scanCodebase.ts` + `questBoard*.ts` (Phase 18 scanners)                                       | Blight camps, camp HP, dawn patrol, Blight Titan                                                           | Sec. 2, Sec. 10          |
| `missionTags.ts` -> `heroSpecialization.ts`                                                    | Hero **class** identity, class barks, class icon; class-advantage muster bonus                             | Sec. 6, Sec. 6A          |
| `missionComplexity.ts` x `heroEfficiency.ts`                                                   | XP formula + efficiency multiplier (anti-Goodhart)                                                         | Sec. 6, Sec. 9           |
| `plans.ts` events (`plan_verification_complete`, budgets)                                      | Battle-plan ritual, verification bonus, supply lines                                                       | Sec. 3, Sec. 6           |
| `lineage.ts` (`subagent_lineage_update`)                                                       | Peon mini-units tethered to parent hero                                                                    | Sec. 3, Sec. 5A          |
| `missionHeatmap.ts` (path aggregation)                                                         | Sector activity heat -> fog pushback rates                                                                 | Sec. 5                   |
| `battlefield2d.ts` + `overlayLayers.ts`                                                        | Sector grid placement + camp/pennant/boss layer ordering                                                   | Sec. 5B                  |
| `battlefieldHeroes.ts` (12-cap selection)                                                      | Garrison overflow rule                                                                                     | Sec. 5B                  |
| `achievements.ts` engine + attribution                                                         | Titles pipeline, relic triggers, Hall of Banners stats                                                     | Sec. 6, Sec. 7           |
| `scrolls.ts` + `collect_scroll` verb                                                           | Loot layer, tome expansion, the one pure-game click                                                        | Sec. 7, Sec. 3A          |
| `factionStandings.ts` + `heroLeaderboard.ts`                                                   | Seasonal league, MVP hero in Battle Report                                                                 | Sec. 4, Sec. 8           |
| `warroom*.ts` (presence, federation, catch-up)                                                 | Allied standees, shared-front, Dawn Report catch-up                                                        | Sec. 8, Sec. 4           |
| `orchestrationCommandCenter.ts` + `taskQueue.ts`                                               | World Boss HP (campaign queue), Siege (stall escalations), rally orders                                    | Sec. 8, Sec. 10, Sec. 3A |
| `noticeBoard*.ts`                                                                              | Tavern contracts, courier ravens                                                                           | Sec. 8                   |
| `SessionRollup` + `replayLink.ts`                                                              | Battle Report, "watch the battle again", Dawn Report recap                                                 | Sec. 4                   |
| `costProjection.ts` / `factionCostProjection.ts`                                               | War chest (quiet), efficiency grading input                                                                | Sec. 9                   |
| `backgroundMusic.ts` (12 tracks) + `sfxAssets.ts` + `factionVoiceLines.ts` + `audioRuntime.ts` | Dynamic layering, barks, verb ceremonies                                                                   | Sec. 11, Sec. 3A         |
| `docs/game-design/manifest.md` + `mediaCatalog.ts` + provenance gates                          | Generated game-design asset inventory, boss standee art, relic/sigil art, source/runtime promotion records | Sec. 10, Sec. 11         |
| `hostedPersistence.ts` (achievement/scroll persistence path)                                   | Game projection persistence (territory, XP, seasons)                                                       | Sec. 16                  |
| ToastTray + `notifications.ts`                                                                 | Town Crier (game toasts junior to work toasts)                                                             | Sec. 11                  |
| Public demo parity pattern                                                                     | Synthetic front for pre-install visibility                                                                 | Sec. 5B                  |

**Reading of the table that matters:** there is no row whose left column is empty. The entire game, including the second-pass additions, is presentation

* one pure reducer over systems that already exist. That is the strongest objective evidence the design is buildable at high fun-per-engineering-hour.

**Generated asset authority:** production-generated visuals live in `docs/game-design/manifest.md` first. Runtime code should not discover assets directly from `assets/generated/game-design/`; the owning phase promotes a specific manifest asset through the app/catalog path it consumes, records public-demo mirror/cache behavior when applicable, and preserves live DOM text, fallbacks, reduced-motion parity, and accessibility labels.

**Third-pass correction to the wiring table:** `overlayLayers.ts` is the *cockpit-shell* z-contract (bottom rail 10 -> drawers 30---50, `z-[60..100]`) --- it governs surfaces stacked *above* the board, not layers inside it. Game elements on the battlefield use **board-internal stacking inside `Battlefield.tsx`** (see Sec. 13A layer order); `overlayLayers` only matters for game *surfaces* (Battle Report, war-table plan overlay), which must slot into that ladder like any other drawer.

### 15A. `gameProjection.ts` --- one level deeper (third pass, design-level)

**Shape.** One versioned, serializable object; every field is an aggregate (never an event log), so the persisted size stays small and constant-ish:

```ts
interface GameProjection {
  version: 1;
  // Territory (Phase C fills this; Phase A ships it empty)
  sectors: Record<SectorId, {          // SectorId = stable hash of dir/workspace group
    dirKey: string; cell: number;      // fixed grid cell (Sec. 5B)
    fogPct: number; lastTouchedAt: string;
  }>;
  // The Null Legion --- two tempos (Sec. 3)
  legion: {
    camps: Record<CampId, {            // CampId = sectorId (coalesced, Sec. 14.3)
      hp: number; maxHp: number;       // Sum severity weights: error 3 / warning 2 / info 1
      issueIds: string[];              // from suggestion_update CodebaseIssue.id
      tier: "camp" | "fort" | "citadel";
      entrenchedScans: number;         // Sec. 14.7 aging counter
      scarredPct: number;              // failed-attempt progress memory (Sec. 5A)
    }>;
    skirmishers: Record<string, { path: string; sinceAt: string }>;  // key = test path
    ram: { detail: string; sinceAt: string } | null;                 // build_error singleton
    gremlins: { tsErrors: number; tsFiles: number; lint: number };   // counts only
    wraiths: Record<HeroId, { stack: number; sinceAt: string }>;     // Sec. 14.8 stacked
    siege: { level: number; stalledTaskIds: string[] } | null;
  };
  // Camp-mission combat linkage (Sec. 5A, verified mechanism)
  pendingLinks: Array<{ campId: CampId; heroId: string; prompt: string; expiresAt: string }>;
  campLinks: Record<MissionId, CampId>;
  // Hero game identity (Phase B)
  heroes: Record<HeroId, {
    xp: number; level: number; titles: string[];
    quirkSeed: string;                 // = sessionId (deterministic cosmetics, Sec. 6)
    swiftCommand: { count: number; meanMs: number };
    banners: number; wraithKills: number;
  }>;
  // Economy (Phase C/D)
  essence: {
    fire: number; lore: number; forge: number;   // lifetime tithed totals
    treasury: number;                            // capped spendable (Sec. 7A)
    burst: Record<"fire" | "lore" | "forge", { windowStartAt: string; count: number }>;
  };
  buildings: Record<BuildingLine, { level: number; xp: number }>;
  // Fourth-pass additions (Phase B unless noted)
  warTide: {                             // Sec. 4 glance topline; trailing war-day window
    windowStartAt: string; gains: number; losses: number;
  };
  council: {                             // Sec. 4B session stakes; null until dawn draw
    warDay: string; rerolled: boolean;
    objectives: Array<{
      id: string; kind: "raze" | "relight" | "swift" | "nemesis" | "siege";
      refId: string; done: boolean;
    }>;
  } | null;
  nemeses: Record<string, {              // Sec. 10; key = stable source key (Phase D)
    name: string;                        // deterministic from key x name table
    source: "camp" | "test" | "wraith";
    refId: string; escalations: number; slainAt: string | null;
  }>;
  // Single-pulse alert authority (Sec. 14.6)
  alertFocus:
    | { kind: "flare" | "gate" | "siege" | "ram" | "skirmisher" | "newCamp"; refId: string }
    | null;
  // Meta
  season: { id: string; startedAt: string };
  flareCeremony: { recentFlares: number; windowStartAt: string };   // Sec. 14.5
  lastEventAt: string;
}
```

**Event -> mutation map** (reducer cases; everything else is ignored):

| Event(s)                                                                                   | Mutates                                                                                                                                                                                                                                             |
| ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `suggestion_update` (snapshot)                                                             | Phase 22 shipped behavior: explicit projection no-op for camps; Quest Board remains source of truth. Future camp reconciliation may coalesce issues per sector only in a later scoped phase.                                                        |
| `tool_use`                                                                                 | essence `burst` counters (+income after decay curve); combat strike emission if `missionId in campLinks` (presentation reads a transient strike queue, not persisted); `lastEventAt`                                                                |
| `mission_start`                                                                            | Dormant unless a caller already recorded a real pending link with `campId`, `heroId`, and verbatim `prompt`; then resolve `pendingLinks` to `campLinks` by hero and prompt match.                                                                   |
| `mission_complete` / `mission_update(failed)`                                              | banner/XP accrual (complexity x verification x swift x class-advantage Sec. 6A factors); camp `scarredPct` + nemesis escalation check (Sec. 10) on failure; `warTide` gains on verified success; council objective checks (Sec. 4B); clear campLink |
| `task_verification`, `plan_verification_complete`                                          | XP verification multiplier; camp kill authorization (Sec. 5A "kill shot")                                                                                                                                                                           |
| `test_failure` / `test_pass` / `build_error` / `build_fix` / `ts_errors` / `lint_error`    | `legion.skirmishers` / `ram` / `gremlins` (`test_pass` clears the matching skirmisher path; ram dies on `build_fix`)                                                                                                                                |
| `tool_result{ok:false}`, hero `error` state                                                | `wraiths[heroId].stack++` (capped, Sec. 14.8)                                                                                                                                                                                                       |
| `awaiting_input` / `input_received`                                                        | `alertFocus` recompute; `flareCeremony` window; swiftCommand timing on the answer                                                                                                                                                                   |
| `permission_request/response`, `guarded_action_update`, `command_center_permission_update` | Shared `attention.gates` authority for legacy permissions, guarded actions, and Command Center permissions; `alertFocus` selects the highest-priority gate pulse.                                                                                   |
| `task_stalled` / `task_escalation`                                                         | `legion.siege` level                                                                                                                                                                                                                                |
| `internal_hero_spawn` / `hero_dismissed`                                                   | `heroes` entry create / Hall-of-Banners freeze                                                                                                                                                                                                      |
| `scroll_collected`, `achievement_unlocked`                                                 | title/relic triggers (Phase D)                                                                                                                                                                                                                      |
| `mission_state`, `roster_update` (snapshots)                                               | reconciliation only --- never accumulate (Sec. 14.9)                                                                                                                                                                                                |
| first event of a new war day                                                               | `council` objective draw (deterministic picker, Sec. 4B); `warTide` window rollover                                                                                                                                                                 |
| skirmisher respawn / wraith cap hit (derived in existing cases)                            | nemesis promotion check (Sec. 10) --- renames existing state, adds no enemy logic                                                                                                                                                                   |

**Purity & guards.** Signature `reduce(state, event, ctx) -> state` where `ctx` carries `now` and `isReplaying` (from the store's existing `replayingSinceMs`). When `isReplaying`, all accumulation cases become no-ops; snapshot reconciliation still applies. Strike/juice emissions are *derived transients* handed to presentation, never stored.

**Persistence cadence** (mirrors the shipped replay-buffer pattern: `schedulePersist` debounce + versioned key): serialize to `localStorage["factionos-game-v1"]` on a \~2s idle debounce with a 30s max-latency flush and a flush on `visibilitychange/beforeunload`. The object is aggregates-only, so size is bounded by roster x titles, not by event volume. Boot order: hydrate persisted projection -> apply server hydration snapshots as reconciliation -> resume live folding. Cross-device/hosted persistence rides the existing `hostedPersistence` posture later (Sec. 16); localStorage is correct for Phase A because the projection is *derived* --- worst-case loss re-fogs cosmetic progress, never work state.

**Phase 22 shipped foundation notes.** The current source implements the v1 projection as a browser-local derived aggregate, persisted under `localStorage["factionos-game-v1"]`. The persisted aggregate includes `attention` so flare refs and gate refs survive browser re-entry without copying raw prompts, replay entries, terminal output, provider payloads, or file contents. `suggestion_update` intentionally remains a no-op for `legion.camps` in this phase; Quest Board snapshots stay authoritative until a later camp-reconciliation phase scopes the mapping. Camp links also remain dormant unless real `campId`, `heroId`, and verbatim `prompt` values are recorded before a matching `mission_start`. Browser-local erasure now removes the projection key through the existing browser storage cleanup inventory, and `resetToSeed()` removes the same key before resetting in-memory seed state. This is one browser-local cleanup path for derived projection state, not a trusted unified erasure claim.

## 15B. Implemented Shell And Orchestration Integration Points

These systems are not game state authorities. They are access, inspection, and execution surfaces that the game design can sensibly frame when the current design names them: flares, gates, rally orders, campaign bosses, siege states, claim pennants, trophies, handoffs, and town-crier notifications. Raw admin controls, validator caps, diagnostics, redaction rules, and local data hygiene remain utility-only and are held out in `12-utility-admin-holdout-inventory.md`.

### Cockpit Shell, Navigation, And Settings

Code references: `apps/web/src/App.tsx`, `apps/web/src/components/Layout.tsx`, `apps/web/src/components/BottomRailExpansionHost.tsx`, `apps/web/src/components/CommandPalette.tsx`, `apps/web/src/components/KeyboardShortcutsModal.tsx`, `apps/web/src/components/SettingsDrawer.tsx`, `apps/web/src/store/useSettingsStore.ts`, `apps/web/src/lib/commandPalette.ts`, `apps/web/src/lib/useKeyboardShortcuts.ts`, `apps/web/src/lib/notifications.ts`. Focused tests: `apps/web/tests/CommandPalette.test.tsx`, `apps/web/tests/KeyboardShortcutsModal.test.tsx`, `apps/web/tests/keyboardShortcuts.test.ts`, `apps/web/tests/useSettingsStore.test.ts`, `apps/web/tests/SettingsScan.test.tsx`, `apps/web/tests/settingsNotifications.test.ts`.

* The shell already tracks surface availability for battlefield, mission log, notice board, hero roster, scroll shelf, quest board, orchestration, and War Room.
* Bottom-rail expansion, focus restoration, focus containment, Escape closing, and transient expanded-surface persistence provide the cockpit surface model.
* Command palette and keyboard shortcuts already expose game-relevant jumps: trophy room, replay scrubber, settings, keyboard help, mission heatmap, faction standings/radar/efficiency, hero leaderboard, fleet tool usage, fleet mission complexity, Quest Board actions, and orchestration attention.
* Settings already carry the design-facing toggles: active faction, audio/volume, reduce motion, severity filters, browser notifications, scan root, Quest Board ignore patterns, roster sort, mock generator, and theme.
* Codebase scan state and scan-root selection are already available from settings; these feed Dawn Patrol/Legion setup without inventing a new scan UI.

### Orchestration Command Center

Code references: `packages/protocol/src/orchestrationCommandCenter.ts`, `packages/protocol/src/taskQueue.ts`, `packages/protocol/src/guardedActions.ts`, `packages/protocol/src/lineage.ts`, `apps/server/src/managers/orchestrationCommandCenter.ts`, `apps/server/src/managers/taskQueue.ts`, `apps/server/src/managers/planCampaignManager.ts`, `apps/server/src/managers/executorRegistry.ts`, `apps/server/src/managers/fileIntentManager.ts`, `apps/server/src/managers/fileMutationManager.ts`, `apps/server/src/managers/gitWorkbenchManager.ts`, `apps/server/src/managers/terminalSessionManager.ts`, `apps/server/src/managers/handoffManager.ts`, `apps/server/src/managers/channelCommandManager.ts`, `apps/server/src/routes/commandCenter.ts`, `apps/web/src/store/useGameStore.ts`, `apps/web/src/lib/commandCenterUi.ts`, `apps/web/src/lib/commandCenterShortcuts.ts`, `apps/web/src/lib/commandCenterMetrics.ts`, `apps/web/src/lib/commandCenterNotifications.ts`, `apps/web/src/components/orchestration/`. Focused tests: `packages/protocol/tests/orchestrationCommandCenter.test.ts`, `packages/protocol/tests/orchestration.test.ts`, `apps/server/tests/commandCenterRoutes.test.ts`, `apps/server/tests/commandCenterManager.test.ts`, `apps/server/tests/planCampaignManager.test.ts`, `apps/server/tests/taskExecutionCoordinator.test.ts`, `apps/web/tests/CommandCenterPanes.test.tsx`, `apps/web/tests/commandCenterUi.test.ts`, `apps/web/tests/commandCenterShortcuts.test.ts`.

* Command Center tabs already cover Overview, Campaigns, File/Git, Attention, Executors, Hero/Lineage, Diagnostics, Federation, and Metrics.
* Task queue records provide the campaign/boss substrate: states, priorities, sources, executable families, dispatch/retry/reject/restore/complete flows, linked hero/mission references, and compact six-row summaries.
* Agent templates provide a war-council substrate: roles, categories, tool scopes, suggestion reasons, memory filters, preview, and queue creation.
* Subagent lineage and mission graph data already track parent/child missions, spawned/active/completed/failed/degraded states, degraded reasons, graph nodes/edges, lineage roster filters, and compact graph rows.
* Hero lifecycle commands already cover spawn, fork, handoff, resume, message, stop, dismiss, model changes, permission-mode changes, isolation-mode changes, pause, restart, assign, and release; managed readiness distinguishes observed-only, ready, running, stopped, stale, and unavailable heroes.
* Guarded-action, attention, permission, review-gate, verification, evidence, file-intent, file-mutation, and workpad records are the concrete sources for gates, claims, trophies, proof, blocked tasks, failed verification, and Warchief decisions.
* Campaign workbench state already supports draft, awaiting approval, approved, in progress, paused, blocked, completed, cancelled, failed campaigns, dependency-aware task graphs, task refinement, dispatch, retry, pause, resume, cancel, and approval actions.
* Handoff, collaboration, War Room visibility, channel command, notification, usage metric, provider diagnostic, terminal runtime, and isolation runtime records are inspection and control surfaces. The game may summarize their state, but should not turn their low-level controls into progression rewards.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://faction-os.gitbook.io/faction-os-docs/docs/game-design/10-technical-design-and-game-projection.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
