> 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/.spec_system/archive/phases/phase_22/session_01_projection_contract.md).

# Session 01: Projection Contract

**Session ID**: `phase22-session01-projection-contract` **Package**: apps/web **Status**: Not Started **Estimated Tasks**: \~12-25 **Estimated Duration**: 2-4 hours

***

## Objective

Establish the `gameProjection.ts` public contract, complete v1 state shape, and defensive storage helpers without store wiring or broad event folding.

***

## Scope

### In Scope (MVP)

* Create `apps/web/src/lib/gameProjection.ts` with version constants, storage key, persistence cadence constants, exported projection types, reducer context types, persistence context types, and serializable subtypes.
* Implement `createInitialGameProjection(now?)` with the full neutral v1 shape for sectors, legion, links, heroes, essence, buildings, War Tide, council, nemeses, alert focus, season, flare ceremony, and `lastEventAt`.
* Implement defensive `parsePersistedGameProjection`, `loadPersistedGameProjection`, `persistGameProjection`, and `shouldPersistGameProjection` helpers that tolerate unavailable storage, malformed JSON, wrong versions, quota failures, and null storage.
* Add the initial pure tests in `apps/web/tests/gameProjection.test.ts` for full shape, deterministic timestamps, deterministic season id, malformed persisted input, JSON round trip, and source-of-truth exclusions.

### Out of Scope

* Follow the explicit out-of-scope and deferred-work boundaries in the Dependencies / Notes section below.
* Do not add rendering, audio, hosted persistence, protocol changes, or a second game state authority unless this session explicitly lists that work as in scope.

***

## Dependencies / Notes

* None.
* Out of scope: store folding, debounced persistence scheduling, event reducer breadth beyond same-reference unknown events, rendering, audio, toasts, hosted persistence, and protocol changes.
* The state contract must not duplicate faction selection, scroll ownership, achievement ownership, War Room membership, settings, Notice Board messages, visible hero slots, replay entries, animation state, audio state, or raw prompt logs.

***

## Prerequisites

* [ ] Phase 22 PRD reviewed, including the integrated source brief.

***

## Deliverables

1. New projection library module with a complete versioned aggregate contract.
2. Pure projection contract tests that do not depend on React rendering or store lifecycle.

***

## Success Criteria

* [ ] `createInitialGameProjection()` returns the full v1 shape with neutral future-owned fields and injected time.
* [ ] Persisted parsing returns a valid fresh projection for missing, malformed, unsupported, or unsafe input.
* [ ] JSON serialization contains only aggregate projection state, not presentation transients or copied source-of-truth data.
* [ ] Unknown reducer behavior returns the exact same state reference until later sessions expand reducer coverage.


---

# 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/.spec_system/archive/phases/phase_22/session_01_projection_contract.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.
