> 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/sessions/phase23-session08-validation-and-documentation/phase-exit-audit.md).

# Phase 23 Exit Audit

**Session ID**: `phase23-session08-validation-and-documentation` **Phase**: 23 - Legion I - Scanner Camps **Package**: apps/web **Created**: 2026-07-05 **Status**: Complete - validation PASS and `updateprd` closeout recorded

***

## Evidence Baseline

| Evidence               | Result | Notes                                                                                                                                                                                                                                                                                                                                  |
| ---------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Focused Legion I tests | PASS   | `npm test -- apps/web/tests/legionCamps.test.ts apps/web/tests/gameProjection.test.ts apps/web/tests/gameProjectionStore.test.ts apps/web/tests/Battlefield.test.tsx apps/web/tests/QuestBoard.test.tsx apps/web/tests/questBoardActions.test.ts apps/web/tests/SettingsScan.test.tsx` passed 7 files and 137 tests under Node 26.2.0. |
| Web typecheck          | PASS   | `npm --workspace @factionos/web run typecheck` passed `tsc -b --noEmit`.                                                                                                                                                                                                                                                               |
| Root format check      | PASS   | `npm run format:check` passed with 781 files checked and no fixes applied.                                                                                                                                                                                                                                                             |
| Broader tests          | N/A    | No validation fix touched shared store, Quest Board, or battlefield behavior outside the focused files, so the spec did not require a broad `npm test` rerun.                                                                                                                                                                          |
| Prior session evidence | PASS   | Sessions 04-07 validation and security reports are PASS with no unresolved blockers.                                                                                                                                                                                                                                                   |

***

## Phase Exit Criteria Matrix

| Criterion                                                                                                                                                          | Status | Evidence                                                                                                                                                                                                                                                                                                                   |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Real scanner snapshots with codebase issues create visible battlefield camps through normal event flow.                                                            | PASS   | `apps/web/tests/gameProjection.test.ts` covers `suggestion_update` scanner issue folding into aggregate camps; `apps/web/tests/gameProjectionStore.test.ts` covers store `applyEvent` and persistence after explicit flush; `apps/web/tests/Battlefield.test.tsx` covers rendered ranked scanner camps.                    |
| Every rendered camp maps to at least one real current issue id and opens the matching Quest Board issue set.                                                       | PASS   | `apps/web/tests/legionCamps.test.ts` asserts sorted unique `issueIds`; `apps/web/tests/Battlefield.test.tsx` asserts camp click and keyboard inspection call Quest Board camp focus; `apps/web/tests/QuestBoard.test.tsx` asserts focused card filtering to active camp issue ids.                                         |
| Large issue sets coalesce into bounded readable sector camps with safe relative labels.                                                                            | PASS   | `apps/web/tests/legionCamps.test.ts` covers tiny repository splitting, large tail grouping into `Borderlands`, stable cells, and absolute/sensitive path label sanitization.                                                                                                                                               |
| Visible copy frames fronts, sectors, and current camp counts instead of overwhelming total debt.                                                                   | PASS   | `apps/web/tests/Battlefield.test.tsx` covers tier, sector, HP, issue count, Champion Mode limits, and scanner-state summaries; `apps/web/src/components/battlefield/CampLayer.tsx` renders aggregate product labels only.                                                                                                  |
| Entrenched camps are quieter but remain inspectable and do not create bosses, rewards, Dawn Report behavior, or progress.                                          | PASS   | `apps/web/tests/legionCamps.test.ts` covers entrenchment ranking metadata; `apps/web/tests/Battlefield.test.tsx` covers entrenched edge presentation and inspectability; `apps/web/tests/gameProjection.test.ts` covers preservation of rewards, links, camp damage, and unrelated projection fields during scanner folds. |
| Banish dismisses real issues through existing Quest Board actions and gives no game reward.                                                                        | PASS   | `apps/web/tests/questBoardActions.test.ts` covers existing issue dismiss routes and safe issue ids; `apps/web/tests/QuestBoard.test.tsx` covers camp Banish control and pending state; `apps/web/tests/Battlefield.test.tsx` covers dry Banish through the store.                                                          |
| One-hero and two-hero rosters show a small prioritized camp set instead of the full census.                                                                        | PASS   | `apps/web/tests/legionCamps.test.ts` covers Champion Mode visible limits for zero, solo, duo, squad, and army rosters; `apps/web/tests/Battlefield.test.tsx` covers limited visible camps.                                                                                                                                 |
| A clean scan shows Golden Age; a not-yet-scanned state does not masquerade as Golden Age.                                                                          | PASS   | `apps/web/tests/Battlefield.test.tsx` covers canonical clean scanner snapshot Golden Age and scan-not-run before any canonical snapshot; `apps/web/tests/gameProjection.test.ts` covers successful clean snapshots clearing camps.                                                                                         |
| Reduced-motion mode has complete static equivalents.                                                                                                               | PASS   | `apps/web/tests/Battlefield.test.tsx` covers reduced-motion battlefield frame, static scout badge, camp marker data, and static achievement bursts.                                                                                                                                                                        |
| Replay cannot mutate or persist camp progress.                                                                                                                     | PASS   | `apps/web/tests/gameProjection.test.ts` covers replayed scanner snapshots staying camp-inert; `apps/web/tests/gameProjectionStore.test.ts` covers replay dispatch leaving projection storage unchanged.                                                                                                                    |
| Mock mode can show camps in memory but cannot persist them.                                                                                                        | PASS   | `apps/web/tests/gameProjection.test.ts` covers mock snapshots folding in memory and `shouldPersistGameProjection` returning false; `apps/web/tests/gameProjectionStore.test.ts` covers mock mode storage remaining unchanged.                                                                                              |
| No new protocol event, storage key, hosted dependency, or trusted-erasure claim is introduced.                                                                     | PASS   | Focused tests and source inspection use existing `suggestion_update`, existing `factionos-game-v1`, existing local routes, and no package changes; detailed boundary inventory is below.                                                                                                                                   |
| No camp projection stores raw issue text, prompts, transcripts, terminal output, provider payloads, file contents, absolute paths, environment values, or secrets. | PASS   | `apps/web/tests/legionCamps.test.ts` covers aggregate-only camp output; `apps/web/tests/gameProjection.test.ts` covers raw scanner detail omission; `apps/web/tests/gameProjectionStore.test.ts` covers serialized projection omission of raw scanner values.                                                              |

***

## Testing Requirements

| Requirement                                                               | Status | Evidence                                                                                                                                         |
| ------------------------------------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| Focused Phase 23 web test command passes.                                 | PASS   | 7 files and 137 tests passed.                                                                                                                    |
| `npm --workspace @factionos/web run typecheck` passes.                    | PASS   | `tsc -b --noEmit` exited 0.                                                                                                                      |
| `npm run format:check` passes.                                            | PASS   | Biome checked 781 files; no fixes applied.                                                                                                       |
| Broader tests run if fixes touch shared behavior outside focused files.   | N/A    | T007 required no code repair and no `apps/web/src` or `apps/web/tests` diff exists from Session 08.                                              |
| Validation output and residual failures recorded in implementation notes. | PASS   | `.spec_system/specs/phase23-session08-validation-and-documentation/implementation-notes.md` records T004-T008 evidence and no residual blockers. |

***

## Privacy, Storage, And Honesty Boundary Audit

| Boundary                        | Status | Evidence                                                                                                                                                                                                                                                                                                                                                                                          |
| ------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Projection privacy data shape   | PASS   | `apps/web/src/lib/legionCamps.ts` builds camp groups from `CodebaseIssue` inputs but writes only `campId`, `sectorId`, safe sector metadata, sorted `issueIds`, HP, tier, entrenchment, scars, cells, and timestamps into projection records. Tests assert raw titles, messages, prompts, terminal output, provider payloads, file contents, absolute paths, env values, and secrets are omitted. |
| Safe sector labels              | PASS   | `normalizeLegionIssuePathSegments` and sector label helpers sanitize paths, collapse sensitive segments to `redacted`, and fall back to bounded labels; `apps/web/tests/legionCamps.test.ts` covers absolute and sensitive path labels.                                                                                                                                                           |
| Storage key                     | PASS   | `GAME_PROJECTION_STORAGE_KEY` is `factionos-game-v1` in `apps/web/src/lib/gameProjection.ts`; `persistGameProjection` only writes that key, and `removePersistedGameProjection` removes the same key.                                                                                                                                                                                             |
| Replay persistence guard        | PASS   | `reduceSuggestionUpdate` returns the existing projection when `ctx.isReplaying` is true, and `applyEvent` skips replay capture while `replayingSinceMs` is set. `shouldPersistGameProjection` returns false when replaying.                                                                                                                                                                       |
| Reconnect and hydration honesty | PASS   | `connected` events do not create camp progress, while real non-replay `suggestion_update` snapshots remain the only camp reconciliation input. `apps/web/tests/gameProjectionStore.test.ts` covers post-boot scanner reconciliation and real clean snapshots removing camps.                                                                                                                      |
| Failed scan honesty             | PASS   | `reduceSuggestionUpdate` returns the existing projection when `event.scanStatus.status === "failed"`, preserving current camps without pretending a failed scan is clean.                                                                                                                                                                                                                         |
| Mock mode persistence guard     | PASS   | `shouldPersistGameProjection` returns false when `mockEnabled` is true. Store persistence scheduling uses that guard, so mock camps can fold in memory without writing durable projection storage.                                                                                                                                                                                                |
| Dry Banish action               | PASS   | `banishQuestBoardCamp` selects current focused issue cards, guards duplicate action keys, calls `dismissQuestBoardIssue`, rolls back failed optimistic removals, and clears pending keys in `finally`. It does not touch projection progress, rewards, HP, storage, or protocol events.                                                                                                           |
| Dry Banish route                | PASS   | `dismissQuestBoardIssue` validates the issue id and posts to the existing `/issues/:issueId/dismiss` local route with `{ issueId }`; no new route or reward endpoint is introduced.                                                                                                                                                                                                               |
| Reduced-motion parity           | PASS   | `ScannerStateLayer` renders static labels and a reduced-motion scout badge when `reduceMotion` is true; `index.css` removes camp/scanner animations and transitions while preserving camp chips, marker opacity, and static labels.                                                                                                                                                               |

***

## Fun Audit

| Check                  | Status | Evidence                                                                                                                                                                                                                                                                                                                  | Residual Boundary                                                                                                           |
| ---------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| Glance classification  | PASS   | `apps/web/tests/Battlefield.test.tsx` covers Golden Age, scan-not-run, Dispatch Scouts running, scan failed with existing camps, mock drill labeling, zero-hero neutrality, and visible ranked camps. `ScannerStateLayer` exposes label, detail, static label, tone, camp count, hero count, scan scope, and scan status. | This is component-level local browser evidence, not a formal UX study or mobile certification.                              |
| Source inspection      | PASS   | Camp marker activation calls Quest Board focus with the camp issue ids; `QuestBoard.test.tsx` proves focused cards filter to those ids and return to normal when cleared.                                                                                                                                                 | Quest Board may show richer card details because it owns those issue cards; projection state must not copy the raw details. |
| Honesty                | PASS   | Replay returns existing projection state, mock mode blocks durable projection writes, failed scans preserve existing camps, and Banish dismisses current issue cards without rewards, HP changes, kills, XP, loot, banners, achievements, or Dawn Report behavior.                                                        | Live combat playback, camp damage, rewards, and mission strike semantics remain future Phase 24+ work.                      |
| Silence and calm state | PASS   | Clean canonical scans render Golden Age, not fake danger; not-yet-scanned state remains distinct from Golden Age; zero-hero state stays neutral; event-free clean boards do not mint synthetic camps.                                                                                                                     | Public-demo synthetic fronts and War Games remain future scoped work and are not claimed for the shipped app.               |
| Reduced-motion parity  | PASS   | Reduced-motion tests and CSS keep static scanner labels, camp tier, sector, HP, issue count, chips, marker opacity, and scout state while removing motion-only treatment.                                                                                                                                                 | This is scoped reduced-motion regression evidence, not formal WCAG certification.                                           |

***

## No-New-Boundary Inventory

| Boundary               | Status | Evidence                                                                                                                                                                                                                              |
| ---------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Protocol events        | PASS   | `git diff --name-only ba6c30994180c399dd3d68607812867fbe7b001c -- packages/protocol/src/events.ts` produced no output. Phase 23 uses existing `suggestion_update`.                                                                    |
| Server routes          | PASS   | `git diff --name-only ba6c30994180c399dd3d68607812867fbe7b001c -- apps/server/src` produced no output. Camp inspection and Banish stay on existing Quest Board routes.                                                                |
| Dependencies           | PASS   | `git diff --name-only ba6c30994180c399dd3d68607812867fbe7b001c -- package.json package-lock.json apps/web/package.json apps/web/package-lock.json` produced no output. No hosted dependency or package change was introduced.         |
| Projection storage key | PASS   | Storage-key search found the existing `GAME_PROJECTION_STORAGE_KEY` and `factionos-game-v1` references plus unrelated pre-existing browser keys; focused store tests assert no camp-specific storage keys.                            |
| Hosted state           | PASS   | No package, server, protocol, or app route diff creates hosted storage, hosted identity, production-hosted validation, or remote state for camps. Docs keep hosted claims as no-claim until a later scoped phase proves them.         |
| Reward path            | PASS   | Camp and Banish code paths do not mutate XP, loot, achievements, banners, camp kills, Dawn Report, or Battle Report. Existing achievement code in `Battlefield.tsx` is the pre-existing celebration path and is not called by Banish. |
| Trusted-erasure claim  | PASS   | Phase 23 keeps projection erasure browser-local and continues to describe full trusted unified erasure as unavailable/no-claim.                                                                                                       |

***

## Non-Functional Requirements

| Requirement                                                                               | Status | Evidence                                                                                                                                                                                                                                              |
| ----------------------------------------------------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GameProjection` remains the only derived game-state authority for camps.                 | PASS   | Camp reconciliation evidence is in `apps/web/src/lib/gameProjection.ts`, `apps/web/src/lib/legionCamps.ts`, and store selectors; no parallel camp state file or new protocol source was introduced.                                                   |
| Projection storage remains `localStorage["factionos-game-v1"]` only.                      | PASS   | `apps/web/tests/gameProjectionStore.test.ts` covers the existing storage key and no camp-specific storage keys.                                                                                                                                       |
| Documentation describes shipped behavior only and preserves no-claim boundaries.          | PASS   | Stable docs now document shipped scanner camps, Dispatch Scouts, Golden Age, dry Banish, aggregate-only projection data, browser-local storage, ledgers, PRD wording, and no-claim boundaries without marking workflow completion before `updateprd`. |
| Phase-exit audit records glance, source, honesty, silence, and reduced-motion fun checks. | PASS   | Fun audit section above records all five required checks with evidence and residual boundaries.                                                                                                                                                       |


---

# 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/sessions/phase23-session08-validation-and-documentation/phase-exit-audit.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.
