> For the complete documentation index, see [llms.txt](https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/.spec_system/archive/phases/phase_34/prd_phase_34.md).

# PRD Phase 34: AI Rogue Audit Remediation

**Status**: Complete **Sessions**: 8 (initial estimate) **Estimated Duration**: 6-10 days

**Progress**: 8/8 sessions completed and validated (100%)

***

## Overview

Phase 34 converts the completed AI Rogue comprehensive audit into a scoped remediation phase. The phase fixes the default-enablement blockers and refactor prerequisites recorded in `.spec_system/PRD/phase_35/PRD_phase_35.md` while preserving the explicit opt-in posture, local-only game state, static public-demo boundary, and established quality gates.

The complete audit method and execution record from the former ongoing-project audit plan is migrated into Appendix A of this PRD. References to the old path inside Appendix A are historical log entries, not active dependencies.

The audit promoted no privacy, hosted storage, network, public-demo server write, raw private LiveData render, raw private persistence, or seed-share leak finding. Phase 34 therefore focuses on accessibility, correctness, architecture, renderer lifecycle, schema/persistence, performance, documentation drift, and validation evidence rather than adding new data collection or hosted runtime behavior.

***

## Progress Tracker

| Session | Name                                     | Status   | Est. Tasks | Validated  |
| ------- | ---------------------------------------- | -------- | ---------- | ---------- |
| 01      | Characterization Test Harness            | Complete | \~12-25    | 2026-06-26 |
| 02      | Accessibility And Compact Input          | Complete | \~12-25    | 2026-06-26 |
| 03      | Simulation Correctness And Scenario Gate | Complete | \~12-25    | 2026-06-26 |
| 04      | Renderer Lifecycle And Robustness        | Complete | \~12-25    | 2026-06-26 |
| 05      | Runtime API Ownership                    | Complete | \~12-25    | 2026-06-26 |
| 06      | Persistence Schema Contracts             | Complete | \~12-25    | 2026-06-26 |
| 07      | Render Performance And Audio Docs        | Complete | \~12-25    | 2026-06-26 |
| 08      | Default Enablement Evidence Closeout     | Complete | \~12-25    | 2026-06-26 |

***

## Completed Sessions

* Session 01: Characterization Test Harness - Complete 2026-06-26. Added characterization coverage for lethal turn-start status command behavior, runtime summary exposure, transient Pixi feedback sprite retention, oversized direct claim drift, and durable saved-run conversion seams while preserving disabled-first browser-local behavior and leaving product fixes to later remediation sessions.
* Session 02: Accessibility And Compact Input - Complete 2026-06-26. Added a dynamic screen-reader runtime summary, compact Inspect and Next target controls through the existing touch command path, Large HUD Labels runtime projection behavior, and focused unit/mobile coverage while preserving the browser-local public-demo boundary.
* Session 03: Simulation Correctness And Scenario Gate - Complete 2026-06-26. Centralized lethal turn-start status handling across Movement, Strike, Surge, and Protocol, removed product-route combat fixture query behavior, preserved deterministic combat coverage through a local/test-only hook, and updated developer docs and tests.
* Session 04: Renderer Lifecycle And Robustness - Complete 2026-06-26. Destroyed inactive transient feedback sprites, coalesced browser resize work, hardened reduced-motion media-query setup, covered renderer setup and audio fallback paths, and preserved gameplay rules, local-only state, and product-facing Play route copy.
* Session 05: Runtime API Ownership - Complete 2026-06-26. Moved pre-run selected-upgrade and progression-loadout ownership into simulation APIs, rewired renderer/controller calls to request those transitions, narrowed the mounted runtime entrypoint, and added boundary tests that keep fixtures and broad internals out of the public barrel.
* Session 06: Persistence Schema Contracts - Complete 2026-06-26. Routed durable claim writes through schema-owned normalization, rejected oversized direct claims before wallet or ledger mutation, renamed durable saved-run snapshot contracts, moved durable-to-runtime hydration into the save schema, and expanded persistence, save-schema, claim-store, and Runtime Canvas tests.
* Session 07: Render Performance And Audio Docs - Complete 2026-06-26. Added a renderer-local latest-value render projection cache with invalidation for lifecycle, state, viewport, preference, and seed metadata changes; preserved per-frame presentation work; updated audio/media documentation to remove unimplemented ducking claims and distinguish historical no-audio and 200 KB evidence from the current Web Audio and 900 KB music-cap policy.
* Session 08: Default Enablement Evidence Closeout - Complete 2026-06-26. Reran the closeout gate matrix, recorded targeted privacy/boundary scans, updated AI Rogue audit, enablement, runtime-data, security/compliance, and PRD docs, preserved explicit opt-in, and recorded Conditional Go for a future default-enable product action.

***

## Upcoming Sessions

No further implementation sessions are planned for Phase 34. The next workflow step is `audit` because Phase 34 is complete and the workflow is entering Phase Transition.

## Session 08 Implementation Closeout

Closeout source: `phase34-session08-default-enablement-evidence-closeout`.

Recommendation: Conditional Go for a future default-enable product action. This implementation session did not flip product configuration; AI Rogue remains explicit opt-in through `VITE_CLAUDE_OS_ENABLED_EXTENSIONS` until a separate validated product change intentionally changes visibility.

Closed original default-enable blockers:

| Finding ID | Status | Closing evidence                                                                                                                   |
| ---------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| AR-D6-001  | Fixed  | Dynamic assistive summary, compact Inspect/Next controls, Large HUD projection behavior, and mobile/unit coverage from Session 02. |
| AR-D2-001  | Fixed  | Central lethal turn-start handling across Movement, Strike, Surge, and Protocol from Session 03.                                   |
| AR-D1-002  | Fixed  | Product-facing combat query scenario removed; deterministic combat coverage moved to local/test-only hook in Session 03.           |
| AR-D4-001  | Fixed  | Inactive transient `feedback:*` sprites destroyed with renderer lifecycle coverage from Session 04.                                |

Security and GDPR posture: Phase 34 introduces no new personal-data collection, account flow, consent flow, hosted persistence, analytics, runtime upload path, AI Rogue collector, Pages Function, or third-party transfer. Targeted closeout scans found no AI Rogue bridge call, hosted write, collector, analytics, Function, remote game-content loading, private path, credential, raw prompt, provider body, or raw telemetry path. Public-demo AI Rogue state remains browser-local and Pages route smoke rejects `/__*` route requests.

Gate evidence summary:

| Gate group        | Result           | Evidence                                                                                                                                                                       |
| ----------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Static quality    | PASS             | Typecheck, script typecheck, lint, format check after Session 08 markdown formatting, and `git diff --check HEAD` passed.                                                      |
| Unit tests        | PASS             | Full Vitest passed 382 files / 4,338 tests; focused AI Rogue passed 45 files / 307 tests; host extension tests passed 4 files / 75 tests.                                      |
| Build/artifacts   | PASS             | Production build, app budget, asset-size, and private-runtime checks passed; app budget was 1,490 KB / 1,500 KB JS gzip and 275 KB / 300 KB CSS.                               |
| AI Rogue browser  | PASS             | 16 Chromium tests passed across runtime, mobile, ledger, persistence, and enablement specs.                                                                                    |
| Pages demo        | PASS             | Pages build, privacy scan, and budget passed; Pages budget was 1,490 KB / 1,500 KB JS gzip and 275 KB / 300 KB CSS.                                                            |
| Pages route smoke | PASS             | 48 `pages-demo-chromium` tests passed, including AI Rogue Play, Ledger, Loadout, Settings, mobile no-overflow, painted canvas, compact movement, and no `/__*` route requests. |
| Playthrough       | PASS with caveat | 6 deterministic seeds exited 0: 2 won, 1 lost, and 3 remained active at the 4,000-turn harness cap on depth 3.                                                                 |

Handoff facts:

* Phase Transition starts next with `audit`.
* Any future product action that changes default visibility should rerun the closeout gate bundle and preserve the no-new-D3 boundary.

***

## Objectives

1. Add characterization coverage before changing high-risk AI Rogue runtime, simulation, renderer, persistence, accessibility, and compact-input paths.
2. Fix the audit's default-enablement blockers: dynamic accessible runtime summary, lethal turn-start status handling, production combat scenario gate, and transient Pixi sprite retention.
3. Narrow runtime ownership so run-state transitions flow through simulation APIs and durable save/claim contracts flow through schema-owned helpers.
4. Reduce renderer hot-loop, resize, media-query, platform-fallback, and audio/doc drift risk without adding remote loading or hosted game state.
5. Re-run complete AI Rogue, Pages demo, privacy, budget, and release gates and record a renewed default-enablement recommendation.

***

## Prerequisites

* Phase 33 completed.
* Appendix A in this file preserves the original AI Rogue audit plan, Sessions 01-14 execution log, mechanical checks, project gates, output contract, completion criteria, and final synthesis status that were formerly tracked in the ongoing-project audit plan.
* `.spec_system/PRD/phase_35/PRD_phase_35.md` exists and preserves the historical No-Go default-enablement verdict, follow-up backlog, and Phase 34 closeout recommendation.
* AI Rogue remains explicit opt-in unless a later validated decision changes that posture.

***

## Planning Assumptions And Resolutions

### Working Assumptions

* Phase 34 should be built from the completed audit findings rather than from a pre-existing master PRD row. Evidence: the user supplied the completed audit plan now migrated into Appendix A, the plan says follow-up implementation should start from `.spec_system/PRD/phase_35/PRD_phase_35.md`, and that report lists concrete blockers, coverage gaps, doc drift, and an ordered backlog. It is safe to proceed because the work is bounded and source-backed.
* The phase should remediate and re-evaluate default enablement, not force a default-on change. Evidence: the audit report verdict was No-Go until blockers were fixed or explicitly accepted with compensating coverage. This phase can close with a renewed recommendation even if a product decision remains separate.

### Conflict Resolutions

* PRD/state tracking ended at completed Phase 33 while the user-supplied audit plan and final findings report define new unfinished work. Chosen interpretation: create Phase 34 from the audit remediation backlog and update `.spec_system/state.json` plus `.spec_system/PRD/PRD.md` so tracking reflects the new phase.

***

## Remediation Source Map

| Phase 34 Session | Migrated audit source                                                   | Primary findings and evidence carried forward                                                                                                                                                     |
| ---------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 01               | Audit Sessions 01, 12, 13, and 14; D8 coverage gaps; evidence appendix  | Baseline inventory, gate results, lethal-DOT matrix, dynamic assistive summary coverage, sprite-pool bound, direct claim validation, durable snapshot hydration, and refactor-precondition tests. |
| 02               | Audit Session 10; D6 accessibility/input; D8 UI coverage gaps           | AR-D6-001, AR-D6-002, AR-D6-003, AR-D8-001, and AR-D8-003. Dynamic screen-reader summary, compact Inspect/Next target reachability, and Large HUD implementation or removal.                      |
| 03               | Audit Sessions 03 and 04; D1/D2 architecture and correctness            | AR-D2-001 and AR-D1-002. Central lethal turn-start status handling and removal or gating of production `scenario=combat` fixture behavior.                                                        |
| 04               | Audit Sessions 07 and 11; D4/D7 runtime lifecycle and robustness        | AR-D4-001, AR-D4-003, AR-D7-001, and AR-D8-002. Transient sprite cleanup, resize coalescing, media-query compatibility, setup-failure, asset, audio, and storage fallbacks.                       |
| 05               | Audit Sessions 03, 09, and 13; runtime API/refactor map                 | AR-D1-001 and AR-D1-003. Move selected-upgrade/loadout mutation into simulation-owned APIs and narrow the runtime barrel before large file splits.                                                |
| 06               | Audit Sessions 05, 09, and 13; economy, persistence, schemas            | AR-D5-001 and AR-D5-002. Normalize claim writes, prevent wallet/ledger drift, rename durable snapshots, and add schema-owned hydration helpers.                                                   |
| 07               | Audit Sessions 07, 08, 13, and 14; performance, assets, audio, docs     | AR-D4-002, AR-D9-001, AR-D9-002, and related D8 gaps. Bound render projection work, preserve asset/bundle policy, and reconcile audio ducking/media documentation.                                |
| 08               | Audit Sessions 01, 08, 12, and 14; final report and completion criteria | Full gate rerun, no-new-D3-finding privacy posture, public-demo static/browser-local safety, doc/security updates, and renewed default-enablement verdict.                                        |

Carry the migrated audit source as evidence. If current source code differs from the archived line numbers, prefer current source truth but preserve the finding IDs, risk statements, and gate expectations until explicitly closed.

***

## Technical Considerations

### Architecture

AI Rogue remains a compile-time registered extension under `src/extensions/ai-rogue/`. Host extension enablement, public-demo mode, and LiveData delivery stay in host-layer files. Simulation/content modules must stay free of Pixi, DOM, React, persistence, browser globals, route state, and host LiveData. Renderer code can own mounted browser resources, but run-state transitions should move through simulation-owned APIs.

### Technologies

* React 19 and TanStack Start host routes.
* PixiJS v8 runtime behind the AI Rogue Play route.
* TypeScript and Zod schema-backed durable browser state.
* Vitest and Playwright for characterization, unit, route, and public-demo coverage.
* Bun/Vite 8 build, budget, asset, privacy, and Pages demo gates.

### Risks

* Fixes can regress current explicit opt-in gameplay. Mitigation: start with characterization tests and preserve existing AI Rogue unit/e2e coverage.
* Refactors can hide current defects behind new file boundaries. Mitigation: fix or characterize default-enablement blockers before splitting modules.
* Accessibility preferences can become nominal controls without behavior. Mitigation: require positive runtime/DOM coverage for dynamic summaries, compact verbs, and Large HUD behavior or remove unsupported UI.
* Bundle and asset budgets are tight. Mitigation: no new large media or eager runtime loading, and run budget/asset gates in closeout.
* Public-demo safety can drift. Mitigation: keep game state browser-local, make no `/__*` bridge calls, and rerun Pages build/scan/budget/mobile smoke.

### Relevant Considerations

* \[P30/P32] **AI Rogue default enablement deferred**: This phase may prepare a renewed recommendation, but default enablement still needs blocker closure, real evidence, and product decision.
* \[P31-P33] **Pages demo stays static-only**: AI Rogue public-demo behavior must remain browser-local with no local bridge calls, hosted writes, collectors, analytics, Functions, or advanced Workers.
* \[P30/P32] **Route-lazy runtime ownership scales**: Keep Pixi behind the Play route/local facade; React owns coarse state and raw-to-effective adapters while Pixi owns frames and cleanup.
* \[P30/P32] **Schema-backed browser-local state works**: Keep Zod defaults, migrations, localStorage, IndexedDB, reset, and save contracts explicit.
* \[P31-P33] **Route smoke is a privacy gate**: Public demo route smoke and no `/__*` assertions remain part of release proof.

***

## Success Criteria

Phase complete when:

* [x] All 8 sessions completed.
* [x] AR-D6-001, AR-D2-001, AR-D1-002, and AR-D4-001 are fixed with focused coverage or explicitly carried as remaining No-Go blockers.
* [x] Runtime API ownership and durable schema/persistence contracts are narrower and covered before larger refactors proceed.
* [x] AI Rogue remains explicit opt-in unless a validated closeout decision says otherwise.
* [x] Public-demo AI Rogue state remains browser-local and Pages routes make no `/__*` bridge or mutation requests.
* [x] Typecheck, lint, format, build, budget, asset, privacy, AI Rogue unit, AI Rogue e2e, Pages build/scan/budget, and Pages mobile gates are recorded.
* [x] AI Rogue docs, audit findings follow-up notes, security/compliance notes, and PRD state agree on the final posture.

***

## Dependencies

### Depends On

* Phase 33: Cloudflare Pages Real Product Fixtures
* `.spec_system/PRD/phase_35/PRD_phase_35.md`
* Appendix A in this file: migrated AI Rogue audit plan and execution log

### Enables

* Future AI Rogue default-enablement decision or follow-up refactor phase.
* Safer oversized-module refactors across simulation, renderer, effects, persistence, render-model, world, and shared runtime types.

***

## Appendix A - Migrated Audit Plan And Execution Log

This appendix migrates the complete contents formerly stored at `docs/ongoing-projects/ai-rogue-audit-plan.md`. It preserves the audit method, session split plan, dimensions, mechanical checks, project gates, output contract, execution log, final synthesis status, findings queued during execution, refactor map inputs, command evidence, and remaining-work notes. Markdown headings from the source were demoted so the content nests under this Phase 34 PRD; historical references to the old path remain part of the archived execution log.

### AI Rogue Comprehensive Code And Architecture Audit Plan

#### Session Split Plan

**Session 01: Audit Baseline**

**Objective**: Establish the current audit baseline before judging any code.

**Scope**:

* Validate the current source, test, e2e, asset, host-wiring, and documentation inventory listed in the plan.
* Run the cheap mechanical checks and record raw results for later triage.
* Run the project gates that can fail independently of AI Rogue findings.
* Confirm the target findings report path and evidence appendix structure.

**Outputs**:

* Current inventory counts for source files, unit specs, AI Rogue e2e specs, public-demo e2e coverage, assets, and referenced docs.
* Gate status table with command, pass/fail, failure summary, and caveats.
* Mechanical-check hit list grouped by likely audit dimension.

**Dependencies / Notes**:

* This is a measurement session, not a repair session.
* If a gate fails from unrelated repo state, record it as baseline evidence and continue the audit.
* Assumption: the execution pass may create or update `.spec_system/PRD/phase_35/PRD_phase_35.md`.

**Acceptance Checks**:

* Every command listed under Mechanical Checks has either run or has a documented reason it could not run.
* Every command listed under Project Gates has pass/fail/not-run status with enough detail to reproduce.
* No product code has been changed.

**Session 02: Source Contracts**

**Objective**: Define the source-of-truth contracts the code will be audited against.

**Scope**:

* Read `docs/extensions/ai-rogue/README.md` and every linked AI Rogue document in full.
* Classify current-maintenance docs, historical session docs, and known drift hotspots.
* Read host extension docs and repo conventions that affect extension boundaries.
* Build a doc-contract matrix for enablement, privacy, runtime data, assets, audio, input, public-demo behavior, and default-on readiness.

**Outputs**:

* Contract matrix that maps each asserted behavior to source docs and owning code areas.
* Initial doc-vs-doc drift candidates, clearly separated from doc-vs-code findings.
* Assumptions list for historical docs that should be treated as evidence rather than current contract.

**Dependencies / Notes**:

* Depends on Session 01 inventory so stale counts are not carried forward.
* Open question carried forward: whether stale historical session-closeout docs should be edited in place or superseded from current docs.

**Acceptance Checks**:

* Every file under `docs/extensions/ai-rogue/` is accounted for.
* Current-contract docs are separated from historical-only docs.
* Known hotspots from the plan are explicitly checked or queued for later evidence.

**Session 03: Architecture Boundaries**

**Objective**: Verify the AI Rogue layering, import graph, and host/game boundaries.

**Scope**:

* Audit D1 architecture and module boundaries across extension shell, host routing, views, simulation, content, render pipeline, audio, persistence, and tooling.
* Build the real import graph and identify cycles, back-edges, runtime imports from non-runtime routes, and god-module pressure.
* Confirm simulation/content modules avoid Pixi, DOM, React, browser globals, persistence, and host concerns.
* Confirm public-demo enablement and LiveData routing stay in host-layer code.

**Outputs**:

* Architecture findings with file:line evidence.
* Boundary map that shows allowed imports and any violations.
* Initial oversized-module notes for later refactor-map synthesis.

**Dependencies / Notes**:

* Depends on Session 02 for the intended architecture contract.
* Renderer code may own the mounted run controller, but run-state mutation must still flow through public simulation APIs.

**Acceptance Checks**:

* All files listed in D1 and the Audit Subject Map have been read or deliberately scoped with rationale.
* Every forbidden-import or forbidden-global hit from Session 01 is triaged.
* Host extension wiring is included, not only `src/extensions/ai-rogue/`.

**Session 04: Simulation Correctness**

**Objective**: Audit deterministic run-state correctness in the simulation and content systems.

**Scope**:

* Audit D2 for seeded RNG usage, replayability, ordering hazards, tie-breaks, and time usage that affects run state.
* Inspect combat, FOV, status effects, initiative, enemy behavior, objectives, exits, thief logic, compile beats, cascade, shield buffer, traversal verbs, terminals, prefabs, floor arcs, equipment, and protocols.
* Run or extend headless playthrough evidence only as audit measurement; proposed tests remain follow-up unless separately approved.
* Identify soft-locks, unreachable states, empty-collection paths, off-by-one errors, and replay determinism breaks.

**Outputs**:

* Correctness findings with severity and reproducibility notes.
* Replay-risk matrix covering RNG, time, ordering, and state transitions.
* List of highest-value characterization tests needed before simulation refactors.

**Dependencies / Notes**:

* Depends on Session 03 for public API and boundary understanding.
* `Date.now()` and `new Date()` are not automatically bugs; only run-state influence is a determinism risk.

**Acceptance Checks**:

* Every `Math.random`, time, and ordering-hazard hit is classified.
* The major gameplay systems named in D2 are covered with source evidence.
* Any suspected soft-lock includes a concrete path, seed, fixture, or code path.

**Session 05: Economy And Persistence**

**Objective**: Audit durable state, wallet/ledger behavior, migrations, reset, and seed sharing.

**Scope**:

* Inspect economy, economy schema, claim store, save schema, persistence, save-state hooks, and seed-share code.
* Verify idempotent claim keys, daily caps, unknown-pricing handling, missing telemetry handling, and double-claim race behavior.
* Verify schema migration completeness, corrupt or partial save recovery, IndexedDB/localStorage fallback, and AI-Rogue-only reset.
* Verify seed URL normalization, replay-relevant state preservation, and removal of debug or private-looking query data.

**Outputs**:

* Economy and persistence findings with file:line evidence.
* Migration and reset-boundary checklist.
* Seed-sharing privacy and determinism notes for D3/D2 cross-reference.

**Dependencies / Notes**:

* Depends on Session 02 privacy/runtime-data contracts and Session 04 run-state model.
* Public-demo browser-local state copy must be checked here and again in the privacy session.

**Acceptance Checks**:

* Every save schema version and migration path is accounted for.
* Reset behavior is shown not to touch unrelated AI OS state, or a finding is filed.
* Claim idempotency and daily-cap behavior have source or test evidence.

**Session 06: Privacy Boundary**

**Objective**: Audit AI Rogue privacy, capabilities, provenance, and public-demo storage behavior end to end.

**Scope**:

* Audit D3 allowed and denied data classes across UI, saves, URLs, ledger, economy, public-demo mode, and tests.
* Compare declared capabilities in `capabilities.ts` with actual behavior.
* Confirm no network access, collectors, hosted storage, raw telemetry, private paths, command bodies, prompts, transcripts, credentials, or logs are reachable through the game.
* Inspect provenance labels and adversarial LiveData fixture handling.

**Outputs**:

* Privacy findings, including any default-enablement blockers.
* Capability-vs-behavior matrix.
* Evidence that repo-level private-runtime checks are supplemented by direct AI Rogue inspection.

**Dependencies / Notes**:

* Depends on Session 05 for persistence and seed-sharing behavior.
* Critical severity applies to privacy leaks, hosted/public-demo server writes, and disallowed data persistence.

**Acceptance Checks**:

* Every privacy/storage/URL triage hit is classified.
* Public-demo state is confirmed browser-local or a finding is filed.
* Adversarial fixtures are checked for render, persist, and share-URL exposure.

**Session 07: Render And Performance**

**Objective**: Audit rendering, Pixi lifecycle, runtime loop behavior, and client performance risk.

**Scope**:

* Inspect runtime canvas, renderer, render model, effects, Pixi runtime, and assets code.
* Verify per-frame work avoids React churn, unbounded allocations, runaway arrays, and stale callbacks.
* Verify textures, sprites, containers, ticker, listeners, particles, resize handlers, and animation frames are disposed on unmount.
* Verify tab hidden, blur, resize, reduced-motion, and route-change behavior do not leave runaway work.

**Outputs**:

* Performance and lifecycle findings with evidence.
* Mount/unmount resource ownership map.
* Measurement caveats for browser, viewport, demo mode, and bundle directory.

**Dependencies / Notes**:

* Depends on Session 03 architecture results and Session 04 run-loop understanding.
* This session identifies and measures; it does not optimize code.

**Acceptance Checks**:

* Every long-lived renderer resource has an owner and teardown path or a finding.
* Lazy Pixi/runtime loading assumptions are checked from route entry to mounted canvas.
* Reduced-motion implications for runtime effects are queued for Session 10 if not resolved here.

**Session 08: Assets, Audio, And Bundles**

**Objective**: Audit media provenance, audio lifecycle, lazy loading, and bundle/public-demo budgets.

**Scope**:

* Inspect audio runtime, asset manifests, committed media, provenance docs, bundle budget checks, asset-size checks, demo build checks, and private-runtime artifact checks.
* Verify Web Audio unlock, decode-on-demand, buffer-cache bounds, silent degradation, ducking, and audio-node teardown.
* Verify atlases and music meet budget policy and are not eagerly loaded by non-Play routes.
* Verify public-demo build, scan, budget, and mobile demo coverage align with AI Rogue constraints.

**Outputs**:

* Asset/audio/bundle findings with evidence.
* Media provenance and budget table.
* List of stale asset or audio documentation claims.

**Dependencies / Notes**:

* Depends on Sessions 01 and 02 for gate results and doc contracts.
* Older no-audio statements are expected historical drift candidates until verified.

**Acceptance Checks**:

* Every remote/audio-loading triage hit is classified as local asset, local dynamic import, or risk.
* Asset and demo budget commands are represented in the evidence appendix.
* Audio failure paths are either graceful or recorded as findings.

**Session 09: Types And Schemas**

**Objective**: Audit type safety, exported APIs, serialization contracts, and schema/type drift.

**Scope**:

* Inspect `runtime/types.ts`, `runtime/index.ts`, save schemas, economy schemas, persistence payloads, snapshots, and exported runtime APIs.
* Triage `any`, unsafe casts, non-null assertions, `@ts-ignore`, wide payloads, duplicated schema types, and defaults that erase fields.
* Verify Zod schemas and inferred types are the contract for persisted and economy data.
* Check whether public exports leak internals or hide behavior that tests need.

**Outputs**:

* Type-safety findings with severity and scope.
* Schema-vs-runtime contract map.
* Refactor prerequisites for type-heavy modules.

**Dependencies / Notes**:

* Depends on Sessions 04 and 05 for actual runtime and persistence behavior.
* Type unsoundness that can corrupt saves or replay state should be escalated above maintainability severity.

**Acceptance Checks**:

* Every type-safety smell from Session 01 is triaged.
* Runtime snapshot and save payloads are compared against schemas.
* Exported APIs are matched to current runtime behavior.

**Session 10: Accessibility And Input**

**Objective**: Audit keyboard, touch, reduced-motion, layout, and assistive text behavior across the full UI.

**Scope**:

* Inspect input-mode resolution, runtime input sampling, Play, Settings, Ledger, Loadout, View Shell, canvas a11y text, compact controls, and high-contrast/large-HUD preferences.
* Verify Auto input copy, explicit overrides, keyboard reachability, focus transitions, disabled-before-start controls, pointer movement, clipboard fallback, and portrait-width layout.
* Verify every animation, shake, glide, particle, flash, and canvas effect has a reduced-motion/static fallback.
* Use mobile and public-demo e2e evidence where applicable.

**Outputs**:

* Accessibility and input findings with reproduction notes.
* Input-mode state table from settings to runtime command sampling.
* List of missing coverage for keyboard, compact, mobile, and reduced-motion behavior.

**Dependencies / Notes**:

* Depends on Session 07 for renderer/effects ownership and Session 08 for public-demo/mobile gate status.
* Layout issues should include viewport and route details.

**Acceptance Checks**:

* Every user-facing route for AI Rogue is covered.
* Every runtime verb is checked for keyboard and compact/touch access.
* Reduced-motion coverage is traced through render, effects, and UI layers.

**Session 11: Robustness Paths**

**Objective**: Audit graceful degradation and async race behavior for unavailable APIs and mid-run failures.

**Scope**:

* Inspect failure paths for WebGL, Web Audio, IndexedDB, localStorage, matchMedia, clipboard, corrupt save, missing assets, bad audio, route changes, and mid-run unmount.
* Triage swallowed errors, unguarded JSON parsing, optional asset assumptions, stale mount-generation callbacks, and reset/save/claim races.
* Verify error boundaries and user-visible fallback copy in host and AI Rogue views.
* Cross-check unit and e2e tests for failure-path coverage.

**Outputs**:

* Robustness findings with reachable failure scenarios.
* Async race matrix for imports, renderer/audio setup, persistence, claims, reset, and unmount.
* Missing failure-path test list.

**Dependencies / Notes**:

* Depends on Sessions 05, 07, 08, and 10 for the relevant subsystems.
* A swallowed error is only acceptable when there is a deliberate fallback and evidence that state remains coherent.

**Acceptance Checks**:

* Every `catch` and `JSON.parse` triage hit is classified.
* Each unavailable-platform case in D7 is either tested, manually traced, or filed as a coverage gap.
* No common-path white-screen crash risk remains unclassified.

**Session 12: Test Coverage**

**Objective**: Map and assess test coverage quality across the entire audit subject map.

**Scope**:

* Map all AI Rogue unit specs, AI Rogue e2e specs, public-demo mobile coverage, host-boundary tests, and the playthrough harness to D1-D9.
* Assess whether tests assert behavior rather than implementation details.
* Inspect fixture realism, adversarial privacy fixtures, determinism tests, edge-case coverage, and refactor safety.
* Prioritize missing tests by severity, blast radius, and refactor dependency.

**Outputs**:

* Coverage matrix by subject layer and audit dimension.
* Prioritized missing-test list with proposed test location and scenario.
* Evidence that privacy, public-demo, mobile, and determinism coverage is meaningful.

**Dependencies / Notes**:

* Depends on Sessions 03-11 so gaps are tied to actual risks.
* Characterization tests are proposed as follow-up unless the audit owner explicitly changes the non-goal.

**Acceptance Checks**:

* All 41 unit specs and all named e2e specs from the current inventory are mapped or the inventory is corrected.
* Every high or critical finding has an associated existing test, missing-test item, or rationale.
* Coverage gaps distinguish absent tests from weak tests.

**Session 13: Refactor Map**

**Objective**: Convert architecture, correctness, type, and coverage evidence into a safe oversized-module refactor map.

**Scope**:

* Produce split recommendations for `simulation.ts`, `renderer.ts`, `save-schema.ts`, `effects.ts`, `runtime-canvas.tsx`, `persistence.ts`, `render-model.ts`, `world.ts`, and `types.ts`.
* Identify cohesive sub-systems, state boundaries, public APIs, hidden coupling, and test prerequisites for each split.
* Sequence refactors by dependency, risk reduction, and characterization-test readiness if evidence supports sequencing.
* Identify modules that should not be split yet and why.

**Outputs**:

* Refactor map section for the findings report.
* Per-module seam list with pre-refactor tests.
* Sequencing recommendation or explicit deferral if the audit cannot support sequencing.

**Dependencies / Notes**:

* Depends on Sessions 03, 04, 05, 07, 09, and 12.
* Open question carried forward: whether sequencing belongs in the audit report or a separate refactor plan.

**Acceptance Checks**:

* Every module over roughly 800 lines has a named recommendation.
* Every proposed split includes the seam it cuts and the tests required first.
* No refactor recommendation contradicts known privacy, determinism, or persistence constraints.

**Session 14: Findings Synthesis**

**Objective**: Produce the final comprehensive audit report and default-enablement verdict.

**Scope**:

* Consolidate all session evidence into `.spec_system/PRD/phase_35/PRD_phase_35.md`.
* Group findings by D1-D9, assign severity, deduplicate root causes, cross-link related findings, and include file:line evidence.
* Produce executive summary, Go/No-Go default-enablement verdict, blocker list, refactor map, coverage gaps, doc-drift list, and evidence appendix.
* Verify completion criteria from the plan and list any unmet criteria with reasons.

**Outputs**:

* Complete audit findings report at `.spec_system/PRD/phase_35/PRD_phase_35.md`.
* Final default-enablement verdict with explicit blockers.
* Follow-up backlog for fixes, tests, doc updates, and refactors.

**Dependencies / Notes**:

* Depends on Sessions 01-13.
* This session may update the findings report only; product code and generated assets remain out of scope.
* Open questions from the source plan should be answered when evidence permits or preserved as explicit unresolved questions.

**Acceptance Checks**:

* The report satisfies every item in the Output Contract.
* The completion criteria checklist is included and marked complete, incomplete, or blocked.
* Every finding has location, observation, impact, recommendation, and related links where relevant.
* The evidence appendix records command status, inventory counts, and measurement caveats.

> **Status:** Sessions 01-14 executed on 2026-06-25; final findings synthesis complete and `.spec_system/PRD/phase_35/PRD_phase_35.md` produced. **Captured:** 2026-06-25 **Scope:** `src/extensions/ai-rogue/` plus its tests, AI Rogue e2e specs, host extension wiring, supporting scripts/gates, committed assets, public-demo behavior, and the `docs/extensions/ai-rogue/` doc set it should be auditable against. **Intent:** Define a repeatable, comprehensive audit clearly enough that any later session can execute it dimension-by-dimension and produce a findings report without re-deriving scope.

***

#### Why This Audit

AI Rogue is a large, self-contained game extension in the repo: 21,152 lines of non-test source across 45 TS/TSX files, 7,339 lines across 41 unit specs, and 5 AI-Rogue-specific Playwright e2e specs. It was built across Phase 30 (10 sessions), then later touched by Phase 32 mobile input work and Phase 33 public-demo integration. The extension now contains deep gameplay systems (status effects, ecology, terminals, prefabs, compile beats, traversal verbs) on top of a deterministic simulation core. It remains behind `VITE_CLAUDE_OS_ENABLED_EXTENSIONS` as explicit opt-in, while public-demo mode forces it visible as browser-local, non-hosted runtime state.

Four concerns motivate a single comprehensive pass rather than four narrow ones:

1. **Refactor readiness** - several modules are far past a comfortable size (`runtime/simulation.ts` at 3,108 lines, `runtime/renderer.ts` at 1,605, `save-schema.ts` at 1,247, `runtime/effects.ts` at 1,057, `views/runtime-canvas.tsx` at 1,047, `persistence.ts` at 1,020, `runtime/render-model.ts` at 928, `runtime/world.ts` at 834, and `runtime/types.ts` at 804). We need to know the real seams before any split.
2. **Pre-default-enablement gate** - before flipping from opt-in to default-on, the privacy boundary, bundle budget, runtime performance, accessibility, and failure robustness must hold under scrutiny.
3. **Correctness and quality** - determinism, edge cases, silent failure paths, and test-coverage gaps in the simulation/economy/persistence layers.
4. **General engineering/architecture health** - boundary leaks, coupling, dead code, type soundness, and doc-vs-code drift, surfacing *any* issue.

The deliverable of this plan is the audit *method*. Executing it produces a separate findings report (see Output Contract).

***

#### Audit Subject Map

| Layer                      | Representative files                                                                                                                                                                       | What it owns                                                                                               |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| AI Rogue extension shell   | `client.tsx`, `capabilities.ts`                                                                                                                                                            | View registration, lazy AI Rogue view loading, declared capabilities                                       |
| Host routing/data boundary | `src/extensions/registry.ts`, `src/extensions/use-extension-data.ts`, `src/components/extensions/extension-host.tsx`, `src/routes/extensions.$extensionId*.tsx`, `src/lib/setup-config.ts` | Env gate, public-demo extension enablement, host-LiveData delivery, error boundary, default-view redirects |
| Views (React)              | `views/play-view.tsx`, `runtime-canvas.tsx`, `ledger-view.tsx`, `loadout-view.tsx`, `settings-view.tsx`, `view-shell.tsx`, `reward-icon.tsx`                                               | Routes, menus, forms, a11y text, runtime mount/unmount boundary                                            |
| Input resolution           | `input-mode.ts`, `runtime/input.ts`                                                                                                                                                        | Auto/Keyboard/Compact resolution at the browser boundary, keyboard/pointer command sampling                |
| Economy                    | `economy.ts`, `economy-schema.ts`, `claim-store.ts`                                                                                                                                        | Insight Shards earning blend, daily caps, idempotent claims, provenance                                    |
| Persistence                | `persistence.ts`, `save-schema.ts`, `use-save-state.ts`, `seed-share.ts`                                                                                                                   | Versioned Zod save/wallet/ledger/prefs, IndexedDB/localStorage, reset                                      |
| Progression                | `progression.ts`                                                                                                                                                                           | Loadout upgrades, relics, skill-linked modifiers                                                           |
| Simulation core            | `runtime/simulation.ts`, `world.ts`, `entities.ts`, `combat.ts`, `fov.ts`, `rng.ts`, `status.ts`, `initiative.ts`, `enemy-effects.ts`                                                      | Pure deterministic dungeon rules, seeded RNG, no Pixi/DOM deps                                             |
| Content systems            | `runtime/terminals.ts`, `prefabs.ts`, `themes.ts`, `floor-arc.ts`, `compile.ts`, `equipment.ts`, `protocols.ts`, `inspect.ts`                                                              | Run-local depth systems                                                                                    |
| Render pipeline            | `runtime/render-model.ts`, `renderer.ts`, `effects.ts`, `pixi-runtime.ts`, `assets.ts`                                                                                                     | Pure turn snapshot -> imperative PixiJS draw + effects layer                                               |
| Audio                      | `runtime/audio.ts`                                                                                                                                                                         | Web Audio mixing/ducking, lazy decode, autoplay-gesture unlock                                             |
| Types/contracts            | `runtime/types.ts`, `runtime/index.ts`                                                                                                                                                     | Shared simulation/render types and public surface                                                          |
| Tooling/assets             | `scripts/ai-rogue-playthrough.ts`, `scripts/check-asset-sizes.sh`, `scripts/check-bundle-budget.sh`, `scripts/check-private-runtime-artifacts.sh`, `src/assets/ai-rogue/`                  | Headless playthrough harness, media and bundle gates, atlases, audio, provenance                           |
| Tests                      | `src/extensions/ai-rogue/**/__tests__/`, `tests/e2e/ai-rogue-{runtime,mobile,ledger,persistence,enablement}.spec.ts`, `tests/e2e/pages-demo-mobile.spec.ts`                                | Unit + canvas/runtime + e2e + public-demo coverage                                                         |

Reference docs to audit the code *against*: read the full `docs/extensions/ai-rogue/README.md` document map and every file in `docs/extensions/ai-rogue/`. Treat current-maintenance docs as asserted contracts, while session docs can be historical evidence. Flag drift in either direction and separately call out doc-vs-doc contradictions. Known drift hotspots to verify: pre-audio/no-audio Session 09/10 statements versus current Web Audio runtime, stale atlas byte counts in older docs, public-demo browser-local copy, and default-enablement language.

***

#### Audit Dimensions

Each dimension is an independent pass with its own checklist, evidence requirements, and severity rubric. A finding belongs to exactly one dimension (its primary lens) but may cross-reference others.

**D1 - Architecture And Module Boundaries**

* Verify the declared layering holds in code: simulation modules import **no** PixiJS, no DOM, no React, no persistence, no browser globals. Use `rg` for forbidden imports/globals in the pure simulation/content module list.
* Confirm `render-model.ts` is a pure projection and that transient presentation (shake, hit-stop, tweening, flash) lives only in `effects.ts`, per the baseline contract.
* Map the real import graph; find cycles, back-edges, and god-modules that everything depends on. Renderer code may own the mounted run controller, but it must mutate run state only through the simulation public API (`createAiRogueRun`, `applyAiRogueCommand`, `createAiRogueSnapshot`) rather than editing internals ad hoc.
* Assess `simulation.ts` (3,108 lines): identify cohesive sub-systems that could become files, and the seams (function/closure/state boundaries) a split would cut along. Same for `renderer.ts`, `effects.ts`, `save-schema.ts`, `persistence.ts`, `runtime-canvas.tsx`, `render-model.ts`, `world.ts`, and `types.ts`.
* Check the extension-shell boundary: no Pixi/runtime import reachable from `registry.ts`, the extension host, route files, Settings/Ledger/Loadout, or non-game routes except through lazy AI Rogue Play/runtime loading.
* Confirm public-demo enablement and host-LiveData routing are host-layer concerns, not special cases buried inside game simulation/runtime modules.

**D2 - Correctness And Determinism**

* Trace seeded RNG (`rng.ts`) usage: every stochastic decision that affects run state must draw from the seeded stream, never `Math.random()`.
* Triage time usage separately. `Date.now()`/`new Date()` are acceptable for UI event timestamps, save metadata, and wall-clock ledgers, but must not affect map generation, combat, AI decisions, reward selection, or replayable run state.
* Determinism: same seed + same inputs => identical run. Check ordering hazards (object-key iteration, `Set`/`Map` ordering, float accumulation, initiative/speed-meter tie-breaks).
* Edge cases in combat, FOV, status stacking/expiry, objective-locked exits, thief goal logic, compile beat, cascade, shield buffer - look for off-by-one, unreachable states, soft-locks (no legal move), and division/empty-collection paths.
* Economy: idempotent claim keys (date + provider/run-id), daily-cap enforcement, unknown-pricing/missing-telemetry handling reducing only its own contribution (not penalizing the rest), and no double-claim race.
* Persistence: version migration completeness, forward/backward-compat on schema bumps, corrupt/partial-save recovery, IndexedDB failure fallback, reset-boundary correctness (AI-Rogue-only).
* Seed sharing: URL seed normalization must be bounded, private-looking input must not be retained, scenario/debug query params must not leak into share URLs, and save/load must preserve replay-relevant state.

**D3 - Privacy And Capability Boundary**

* Enforce the allowed/denied data classes from the baseline: only counts, dates, categories, status/source labels, capped spend/token signals, readiness/streak labels; **never** raw prompts, transcripts, command bodies, private paths, credentials, logs, raw telemetry.
* Confirm declared `capabilities` match actual behavior - no `networkAccess`, collectors, hosted storage, or remote loading; flag any capability without matching code and any behavior without a declared capability.
* Verify no game state writes to `src/data/live-data.json` during normal play.
* Confirm provenance labels in the Ledger never leak disallowed content.
* Audit storage names and reset behavior: localStorage/IndexedDB keys must be AI-Rogue-scoped, public-demo copy must make browser-local state explicit, and reset must not touch unrelated AI OS state.
* Do not treat `bun run runtime:check-private` as sufficient for AI Rogue privacy. It is a repo-level artifact gate; D3 still inspects AI Rogue UI, saves, URLs, ledgers, and tests directly.

**D4 - Performance And Runtime Resource Lifecycle**

* Per-frame budget: confirm simulation/render avoid per-frame allocations, unbounded array growth, and React state churn (per-frame state outside React, per the baseline).
* PixiJS lifecycle: textures, sprites, containers, ticker, listeners, and particles are all disposed on route unmount; no leaks across mount/unmount cycles in `runtime-canvas.tsx`/`renderer.ts`.
* Audio lifecycle: buffer cache bounds, decode-on-demand, silent no-op degradation, no dangling audio nodes after unmount.
* Bundle: confirm the lazy Pixi chunk stays out of the static entry; re-measure against the 1,500 KB total client JS gzip budget.
* Asset budget: confirm atlas files stay under the normal 200 KB media cap, AI Rogue music stays under the reviewed per-track cap, provenance manifests exist for generated audio, and audio assets are not eagerly pulled into non-Play routes.
* Runtime loop behavior: tab hidden/blur pause, resize throttling, ticker teardown, and reduced-motion modes should not leave runaway animation frames or per-route global listeners behind.

**D5 - Type Safety And API Surface**

* Hunt `any`, unsafe casts (`as`), non-null assertions (`!`), and `@ts-ignore` in `runtime/types.ts` and across the module; assess whether discriminated unions model game state soundly.
* Check exported surface (`runtime/index.ts`) for leaking internals and for types that drift from runtime behavior.
* Zod schemas vs. TS types: confirm `save-schema.ts`/`economy-schema.ts` are the single source of truth and that inferred types are used, not duplicated.
* Serialization contracts: validate runtime snapshot/save payload types are not wider than their schemas, and schema defaults do not silently erase new fields on old saves.

**D6 - Accessibility And Input**

* Reduced-motion as a hard contract: every animation/shake/glide path gates on the runtime reduced-motion flag with a readable static fallback.
* Input-mode resolution (`input-mode.ts`): Auto -> compact/keyboard derivation, explicit overrides, and that only concrete `keyboard | compact` reaches the runtime; copy reports `Auto (compact)`/`Auto (keyboard)` correctly.
* Keyboard reachability of all verbs; focus management on route/menu transitions; canvas a11y text presence.
* Mobile/touch ergonomics: compact controls are disabled before runtime start, enabled after start, pointer canvas movement is intentional, no horizontal overflow occurs on portrait widths, and clipboard-unavailable seed sharing has a readable fallback.
* High-contrast/large-HUD preferences should improve readability without breaking layout or making canvas text overlap controls.

**D7 - Error Handling And Robustness**

* Map failure paths: WebGL unavailable, Web Audio unavailable, IndexedDB blocked/quota, localStorage blocked, matchMedia unavailable, clipboard unavailable, corrupt save, missing/non-decodable atlas or audio, mid-run unmount. Each should degrade gracefully, not throw to a white screen.
* Find swallowed errors (empty `catch`), unguarded `JSON.parse`, and assumptions that an optional asset/feature is present.
* Check async race paths: route change during renderer/audio import, save/load while resetting, claim while persistence is busy, and stale mount-generation callbacks after unmount.

**D8 - Test Coverage And Quality**

* Map the 41 unit specs + 5 AI Rogue e2e specs to the subject map; also include the public-demo mobile e2e coverage that proves AI Rogue remains browser-local in the hosted demo.
* Assess test quality: determinism assertions, edge-case coverage, whether tests assert behavior vs. restate implementation, fixture realism (`simulation-fixtures.ts`).
* Identify the highest-value missing tests (regression guards a refactor would need before it's safe).
* Verify adversarial privacy fixtures stay meaningful: tests should include raw prompts/private paths/commands in host LiveData and prove those strings do not render, persist, or appear in share URLs.

**D9 - Maintainability And Dead Code**

* Duplicate logic across content systems; magic numbers that should be named constants/config; inconsistent naming vs. repo conventions (`docs/CONVENTIONS.md`).
* Unused exports, unreachable branches, orphaned files, stale TODO/FIXME.
* Doc-vs-code drift against the `docs/extensions/ai-rogue/` set (D1-D8 feed this); flag where docs assert behavior the code no longer has, or vice versa.
* Doc-vs-doc drift: older session closeout docs may preserve historical facts, but current README/baseline/runtime-data docs must not contradict current audio, asset, public-demo, input-mode, or enablement posture without labeling the older statement as historical.

***

#### Execution Method

Run dimensions in this order so structural understanding feeds the rest:

```
Phase A  Baseline + graph     D1, D9        (read docs, build import graph, size map)
Phase B  Core correctness     D2, D3        (sim/economy/persistence + privacy)
Phase C  Runtime quality      D4, D5, D6, D7 (perf, types, a11y, robustness)
Phase D  Coverage + debt      D8, D9        (tests, dead code, doc drift)
Phase E  Synthesis            ranking, refactor map, completion check
```

For each dimension:

1. State the checklist (above) as the pass's working list.
2. Read the owning files in full - large modules (`simulation.ts`, `renderer.ts`) are read in sections, not skimmed.
3. Use `rg` sweeps for boundary/anti-pattern checks (see Mechanical Checks).
4. Record each finding in the standard finding format with file:line evidence.
5. Cross-link findings that share a root cause.

This is a read-and-report audit. Do not change product code while auditing; the only writes are the findings report and (optionally) new characterization tests proposed under D8, which land as a separate follow-up, not during the audit.

**Mechanical Checks (run first, cheap signal)**

```bash
### Inventory: keep source/test counts current before quoting them.
rg --files src/extensions/ai-rogue | rg '\.(ts|tsx)$' | rg -v '/__tests__/' | xargs wc -l
rg --files src/extensions/ai-rogue | rg '/__tests__/.*\.(ts|tsx)$' | wc -l
rg --files tests/e2e | rg 'ai-rogue.*\.spec\.ts$'

### Import graph seed: triage cycles/back-edges from this list.
rg -n "^import|from ['\"]" \
  src/extensions/ai-rogue \
  src/extensions/registry.ts \
  src/extensions/use-extension-data.ts \
  src/components/extensions/extension-host.tsx \
  'src/routes/extensions.$extensionId.tsx' \
  'src/routes/extensions.$extensionId.$viewId.tsx'

### Boundary: simulation/content modules must not import Pixi/DOM/React/persistence.
rg -n "(pixi\.js|@pixi|from\s+['\"]react|document\.|window\.|localStorage|indexedDB|persistence)" \
  src/extensions/ai-rogue/runtime/{simulation,world,entities,combat,fov,rng,status,initiative,enemy-effects,terminals,prefabs,themes,floor-arc,compile,equipment,protocols,inspect}.ts

### Determinism/time hazards: triage Date usage; not every timestamp is a bug.
rg -n "Math\.random|Date\.now|new Date\(" src/extensions/ai-rogue --glob '!**/__tests__/**'

### Type-safety smells.
rg -n "(:\s*any\b|\bas\s+any\b|@ts-(ignore|expect-error)|!\.)" \
  src/extensions/ai-rogue --glob '*.{ts,tsx}' --glob '!**/__tests__/**'

### Swallowed errors / unguarded parse.
rg -n "catch|JSON\.parse" src/extensions/ai-rogue --glob '*.{ts,tsx}' --glob '!**/__tests__/**'

### Privacy/storage/URL triage.
rg -n "(prompt|transcript|credential|secret|private|/home/|live-data|LiveData)" \
  src/extensions/ai-rogue tests/e2e/ai-rogue-*.spec.ts
rg -n "(localStorage|indexedDB|ai-os\.ai-rogue|deleteDatabase|src/data/live-data\.json|live-data)" \
  src/extensions/ai-rogue src/extensions/use-extension-data.ts src/lib/setup-config.ts

### Remote/audio loading triage: local assets and local dynamic imports may be valid.
rg -n "(fetch\(|XMLHttpRequest|WebSocket|EventSource|new Audio|AudioContext|audio/|\.ogg|\.mp3|\.wav|import\()" \
  src/extensions/ai-rogue package.json docs/extensions/ai-rogue

### Dead code / debt markers.
rg -n "TODO|FIXME|HACK|XXX" src/extensions/ai-rogue docs/extensions/ai-rogue
```

**Project Gates (confirm green baseline before judging findings)**

```bash
bun run typecheck
bun run lint
bun run format:check
bun run test -- src/extensions/ai-rogue
bun run test -- \
  src/lib/__tests__/extension-registry.test.ts \
  src/lib/__tests__/use-extension-data.test.tsx \
  src/lib/__tests__/setup-config-extensions.test.ts
bun run build
bun run budget:check
bash scripts/check-asset-sizes.sh
bun run runtime:check-private
bun run test:e2e -- \
  tests/e2e/ai-rogue-runtime.spec.ts \
  tests/e2e/ai-rogue-mobile.spec.ts \
  tests/e2e/ai-rogue-ledger.spec.ts \
  tests/e2e/ai-rogue-persistence.spec.ts \
  tests/e2e/ai-rogue-enablement.spec.ts
bun run demo:build:pages
bun run demo:scan:pages
bun run demo:budget:pages
bun run test:e2e -- tests/e2e/pages-demo-mobile.spec.ts
bun run scripts/ai-rogue-playthrough.ts
```

The headless `scripts/ai-rogue-playthrough.ts` harness can drive a full deterministic run to surface soft-locks and runtime exceptions outside the browser. If any focused host-boundary test has moved, run the equivalent current test for extension registry, host-LiveData, and public-demo enablement.

***

#### Output Contract

Executing this plan produces `.spec_system/PRD/phase_35/PRD_phase_35.md` (new, created at execution time) with:

1. **Executive summary** - overall health verdict per lens (refactor readiness, enablement readiness, correctness, general health) and a Go/No-Go on default-enablement with blockers listed.
2. **Findings register** - every finding in the standard format, grouped by dimension, sorted by severity.
3. **Refactor map** - for each oversized module, the proposed split into cohesive files, the seams it cuts, and the characterization tests required first.
4. **Coverage gaps** - prioritized list of missing/weak tests.
5. **Doc-drift list** - concrete edits owed to the `docs/extensions/ai-rogue/` set.
6. **Evidence appendix** - commands run, pass/fail status, inventory counts, and any measurement caveats (browser/device, bundle directory, demo mode).

**Standard Finding Format**

```
[Dn][SEVERITY] Short title
  Location: src/extensions/ai-rogue/<file>:<line>
  Observation: what the code does
  Impact: why it matters (tie to a lens)
  Recommendation: concrete fix or refactor
  Related: [other finding ids]
```

**Severity Rubric**

| Severity | Meaning                                                                                                                                                           |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Critical | Privacy leak, hosted/public-demo server write, data loss/corruption, replay determinism break in run state, or crash on a common path - blocks default-enablement |
| High     | Boundary violation, soft-lock, resource leak, stale enablement claim, or correctness bug on a reachable path                                                      |
| Medium   | Refactor-blocking structure, weak/missing coverage on important logic, type unsoundness, misleading but non-blocking doc drift                                    |
| Low      | Maintainability, naming, dead code, minor historical-doc drift                                                                                                    |

***

#### Non-Goals

* No product/gameplay redesign or balance changes.
* No code changes during the audit pass itself (findings + optional follow-up characterization tests only).
* No new dependencies (e.g. madge/knip) required - import-graph and dead-code work uses `rg` + reading; a tool may be *recommended* as a finding, not added.
* No asset re-generation or binary re-encoding; asset review is limited to policy/provenance/lifecycle, not art quality.
* No performance work beyond identifying and measuring; optimization is a follow-up.
* No change to the env-gate/opt-in posture; the audit *informs* the default-enablement decision, it does not make it.
* No rewrite of historical session docs during audit execution unless the findings report identifies a current-contract ambiguity that must be fixed immediately.

***

#### Open Questions

* Should the refactor map be sequenced (which split lands first) inside the findings report, or deferred to a separate refactor plan?
* Is there an agreed per-frame allocation/perf budget to measure D4 against, or does the audit propose one?
* Should characterization tests for the big modules be written during the audit (to make findings reproducible) or strictly as a follow-up?
* Should historically stale session-closeout docs be edited in place, or should current docs add explicit supersession notes that point back to them?

***

#### Completion Criteria

This audit plan is satisfied when an execution pass has:

* Run all nine dimensions with documented checklists.
* Produced `.spec_system/PRD/phase_35/PRD_phase_35.md` per the Output Contract.
* Confirmed the project gates' baseline state and recorded any that fail.
* Delivered a refactor map for every module over \~800 lines, each with named seams and required pre-refactor tests.
* Delivered a Go/No-Go verdict on default-enablement with explicit blockers.
* Listed every doc-vs-code and doc-vs-doc drift owed to the `docs/extensions/ai-rogue/` set.
* Recorded current source/test/e2e inventory counts so later sessions can see whether the plan's baseline has drifted again.

***

#### Execution Log

**2026-06-25 qimpl Session 01 Baseline**

**Scope executed**: Session 01 Audit Baseline only. No product code changes were made. The D1-D9 audit passes, findings triage, refactor map, default enablement verdict, and final `.spec_system/PRD/phase_35/PRD_phase_35.md` report remain pending.

**Current inventory**:

* Non-test AI Rogue TS/TSX source: 45 files, 21,152 total lines.
* AI Rogue unit specs: 41 files.
* AI Rogue e2e specs: 5 files: `tests/e2e/ai-rogue-runtime.spec.ts`, `tests/e2e/ai-rogue-mobile.spec.ts`, `tests/e2e/ai-rogue-ledger.spec.ts`, `tests/e2e/ai-rogue-persistence.spec.ts`, and `tests/e2e/ai-rogue-enablement.spec.ts`.
* Public-demo AI Rogue mobile route coverage: Play, Ledger, Loadout, and Settings are included in `tests/e2e/pages-demo-mobile.spec.ts` through the `PAGES_DEMO_ROUTES` matrix; Play also exercises compact controls and checks canvas pixel changes.
* Committed AI Rogue runtime assets: 28 files under `src/assets/ai-rogue` (6 music Ogg files plus provenance, 16 SFX Ogg files plus provenance, and gameplay/UI atlas JSON and PNG files).
* AI Rogue docs: 13 Markdown files and 29 total files under `docs/extensions/ai-rogue`, including generated image assets.
* Host wiring inventory confirmed for audit scope: `src/extensions/registry.ts`, `src/extensions/use-extension-data.ts`, `src/components/extensions/extension-host.tsx`, `src/routes/extensions.$extensionId.tsx`, `src/routes/extensions.$extensionId.$viewId.tsx`, and `src/lib/setup-config.ts`.

**Mechanical-check baseline**:

| Check                              | Result         | Notes                                                                                                                                                                                                                                                       |
| ---------------------------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Inventory commands                 | Run            | Counts recorded above.                                                                                                                                                                                                                                      |
| Import graph seed                  | Run            | Produced a large import/export hit list for AI Rogue plus host wiring. Terminal capture was truncated, so D1 should rerun in narrower slices or save output when building the actual graph.                                                                 |
| Boundary forbidden imports/globals | No hits        | The pure simulation/content module sweep found no Pixi, React, DOM, localStorage, indexedDB, or persistence matches.                                                                                                                                        |
| Determinism/time hazards           | Hits to triage | Raw hits were `new Date()`/`Date.now()` in runtime input, renderer event timestamps, economy date helpers, claim-store, persistence, runtime canvas, plus one comment noting deterministic pseudo-random effects. No `Math.random()` runtime use was found. |
| Type-safety smells                 | No hits        | The `any`, `as any`, `@ts-ignore`, `@ts-expect-error`, and non-null member access sweep returned no matches outside tests.                                                                                                                                  |
| Swallowed errors / JSON.parse      | Hits to triage | Raw hits exist across input-mode, renderer, audio, persistence, seed-share, claim-store, settings/play views, and runtime-canvas. These are queued for D7 robustness classification.                                                                        |
| Privacy/storage/URL triage         | Hits to triage | Raw hits include expected privacy fixtures, sanitization deny-lists, LiveData usage, AI Rogue storage declarations, and persistence/reset code. These are queued for D3 and D5.                                                                             |
| Remote/audio loading triage        | Hits to triage | Raw hits are local dynamic imports, Web Audio setup, local Ogg glob imports, and fetches of bundled asset URLs. These are queued for D4 and D8.                                                                                                             |
| Dead code / debt markers           | No hits        | The TODO/FIXME/HACK/XXX sweep returned no matches in AI Rogue source or docs.                                                                                                                                                                               |

**Project gate baseline**:

| Command                                                                                                                                                                                                   | Status           | Evidence                                                                                                                                                                                                            |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `bun run typecheck`                                                                                                                                                                                       | Pass             | `tsc --noEmit` exited 0.                                                                                                                                                                                            |
| `bun run lint`                                                                                                                                                                                            | Pass             | `eslint .` exited 0.                                                                                                                                                                                                |
| `bun run format:check`                                                                                                                                                                                    | Pass             | Prettier reported all matched files use Prettier style.                                                                                                                                                             |
| `bun run test -- src/extensions/ai-rogue`                                                                                                                                                                 | Pass             | 41 test files passed, 265 tests passed.                                                                                                                                                                             |
| `bun run test -- src/lib/__tests__/extension-registry.test.ts src/lib/__tests__/use-extension-data.test.tsx src/lib/__tests__/setup-config-extensions.test.ts`                                            | Pass             | 3 test files passed, 49 tests passed.                                                                                                                                                                               |
| `bun run build`                                                                                                                                                                                           | Pass             | Vite client and SSR builds completed.                                                                                                                                                                               |
| `bun run budget:check`                                                                                                                                                                                    | Pass             | Total client JS gzip was 1489 KB against a 1500 KB budget; no violations.                                                                                                                                           |
| `bash scripts/check-asset-sizes.sh`                                                                                                                                                                       | Pass             | All assets within configured size limits; total asset size reported as 14M.                                                                                                                                         |
| `bun run runtime:check-private`                                                                                                                                                                           | Pass             | Private runtime artifact check passed.                                                                                                                                                                              |
| `bun run test:e2e -- tests/e2e/ai-rogue-runtime.spec.ts tests/e2e/ai-rogue-mobile.spec.ts tests/e2e/ai-rogue-ledger.spec.ts tests/e2e/ai-rogue-persistence.spec.ts tests/e2e/ai-rogue-enablement.spec.ts` | Pass             | 15 Playwright tests passed.                                                                                                                                                                                         |
| `bun run demo:build:pages`                                                                                                                                                                                | Pass             | Pages demo build completed; assembled dist had 199 files, 192 promoted client files, and 7 copied public files.                                                                                                     |
| `bun run demo:scan:pages`                                                                                                                                                                                 | Pass             | Privacy scan passed: fixtures 5 scanned, dist 13 scanned, 186 skipped, 0 issues.                                                                                                                                    |
| `bun run demo:budget:pages`                                                                                                                                                                               | Pass             | Total client JS gzip was 1489 KB against a 1500 KB budget; no violations.                                                                                                                                           |
| `bun run test:e2e -- tests/e2e/pages-demo-mobile.spec.ts`                                                                                                                                                 | Pass             | 24 Playwright tests passed, including AI Rogue Play, Ledger, Loadout, and Settings mobile routes.                                                                                                                   |
| `bun run scripts/ai-rogue-playthrough.ts`                                                                                                                                                                 | Pass with caveat | Harness exited 0 across 6 seeds. Results: 2 won, 1 lost, and 3 still active at the 4000-turn cap; Session 04 should classify active capped runs as expected exploration, harness limitation, or soft-lock evidence. |

**Target report path**:

* `.spec_system/PRD/phase_35/PRD_phase_35.md` was checked and did not exist at the start of this qimpl run.
* No findings report was created in this baseline pass because no D1-D9 finding triage was performed. The eventual report should use the Output Contract above, including an evidence appendix seeded from this baseline.

**Files changed this session**:

* `docs/ongoing-projects/ai-rogue-audit-plan.md`

**Remaining work**:

* Run Session 02 Source Contracts next, then proceed through Sessions 03-14.
* Re-run or persist the import graph seed in D1 using narrower commands or a captured artifact so it is not truncated.
* Triage every mechanical-check hit under the relevant audit dimension before promoting anything to a finding.
* Watch the client JS budget during follow-up work; the baseline is only 11 KB under the configured 1500 KB gzip limit.

**2026-06-25 qimpl Session 02 Source Contracts**

**Scope executed**: Session 02 Source Contracts only. No product code changes were made. This pass read and classified the AI Rogue documentation set, checked the host extension/data-boundary docs that govern AI Rogue, and spot-checked the current code contracts named by the docs.

**Documentation inventory accounted for**:

* AI Rogue Markdown docs read in full: `README.md`, `runtime-data-and-enablement.md`, `game-feel.md`, `gameplay-depth.md`, `implementation-baseline.md`, `visual-assets.md`, `enablement-decision.md`, `content-polish-mobile-notes.md`, `run-loop-rebuild-notes.md`, `playtest-notes.md`, `progression-depth-notes.md`, `imagegen-session-recovery.md`, and `plan-2026-06-21.md`.
* AI Rogue generated docs assets accounted for by filename and size: 16 PNG files under `docs/extensions/ai-rogue/generated/`. These are docs/source references, not runtime assets.
* Host/reference docs read or scoped for contract impact: `docs/extensions/README_docs-extensions.md`, `src/extensions/README_extensions.md`, `docs/CONVENTIONS.md`, `docs/data-contract.md`, `docs/ARCHITECTURE.md`, and `docs/adr/0001-extension-platform-foundation.md`.

**Document classification**:

| Classification                         | Documents                                                                                                                                                                                                    | Notes                                                                                                                                                                       |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Current primary AI Rogue contracts     | `README.md`, `runtime-data-and-enablement.md`, `game-feel.md`, `gameplay-depth.md`                                                                                                                           | These have current status/checked dates or are named by the README as maintenance surfaces for current behavior.                                                            |
| Current host/platform contracts        | `src/extensions/README_extensions.md`, `docs/extensions/README_docs-extensions.md`, `docs/data-contract.md`, `docs/ARCHITECTURE.md`, `docs/CONVENTIONS.md`, `docs/adr/0001-extension-platform-foundation.md` | Use these for extension registration, runtime data modes, generated-data boundaries, public-demo rules, and repo conventions.                                               |
| Mixed current plus historical baseline | `implementation-baseline.md`, `visual-assets.md`, `enablement-decision.md`, `run-loop-rebuild-notes.md`                                                                                                      | These preserve ratified decisions and evidence. Use current sections where superseded by newer docs, and treat stale session evidence as historical.                        |
| Historical/session evidence            | `plan-2026-06-21.md`, `content-polish-mobile-notes.md`, `playtest-notes.md`, `progression-depth-notes.md`, `imagegen-session-recovery.md`                                                                    | Useful for rationale, acceptance history, and known follow-ups. Do not treat older no-audio or old atlas-size claims as current contracts without checking newer docs/code. |

**Source contract matrix**:

| Contract area            | Current source docs                                                                                | Owning code/tests to audit                                                                                                                        | Current contract for later sessions                                                                                                                                                                                                                                                                                                                                            |
| ------------------------ | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Enablement               | `README.md`, `runtime-data-and-enablement.md`, `enablement-decision.md`, host extension docs       | `src/extensions/ai-rogue/client.tsx`, `src/extensions/registry.ts`, `src/lib/setup-config.ts`, registry/setup tests                               | AI Rogue is statically registered, hidden unless `VITE_CLAUDE_OS_ENABLED_EXTENSIONS` includes `ai-rogue` or `all`, and remains explicit opt-in outside public-demo mode.                                                                                                                                                                                                       |
| Runtime data             | `runtime-data-and-enablement.md`, host extension docs, `docs/data-contract.md`                     | `src/extensions/ai-rogue/client.tsx`, `src/extensions/use-extension-data.ts`, `src/lib/live-data-types.ts`, enablement tests                      | AI Rogue uses `runtimeDataMode: "host-live-data"`. It must not require `LiveData.extensions.items["ai-rogue"]` and should read the browser-safe host LiveData payload directly when enabled.                                                                                                                                                                                   |
| Privacy and capabilities | `README.md`, `implementation-baseline.md`, `runtime-data-and-enablement.md`, `docs/CONVENTIONS.md` | `capabilities.ts`, `economy.ts`, `progression.ts`, `save-schema.ts`, `seed-share.ts`, Ledger/Loadout/Play views, privacy-focused unit/e2e tests   | Allowed data is counts, dates, categories, source/status labels, capped spend/token signals, readiness/streak labels, bounded provenance, and local game state. Denied data includes raw prompts, transcripts, command bodies/output, private paths, credentials, logs, and raw private telemetry. Current code declares `readGeneratedData`, `localStorage`, and `indexedDB`. |
| Persistence and reset    | `README.md`, `implementation-baseline.md`, `docs/ARCHITECTURE.md`                                  | `persistence.ts`, `save-schema.ts`, `use-save-state.ts`, `claim-store.ts`, Settings view, persistence tests                                       | Preferences are browser-local `localStorage`; wallet, ledger, run history, upgrades, and save slots are IndexedDB-backed. Reset must be AI-Rogue-scoped and not touch unrelated AI OS state.                                                                                                                                                                                   |
| Assets                   | `visual-assets.md`, `game-feel.md`, `implementation-baseline.md`, `docs/media-policy.md`           | `src/assets/ai-rogue/`, `runtime/assets.ts`, `runtime/renderer.ts`, `scripts/check-asset-sizes.sh`, asset tests                                   | Runtime art uses local gameplay/UI atlases under `src/assets/ai-rogue/` and must stay under the runtime media policy. Docs generated PNGs are source/reference assets and are not subject to the `src/assets` 200 KB runtime-image cap.                                                                                                                                        |
| Audio                    | `README.md`, `game-feel.md`, current sections of `implementation-baseline.md`, `visual-assets.md`  | `runtime/audio.ts`, `runtime/renderer.ts`, `save-schema.ts`, Settings view, committed Ogg/provenance files, asset-size and audio lifecycle checks | Audio is current and implemented: local Ogg music/SFX, lazy Web Audio unlock after user gesture, silent no-op fallback when unavailable, persisted mute/music/SFX preferences, and no external audio wrapper.                                                                                                                                                                  |
| Input and accessibility  | `runtime-data-and-enablement.md`, `README.md`, `content-polish-mobile-notes.md`, `game-feel.md`    | `input-mode.ts`, `views/runtime-canvas.tsx`, Play/Settings views, runtime input tests, mobile/runtime e2e                                         | Raw preferences are auto/keyboard/compact; Auto resolves at the mounted browser boundary to concrete keyboard/compact before reaching runtime. Reduced motion is a hard contract for animation, shake, glide, and effects.                                                                                                                                                     |
| Public demo              | `runtime-data-and-enablement.md`, `docs/ARCHITECTURE.md`, `src/extensions/README_extensions.md`    | `src/extensions/registry.ts`, `src/lib/public-demo.ts`, `scripts/lib/pages-demo-routes.ts`, `tests/e2e/pages-demo-mobile.spec.ts`                 | Public-demo mode enables registered extensions in the static demo, covers AI Rogue Play/Ledger/Loadout/Settings, must not call local `/__*` middleware, and must keep AI Rogue state browser-local.                                                                                                                                                                            |
| Default-on readiness     | `enablement-decision.md`, `README.md`, this audit plan                                             | Final `folded Phase 35 PRD source`, all D1-D9 evidence, project gates                                                                             | Current decision is safe explicit opt-in only. Default enablement remains a separate verdict to be made after Sessions 03-14, not inferred from Session 10 opt-in gates.                                                                                                                                                                                                       |

**Initial doc-vs-doc/code drift candidates**:

* Audio posture drift: current docs say audio is approved and implemented, but `docs/extensions/README_docs-extensions.md`, `enablement-decision.md`, and `content-polish-mobile-notes.md` still contain no-audio current-slice or Session 09/10 evidence. Treat Session 09/10 notes as historical, but queue the host extension README and enablement-doc wording for D9/doc cleanup.
* Capability list drift: `implementation-baseline.md` still lists the initial two-capability posture (`readGeneratedData`, `localStorage`), while current source and tests declare `readGeneratedData`, `localStorage`, and `indexedDB`. Session 06 should audit capability-vs-behavior; D9 should update the baseline if the `indexedDB` capability is now ratified.
* Atlas size drift: older baseline/session docs record earlier atlas byte counts. Current runtime files are `gameplay-atlas.png` 8,483 bytes, `gameplay-atlas.json` 37,874 bytes, `ui-atlas.png` 5,041 bytes, and `ui-atlas.json` 32,797 bytes. D8/D9 should reconcile older size claims with `visual-assets.md` and actual files.
* Public-demo contract is split across architecture, runtime-data, route-matrix, and e2e docs/code. No contradiction was found, but Session 06 should verify browser-local copy and storage behavior directly.
* Original `plan-2026-06-21.md` budget and optional-audio language is historical planning context. Later sessions should use current gate output and `game-feel.md` for current bundle/audio contracts.

**Spot checks run**:

| Check                    | Result  | Evidence                                                                                                                                                                                                                |
| ------------------------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| AI Rogue doc inventory   | Run     | 13 Markdown docs and 16 generated PNG docs assets accounted for under `docs/extensions/ai-rogue/`.                                                                                                                      |
| Host extension docs      | Run     | Read/scoped extension platform, data contract, architecture, ADR, and conventions docs relevant to AI Rogue boundaries.                                                                                                 |
| Code contract spot-check | Run     | Confirmed `runtimeDataMode: "host-live-data"`, lazy AI Rogue views, public-demo registry override, current capability list, input-mode resolver, audio local Ogg/Web Audio path, and public-demo AI Rogue route matrix. |
| Product code edits       | Not run | This was a read-and-report source-contract session; product code changes remain out of scope.                                                                                                                           |
| Full project gates       | Not run | Session 01 already recorded the baseline gate run; Session 02 did not change product code.                                                                                                                              |

**Files changed this session**:

* `docs/ongoing-projects/ai-rogue-audit-plan.md`

**Remaining work**:

* Run Session 03 Architecture Boundaries next.
* Use the matrix above as the source-contract baseline for D1-D9 findings.
* In Session 03, rerun the import graph in narrower persisted slices and audit host wiring, not only `src/extensions/ai-rogue/`.
* Carry the three confirmed doc-drift candidates into D9: audio posture, capability list, and atlas-size claims.

**2026-06-25 qimpl Session 03 Architecture Boundaries**

**Scope executed**: Session 03 Architecture Boundaries only. No product code changes were made. This pass focused on D1 layering, host/game boundaries, import graph shape, runtime loading, and oversized-module pressure. Full correctness, persistence, performance, type-safety, accessibility, and robustness internals remain assigned to Sessions 04-11.

**Files and surfaces inspected**:

* Host wiring and extension shell: `src/extensions/registry.ts`, `src/extensions/use-extension-data.ts`, `src/components/extensions/extension-host.tsx`, `src/routes/extensions.$extensionId.tsx`, `src/routes/extensions.$extensionId.$viewId.tsx`, `src/lib/setup-config.ts`, `src/extensions/ai-rogue/client.tsx`, and `src/extensions/ai-rogue/capabilities.ts`.
* AI Rogue view/runtime boundary: `views/play-view.tsx`, `views/runtime-canvas.tsx`, `views/settings-view.tsx`, `views/ledger-view.tsx`, `views/loadout-view.tsx`, `runtime/index.ts`, `runtime/renderer.ts`, `runtime/pixi-runtime.ts`, `runtime/assets.ts`, and `runtime/simulation-fixtures.ts`.
* Pure runtime/content boundary: imports and boundary-relevant sections in `runtime/simulation.ts`, `world.ts`, `entities.ts`, `combat.ts`, `fov.ts`, `rng.ts`, `status.ts`, `initiative.ts`, `enemy-effects.ts`, `terminals.ts`, `prefabs.ts`, `themes.ts`, `floor-arc.ts`, `compile.ts`, `equipment.ts`, `protocols.ts`, and `inspect.ts`.
* Large modules were read for import/export, public API, run-state ownership, and boundary-relevant mutation paths. Their behavioral internals are deliberately scoped to later sessions where the plan assigns them.

**Focused checks run**:

| Check                                             | Result           | Evidence                                                                                                                                                                                                                          |
| ------------------------------------------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| AI Rogue source list                              | Run              | Confirmed 45 non-test TS/TSX source files under `src/extensions/ai-rogue/`.                                                                                                                                                       |
| Import graph parser                               | Run              | Parsed 161 relative import/export edges across 45 source files. Found 0 value/runtime cycles and 7 type-only cycles centered on `runtime/types.ts`.                                                                               |
| Top incoming dependencies                         | Run              | Highest incoming counts: `runtime/types.ts` 25, `runtime/world.ts` 9, `save-schema.ts` 9, `runtime/protocols.ts` 8, `runtime/equipment.ts` 7, `runtime/status.ts` 7, `runtime/terminals.ts` 7, `runtime/themes.ts` 7.             |
| Pure simulation/content forbidden imports/globals | No hits          | No Pixi, React, DOM, `window`, `document`, `localStorage`, `indexedDB`, persistence, LiveData, host, component, or route imports in the pure module sweep.                                                                        |
| Runtime imports from outside AI Rogue             | No hits          | No imports of AI Rogue runtime or runtime canvas from outside `src/extensions/ai-rogue/`.                                                                                                                                         |
| Pixi import isolation                             | Pass with caveat | Only `runtime/pixi-runtime.ts:1-13` imports `pixi.js` directly. `renderer.ts` and `effects.ts` use the Pixi bridge dynamically or as a type.                                                                                      |
| Host/public-demo LiveData boundary                | Pass             | `registry.ts:15-27` owns public-demo enablement/env gating; `use-extension-data.ts:20-35` owns host-live-data fallback; `ExtensionHost` passes data/status/warnings into views at `extension-host.tsx:127-141`.                   |
| Oversized-module line count                       | Run              | Current >800-line modules remain `simulation.ts` 3108, `renderer.ts` 1605, `save-schema.ts` 1247, `effects.ts` 1057, `runtime-canvas.tsx` 1047, `persistence.ts` 1020, `render-model.ts` 928, `world.ts` 834, and `types.ts` 804. |
| Product/tests                                     | Not run          | This was a read-and-report architecture pass with no product code changes. Session 01 already recorded the full baseline gates.                                                                                                   |

**Boundary map**:

| Boundary           | Current shape                                                                                                                                                                         | Session 03 status                                                                                                                          |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| Host registration  | `registry.ts` statically registers the AI Rogue client shell but only enables it when public-demo mode is active or `VITE_CLAUDE_OS_ENABLED_EXTENSIONS` allows it.                    | Holds. Public-demo and env-gate logic stay in host code.                                                                                   |
| Extension shell    | `client.tsx` imports icons/capabilities and lazy-loads Play, Ledger, Loadout, and Settings views.                                                                                     | Holds. No runtime/Pixi import is reachable from the client shell.                                                                          |
| Host LiveData      | `use-extension-data.ts` returns full browser-safe host LiveData for enabled `runtimeDataMode: "host-live-data"` extensions without requiring `liveData.extensions.items["ai-rogue"]`. | Holds. D3 must still inspect allowed/denied data classes.                                                                                  |
| Views              | Play owns seed/share/progression/save wiring and mounts `AiRogueRuntimeCanvas`; Ledger/Loadout/Settings stay on economy, persistence, and preferences.                                | Mostly holds. The Play view also owns a test scenario query path; see finding AR-D1-002.                                                   |
| Runtime bridge     | `runtime-canvas.tsx` dynamically imports `../runtime`, mounts the controller, guards stale mounts with a generation ref, and destroys controllers on cleanup.                         | Holds for lazy loading and teardown ownership. Public barrel width remains a refactor concern; see AR-D1-003.                              |
| Renderer           | `runtime/index.ts` dynamically imports `renderer.ts`; `renderer.ts` dynamically imports Pixi, audio, and effects and owns browser globals, listeners, ticker, and canvas resources.   | Mostly holds. Command application flows through simulation APIs, but selected-upgrade/loadout mutations happen in renderer; see AR-D1-001. |
| Simulation/content | Pure gameplay modules import only other runtime modules/types and have no browser, Pixi, React, persistence, or host imports in the boundary sweep.                                   | Holds for forbidden import/global checks. D2 must still audit correctness and determinism internals.                                       |

**Architecture findings queued for the final report**:

```
[D1][High] AR-D1-001 Renderer mutates run state outside simulation APIs
  Location: src/extensions/ai-rogue/runtime/renderer.ts:852
  Observation: `updateSelectedUpgrade` calls renderer-local
  `applySelectedUpgradeToRun`, and `updateProgressionLoadout` directly replaces
  `state.runState.progressionLoadout` before turn 0. The helper mutates player
  health/maxHealth at `renderer.ts:1052`. This is outside the public simulation
  API path used by commands (`applyAiRogueCommand` at `renderer.ts:461` and
  `createAiRogueRun` at `simulation.ts:452`).
  Impact: Boundary violation. Run-state rules live partly in the renderer,
  which makes simulation refactors and replay/correctness audits harder and can
  let renderer behavior drift from headless simulation tests.
  Recommendation: Move selected-upgrade and pre-start loadout application into
  simulation-owned APIs or `createAiRogueRun` options. Renderer should request
  a run-state transition rather than editing `AiRogueRunState` directly.
  Related: D2 determinism, D5 type/API surface, D8 characterization tests.

[D1][Medium] AR-D1-002 Production Play route exposes the combat fixture scenario
  Location: src/extensions/ai-rogue/views/play-view.tsx:125
  Observation: The Play route reads `?scenario=combat` from the browser query
  string and passes it into `AiRogueRuntimeCanvas`. `renderer.ts:958` documents
  that this scenario is a deterministic forced-encounter fixture for browser
  tests, and `renderer.ts:961` swaps world generation to
  `createAiRogueScenarioWorld("combat")` from `simulation-fixtures.ts:50`.
  Impact: The real extension route contains an unguarded test/debug path that
  changes run generation in production and public-demo contexts. This is not a
  privacy leak by itself, but it weakens the user-facing runtime contract and
  should be resolved before default enablement.
  Recommendation: Gate fixture scenarios behind a test/local-only flag, move
  the e2e hook to a test-only harness, or make production/public-demo routes
  ignore `scenario` query params. Session 05/06 should also verify seed sharing
  never preserves debug scenario params.
  Related: D2 seed/replay correctness, D3 public-demo privacy, D8 e2e coverage.

[D1][Medium] AR-D1-003 Runtime public surface is too wide for refactor safety
  Location: src/extensions/ai-rogue/runtime/index.ts:3
  Observation: The runtime barrel re-exports most simulation/content modules
  plus `simulation-fixtures.ts` from `index.ts:3-19`, while also exposing
  `mountAiRogueRuntime` at `index.ts:91`. `runtime/types.ts:1-16` imports and
  re-exports domain and persistence schema types, producing 7 type-only cycles
  centered on `runtime/types.ts` in the import-graph check.
  Impact: No runtime cycle was found, but the public API, test fixtures,
  persistence schema types, and core runtime types are coupled through one
  barrel. This raises refactor risk and makes it unclear which exports are
  stable runtime contracts versus test/internal helpers.
  Recommendation: Split a narrow mount/controller entrypoint from simulation
  internals, move fixture helpers behind an explicit testing entrypoint, and
  separate core simulation types from persistence/schema-derived types before
  large module splits.
  Related: D5 type/API surface, D8 refactor prerequisite tests, D9 dead API.
```

**Oversized-module refactor notes for Session 13**:

| Module                     | Lines | Initial seam notes                                                                                                                                                           |
| -------------------------- | ----: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `runtime/simulation.ts`    |  3108 | Split only after D2 coverage: command reducer, enemy turn pipeline, floor progression/objectives, protocol/terminal resolution, and snapshot creation are likely seams.      |
| `runtime/renderer.ts`      |  1605 | Split controller/run lifecycle, Pixi layer/resource ownership, input bridge, render scheduling, audio/effects adapters, and move run-state helpers back to simulation first. |
| `save-schema.ts`           |  1247 | Split persisted schemas/defaults, parsing/migration helpers, wallet/ledger operations, run-save serialization, and loadout purchase helpers after D5/D9 checks.              |
| `runtime/effects.ts`       |  1057 | Split camera/shake, transient text, particles, floor/relic/end-screen presentation, and reduced-motion gates after D4/D6 coverage.                                           |
| `views/runtime-canvas.tsx` |  1047 | Split runtime bridge hook, event summaries, compact controls, save/load/reset actions, and status/notice panels after D6/D7 checks.                                          |
| `persistence.ts`           |  1020 | Split localStorage preferences, IndexedDB stores, migrations, reset/delete flows, and fallback adapters after D5/D7 checks.                                                  |
| `runtime/render-model.ts`  |   928 | Split projection helpers, sprite ordering, HUD descriptors, inspection labels, and preference/high-contrast mapping after D4/D6 checks.                                      |
| `runtime/world.ts`         |   834 | Split world generation, row fixtures/parsing, tile helpers, and position utilities after D2 determinism checks.                                                              |
| `runtime/types.ts`         |   804 | Split core run-state types, runtime controller/event types, render asset frame names, and persistence/progression bridge types; remove the type-only cycle center.           |

**Files changed this session**:

* `docs/ongoing-projects/ai-rogue-audit-plan.md`

**Target report path**:

* `.spec_system/PRD/phase_35/PRD_phase_35.md` still does not exist. Session 03 queued the D1 findings above for the final Session 14 synthesis rather than creating the final report early.

**Remaining work**:

* Run Session 04 Simulation Correctness next.
* In Session 04, validate whether AR-D1-001 has determinism or replay impact beyond architecture risk.
* In Sessions 05-06, verify `scenario` query params and seed-share URLs do not leak or preserve debug/test state.
* In Session 09, decide whether AR-D1-003 should become a D5 API/type finding as well as a D1 architecture finding.

**2026-06-25 qimpl Session 04 Simulation Correctness**

**Scope executed**: Session 04 Simulation Correctness only. No product code changes were made. This pass focused on D2 seeded RNG, replay ordering, turn-start status damage, enemy turns, sentry threats, objective-locked exits, thief behavior, compile milestones, traversal protocols, floor arcs, equipment, shield buffer, and existing headless evidence. Economy, persistence, privacy, rendering, types, accessibility, robustness, and full coverage synthesis remain assigned to Sessions 05-12.

**Files and surfaces inspected**:

* Core simulation/reducer paths: `runtime/simulation.ts`, especially `createAiRogueRun`, `applyAiRogueCommand`, movement, Strike, Surge, Protocol, enemy turns, pending sentry threats, floor descent, compile, terminal, crash dump, vault, and final payload compile paths.
* Determinism helpers and content systems: `runtime/rng.ts`, `runtime/world.ts`, `runtime/fov.ts`, `runtime/initiative.ts`, `runtime/status.ts`, `runtime/combat.ts`, `runtime/entities.ts`, `runtime/floor-arc.ts`, `runtime/compile.ts`, `runtime/equipment.ts`, `runtime/protocols.ts`, and `runtime/terminals.ts`.
* Runtime unit coverage for D2 systems: combat, simulation, status, status-expanded, protocols, traversal-verbs, objective-lock, thief, cascade, shield-buffer, equipment, rng, world, fov, initiative, compile, floor-arc, prefabs, terminals, ecology, enemy-effects, and related AI Rogue unit specs.
* Headless playthrough harness: `scripts/ai-rogue-playthrough.ts`.

**Focused checks run**:

| Check                                 | Result           | Evidence                                                                                                                                                                                                                         |
| ------------------------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Determinism/time hazard sweep         | Run              | No `Math.random()` hits in AI Rogue runtime/source. `new Date()`/`Date.now()` hits are outside pure simulation: runtime input, renderer event timestamps, economy/claim/persistence metadata, and runtime canvas start metadata. |
| Ordering hazard sweep                 | Run              | Deterministic sort/tie-break patterns were present for FOV/exploration, status effects, enemy order, pending threats, world spawns, and render projections. No untriaged `Object.keys`/Map/Set run-state ordering bug promoted.  |
| Start-of-turn status action audit     | Finding          | Movement and Strike guard `turnStart.defeated`; Surge and Protocol do not, producing AR-D2-001.                                                                                                                                  |
| Sentry threat control-flow inspection | Pass             | False alarm resolved: ranged-sentry behavior branches before generic attack range, so sentries telegraph and pending threats resolve on the next enemy turn. Existing tests cover open, blocked, dodged, dead-sentry cases.      |
| Runtime unit suite                    | Pass             | `bun run test -- src/extensions/ai-rogue/runtime/__tests__ src/extensions/ai-rogue/__tests__` passed: 41 files, 265 tests.                                                                                                       |
| Headless playthrough harness          | Pass with caveat | `bun run scripts/ai-rogue-playthrough.ts` exited 0 across 6 seeds: 2 won, 1 lost, 3 still active at the 4000-turn cap. Active capped runs still require Session 04/12 follow-up classification before soft-lock claims.          |
| Lethal DOT direct reproduction        | Finding          | Direct `bun -e` runtime import showed Patch Kit can return a health-0 DOT-ticked player to active status, and Surge still spends shards/attacks after lethal DOT before the loss event is committed.                             |

**Replay-risk matrix**:

| Risk area                | Session 04 assessment                                                                                                                                                                                                               | Follow-up                                                                              |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| RNG source               | Pure runtime generation and combat use `createAiRogueRng`/snapshots. No runtime `Math.random()` hit was found.                                                                                                                      | Keep in D8 determinism coverage map.                                                   |
| Wall-clock time          | Time usage found in UI/runtime metadata, claim/economy dates, persistence timestamps, and renderer events. No source evidence that wall-clock time affects map generation, combat, enemy AI, reward selection, or replayable state. | Recheck persistence/save timestamps in Session 05.                                     |
| Ordering/tie-breaks      | Enemy turns sort by id, pending sentry threats sort by turn/enemy/id, FOV/explored tiles sort by coordinate, world spawns sort by coordinate, and status effects sort by fixed status order.                                        | D8 should add/confirm regression tests for any refactor that touches these sorts.      |
| Turn-start status damage | Inconsistent action guards across verbs let Surge/Protocol resolve after lethal DOT. This is a real run-state correctness bug.                                                                                                      | File AR-D2-001 in final report and add targeted characterization tests before fixing.  |
| Headless run completion  | Harness proves multi-floor wins/losses, but 3 of 6 seeds remain active at 4000 turns with nonzero health. This is not yet evidence of a soft-lock because the simple policy may fail to solve the floor.                            | Classify in D8/test coverage or a later D2 follow-up if the audit reopens correctness. |

**Simulation correctness finding queued for the final report**:

```
[D2][High] AR-D2-001 Surge and Protocol actions resolve after lethal status damage
  Location: src/extensions/ai-rogue/runtime/simulation.ts:2419
  Observation: `applyPulseCommand` ticks player status at `simulation.ts:2419`
  but does not stop when `turnStart.defeated` is true, then subtracts shards
  and resolves Surge attacks at `simulation.ts:2421-2465`. `applyProtocolCommand`
  has the same gap after `simulation.ts:2499`; a Patch Kit can purge/heal a
  player whose health has already reached 0. Movement and Strike do guard this
  case with `turnStart.defeated` at `simulation.ts:841` and
  `simulation.ts:2288`, so the behavior is inconsistent across verbs.
  Impact: Reachable run-state correctness bug. A player killed by burning or
  leaking at turn start can still spend resources, kill enemies, clear threats,
  or even return to active status through Patch Kit healing instead of losing
  immediately. This can change win/loss outcomes and undermines replay
  characterization before default enablement.
  Recommendation: Centralize the player turn-start status tick for all action
  verbs, or make Surge/Protocol return the same loss/no-action path used by
  Movement and Strike when `turnStart.defeated` is true. Add tests covering
  lethal DOT before movement, Strike, Surge, and each Protocol branch.
  Related: D8 characterization tests, D5 runtime API/refactor map.
```

**Manual reproduction evidence for AR-D2-001**:

```
bun -e runtime import:
- Patch Kit state: player health 1, burning amount 1, protocol queue ["patch-kit"].
  Result was status "active", health 2, protocol queue [], with events:
  status DOT, Patch Kit repair/purge, Cache Wraith attack.
- Surge state: player health 1, burning amount 1, 9 shards, adjacent Cache Wraith.
  Result was status "lost", health 0, shards 6, but events still included
  Surge pulse, player attack, and enemy defeat before the loss event.
```

**Covered systems without promoted findings**:

* Seeded RNG restore, `nextInt`, `chance`, `shuffle`, weighted choice, seed normalization, and generated-world determinism are covered by existing `rng.test.ts` and `world.test.ts`.
* FOV and explored-tile ordering are deterministic and covered by `fov.test.ts`.
* Initiative uses integer meters and deterministic action caps; existing tests cover baseline, fast, slow, and lagged behavior.
* Enemy turn order sorts alive enemies by id, sentry threats sort by turn/enemy/id, and the current combat tests cover melee, sentry telegraph, blocked LOS, dodge, dead-sentry cleanup, and pending-threat restore.
* Objective locks, crash-dump purges, Phase Step exit landings, Trace Lance, Signal Jammer, Packet Thief steal/flee/drop, compile milestones, equipment, shield buffer, and deterministic cascade all have existing focused tests.

**Highest-value characterization tests queued**:

* Lethal start-of-turn DOT across every player verb: movement, Strike, Surge, Patch Kit, Trace Map, Trace Lance, Phase Step, and Signal Jammer.
* Headless playthrough classification for the three 4000-turn active seeds: determine whether the harness policy stalls, the floor objective is reachable but unsolved, or a real soft-lock exists.
* Refactor guard for enemy-turn ordering after splitting `simulation.ts`: two enemies with conflicting moves/attacks should produce stable event order and identical serialized state from identical seed/input.
* Final-floor payload compile with pending sentry threat and lethal DOT on the same turn, so win/loss ordering remains explicit before moving compile logic.
* Protocol effects that land on exits or pickups, ensuring consumed protocol queues, enemy turns, objective locks, and payload compile resolution stay stable after any reducer extraction.

**Files changed this session**:

* `docs/ongoing-projects/ai-rogue-audit-plan.md`

**Target report path**:

* `.spec_system/PRD/phase_35/PRD_phase_35.md` still does not exist. Session 04 queued AR-D2-001 for final Session 14 synthesis rather than creating the final report early.

**Remaining work**:

* Run Session 05 Economy And Persistence next.
* In Session 05, audit durable state, wallet/ledger behavior, migrations, reset boundaries, and seed sharing, including whether debug `scenario` query params can be saved or shared.
* In Session 08/12, preserve the playthrough harness caveat: 3 of 6 seeds hit the 4000-turn active cap and need classification before soft-lock language is used.
* In Session 12, record the lethal-DOT verb matrix as a high-priority missing characterization test set.

**2026-06-25 qimpl Session 05 Economy And Persistence**

**Scope executed**: Session 05 Economy And Persistence only. No product code changes were made. This pass focused on durable wallet/ledger writes, claim idempotency and caps, legacy claim migration, localStorage/IndexedDB recovery, AI-Rogue-only reset scope, save-slot schema safety, and seed share URL normalization. Privacy rendering, capability-vs-behavior, public-demo storage language, performance, type/API synthesis, accessibility, robustness, coverage, and final report synthesis remain assigned to Sessions 06-14.

**Files and surfaces inspected**:

* Economy and claim derivation: `economy.ts`, `economy-schema.ts`, and `claim-store.ts`.
* Persistence contracts: `save-schema.ts`, `persistence.ts`, and `use-save-state.ts`.
* Seed sharing and route integration: `seed-share.ts` and `views/play-view.tsx`.
* Wallet, ledger, and reset UI integration: `views/ledger-view.tsx`, `views/settings-view.tsx`, and related unit/e2e tests.

**Focused checks run**:

| Check                        | Result           | Evidence                                                                                                                                                                                                                                                                                                                                                                        |
| ---------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Economy cap/source audit     | Pass             | `deriveAiRogueEconomy` applies locked source weights, ignores unknown pricing/missing token data for only the token source, sets example LiveData to unclaimable, and caps the daily claim at 100 shards. Existing economy tests cover these cases.                                                                                                                             |
| Claim idempotency audit      | Pass with caveat | Current Ledger UI uses `writeAiRogueClaimEntryDurable`, which schema-validates claims before localStorage and durable writes. Existing unit/e2e tests show duplicate redemption keys stay single-claimed. Direct `recordAiRogueClaim` validation has a schema drift; see AR-D5-001.                                                                                             |
| Durable transaction audit    | Pass             | IndexedDB claim, upgrade purchase, and run-summary paths use multi-store readwrite transactions in the default adapter. `useAiRogueSaveState` serializes mutations with `operationRef`, and Ledger also guards claims with `claimInFlightRef`.                                                                                                                                  |
| Migration/recovery audit     | Pass             | Preferences recover from bad JSON to defaults; malformed/future wallet records reset safely; malformed ledger/run/save-slot records are dropped or reset with warnings; legacy localStorage claims migrate into wallet and ledger persistence.                                                                                                                                  |
| Reset-boundary audit         | Pass             | Reset removes only `ai-os.ai-rogue.preferences.v1` and `ai-os.ai-rogue.claims.v1` from localStorage and clears only the AI Rogue IndexedDB stores `wallet`, `ledger`, `runHistory`, and `saveSlots`; unrelated localStorage keys are preserved in unit and e2e coverage.                                                                                                        |
| Seed sharing audit           | Pass             | `createAiRogueSeedShareUrl` clears `url.search` and `url.hash` before setting only `seed`, so `scenario=combat`, debug query params, and fragments are not preserved in copied share URLs. Private-looking seed text is rejected before normalization.                                                                                                                          |
| Oversized claim reproduction | Finding          | Direct `bun --eval` import of `recordAiRogueClaim` with `amount: 250` returned `{ok:true,walletBalance:100,ledgerAmount:250,balanceAfter:100}`, proving wallet cap and ledger amount can diverge when bypassing the Ledger UI's stricter claim-store validator.                                                                                                                 |
| Focused unit tests           | Pass             | `bun run test -- src/extensions/ai-rogue/__tests__/economy.test.ts src/extensions/ai-rogue/__tests__/claim-store.test.ts src/extensions/ai-rogue/__tests__/persistence.test.ts src/extensions/ai-rogue/__tests__/save-schema.test.ts src/extensions/ai-rogue/__tests__/seed-share.test.ts src/extensions/ai-rogue/__tests__/use-save-state.test.tsx` passed: 6 files, 55 tests. |
| Focused browser e2e tests    | Pass             | `bun run test:e2e -- tests/e2e/ai-rogue-ledger.spec.ts tests/e2e/ai-rogue-persistence.spec.ts` passed: 2 Chromium tests covering once-only Ledger claims, refresh persistence, preferences, save readiness, and scoped reset.                                                                                                                                                   |

**Migration and reset-boundary checklist**:

| Area            | Session 05 assessment                                                                                                                                                                                                            |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Preferences     | v0 preferences migrate to v1, missing fields default safely, invalid JSON and invalid current input modes reset to defaults with warnings.                                                                                       |
| Wallet          | v0 wallet balance/earned values migrate; unsupported future versions and malformed current records reset to defaults. Claim keys gate duplicate wallet credits.                                                                  |
| Ledger          | Malformed or private-looking entries are dropped individually; valid entries are capped to the ledger limit. A public durable claim helper can still create ledger amount drift for oversized direct claims; see AR-D5-001.      |
| Run history     | Malformed entries are dropped individually, valid summaries stay bounded, and run summary transactions update achievement metadata idempotently.                                                                                 |
| Save slots      | Three-slot shape is enforced; incomplete or malformed slot records reset safely; runtime snapshots reject private text in summaries/metadata and require ready snapshots to include run state.                                   |
| Legacy claims   | Legacy localStorage claim records parse through `aiRogueClaimRecordSchema` before migration and each migrated entry is committed through the durable claim path.                                                                 |
| Reset           | localStorage reset is allowlisted to AI Rogue keys only. IndexedDB reset clears AI Rogue stores only. If IndexedDB reset fails after localStorage removal, the localStorage keys are restored and the reset fails with warnings. |
| Seed/share URLs | Manual/query seeds normalize to bounded share-safe text; private-looking seeds fall back/reject without echoing private text; share URL creation drops every query/hash field except the normalized `seed`.                      |

**Economy and persistence finding queued for the final report**:

```
[D5][Medium] AR-D5-001 Durable claim validation can drift wallet and ledger amounts
  Location: src/extensions/ai-rogue/persistence.ts:1006
  Observation: `recordAiRogueClaim` validates claims with the local
  `zodClaimEntry` helper, which checks schema version, currency, required
  strings, and non-negative integer amount, but does not reuse
  `aiRogueClaimEntrySchema` or enforce the 100-shard daily cap. The wallet path
  clamps claim amount to the daily cap at `save-schema.ts:1174`, while the
  ledger entry writes the original `claim.amount` at `save-schema.ts:1135`.
  Direct reproduction with `amount: 250` returned wallet balance 100,
  ledger amount 250, and balanceAfter 100.
  Impact: Durable wallet/ledger records can disagree if this exported
  persistence helper is called with an oversized claim or a future malformed
  claim shape. The current Ledger UI path validates through
  `writeAiRogueClaimEntryDurable` at `claim-store.ts:213`, so this is not the
  normal browser claim path, but it is a persistence API contract gap that can
  corrupt audit evidence and future callers.
  Recommendation: Replace `zodClaimEntry` with `aiRogueClaimEntrySchema`
  parsing, or clamp once into a normalized claim before both wallet and ledger
  writes. Add a regression test that direct `recordAiRogueClaim` rejects or
  normalizes claims above `AI_ROGUE_DAILY_SHARD_CAP`.
  Related: D3 privacy/capability API surface, D8 persistence coverage,
  Session 13 save-schema/persistence refactor map.
```

**Covered systems without promoted findings**:

* Unknown pricing and missing token data reduce only the token/spend source, while other sources can still contribute.
* Example LiveData is not claimable and returns unavailable contribution rows.
* Claim redemption keys combine date, provider, source, and run id; duplicate keys remain idempotent through both legacy localStorage and durable wallet/ledger state.
* Default IndexedDB claim and upgrade writes are transaction-scoped across wallet and ledger stores. Run-summary writes are transaction-scoped across run history and wallet achievements when the default adapter is used.
* Seed share URLs strip `scenario=combat`, debug query params, private-looking query text, and hash fragments from copied replay URLs.
* Settings reset copy and implementation both restrict reset to AI Rogue localStorage keys and AI Rogue IndexedDB stores.

**Highest-value follow-up checks queued**:

* Add the direct `recordAiRogueClaim` oversized-amount regression named in AR-D5-001 before refactoring `persistence.ts` or `save-schema.ts`.
* In Session 06, verify public-demo copy and storage behavior directly against hosted/static-demo constraints, not just normal dev e2e.
* In Session 07/11, re-check IndexedDB/localStorage unavailable paths from the mounted Play/Ledger/Settings views so UI fallback copy matches the source recovery behavior.
* In Session 12, map the current persistence tests to D3/D5/D7 coverage and note that direct durable claim validation currently lacks an over-cap test.

**Files changed this session**:

* `docs/ongoing-projects/ai-rogue-audit-plan.md`

**Target report path**:

* `.spec_system/PRD/phase_35/PRD_phase_35.md` still does not exist. Session 05 queued AR-D5-001 for final Session 14 synthesis rather than creating the final report early.

**Remaining work**:

* Run Session 07 Render And Performance next.
* Preserve AR-D5-001 as a D5 durable consistency/API contract finding. Session 06 found no D3 escalation because the normal Ledger path validates claims and no private data class is introduced by the direct helper drift.
* In Session 08, revisit stale historical no-audio/no-remote-loading language against the current local Web Audio asset runtime.

**2026-06-25 qimpl Session 06 Privacy Boundary**

**Scope executed**: Session 06 Privacy Boundary only. No product code changes were made. This pass focused on declared capabilities, host-LiveData routing, allowed and denied LiveData classes, seed/share URL handling, local persistence privacy, public-demo browser-local behavior, adversarial fixtures, and whether AR-D5-001 should be escalated into D3. Rendering lifecycle, audio/bundle budget, types, accessibility, robustness, coverage synthesis, refactor map, and final findings synthesis remain assigned to Sessions 07-14.

**Files and surfaces inspected**:

* Privacy contracts: `docs/extensions/ai-rogue/runtime-data-and-enablement.md`, `docs/extensions/ai-rogue/enablement-decision.md`, `docs/extensions/ai-rogue/implementation-baseline.md`, extension platform docs, and the Session 05 evidence in this work file.
* Capability and host wiring: `src/extensions/ai-rogue/capabilities.ts`, `src/extensions/ai-rogue/client.tsx`, `src/extensions/types.ts`, `src/extensions/registry.ts`, `src/extensions/use-extension-data.ts`, `src/lib/setup-config.ts`, and `scripts/lib/pages-demo-routes.ts`.
* Privacy-sensitive AI Rogue code: `economy.ts`, `progression.ts`, `save-schema.ts`, `persistence.ts`, `claim-store.ts`, `seed-share.ts`, `use-save-state.ts`, `views/play-view.tsx`, `views/ledger-view.tsx`, `views/loadout-view.tsx`, `views/settings-view.tsx`, `runtime/audio.ts`, and `runtime/assets.ts`.
* Tests and fixtures: AI Rogue unit specs under `src/extensions/ai-rogue/__tests__/`, `src/lib/__tests__` extension status specs, `tests/e2e/ai-rogue-{runtime,ledger,persistence,enablement}.spec.ts`, and `tests/e2e/pages-demo-mobile.spec.ts`.

**Focused checks run**:

| Check                         | Result           | Evidence                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ----------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Capability-vs-behavior audit  | Pass             | `AI_ROGUE_CAPABILITIES` declares `readGeneratedData`, `localStorage`, and `indexedDB`. No AI Rogue `networkAccess` declaration exists, and source search found no collector, `XMLHttpRequest`, `WebSocket`, `EventSource`, `sendBeacon`, worker, hosted storage, or LiveData file writes.                                                                                                                                                                                                                          |
| Host-LiveData routing audit   | Pass             | `client.tsx` declares `runtimeDataMode: "host-live-data"`. `useExtensionData` returns the host LiveData payload for enabled host-data extensions without requiring `liveData.extensions.items["ai-rogue"]`. Public-demo mode enables registered extensions through `registry.ts`/`setup-config.ts`.                                                                                                                                                                                                                |
| Allowed/denied data audit     | Pass             | `economy.ts` and `progression.ts` derive counts, dates, source categories, bounded labels, capped token/spend signals, readiness labels, and provenance notes. Private-looking prompts, transcripts, commands, command output, private paths, credentials, tokens, raw payloads, and logs are dropped or replaced before display/persistence.                                                                                                                                                                      |
| Persistence privacy audit     | Pass             | `save-schema.ts` rejects private-looking persisted labels, event messages, run summaries, runtime metadata, progression source labels, ledger entries, and save slots. Local keys are scoped under `ai-os.ai-rogue.*` and IndexedDB uses `ai-os.ai-rogue.persistence`.                                                                                                                                                                                                                                             |
| Seed/share URL audit          | Pass             | `seed-share.ts` rejects private-looking seed input, bounds normalized seed text, strips every query/hash field from copied share URLs, and writes only the normalized `seed` parameter. Existing runtime e2e covers `debug=/home/private#transient` stripping.                                                                                                                                                                                                                                                     |
| Public-demo storage audit     | Pass             | AI Rogue Play, Ledger, Loadout, and Settings are all in the public-demo mobile route matrix. Browser tests passed with no `"/__"` local bridge requests and copy states that runs, saves, claims, loadout, and settings stay in this browser rather than hosted storage.                                                                                                                                                                                                                                           |
| Remote/static asset audit     | Pass with caveat | Source search found one `fetch(url)` in `runtime/audio.ts`. The URL comes only from eager Vite `import.meta.glob` maps for committed local Ogg assets under `src/assets/ai-rogue/audio/`; no user, LiveData, or remote URL can reach it. Session 08 should handle audio lifecycle/budget and stale no-audio doc drift.                                                                                                                                                                                             |
| AR-D5-001 D3 escalation check | No D3 finding    | The direct `recordAiRogueClaim` over-cap drift can disagree on wallet/ledger amounts, but it does not expose a denied data class. The normal Ledger path validates through `writeAiRogueClaimEntryDurable`, and adversarial UI/e2e coverage shows private strings do not render.                                                                                                                                                                                                                                   |
| Focused unit tests            | Pass             | `bun run test -- src/extensions/ai-rogue/__tests__/economy.test.ts src/extensions/ai-rogue/__tests__/claim-store.test.ts src/extensions/ai-rogue/__tests__/progression.test.ts src/extensions/ai-rogue/__tests__/save-schema.test.ts src/extensions/ai-rogue/__tests__/seed-share.test.ts src/extensions/ai-rogue/__tests__/client.test.tsx src/lib/__tests__/extension-registry.test.ts src/lib/__tests__/use-extension-data.test.tsx src/lib/__tests__/settings-extensions.test.tsx` passed: 9 files, 104 tests. |
| Focused browser e2e tests     | Pass             | `bun run test:e2e -- tests/e2e/ai-rogue-ledger.spec.ts tests/e2e/ai-rogue-persistence.spec.ts tests/e2e/ai-rogue-runtime.spec.ts tests/e2e/ai-rogue-enablement.spec.ts tests/e2e/pages-demo-mobile.spec.ts` passed: 35 Chromium tests.                                                                                                                                                                                                                                                                             |

**Capability-vs-behavior matrix**:

| Capability          | Declared | Behavior observed                                                                                                                              | Session 06 assessment                                                      |
| ------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| `readGeneratedData` | Yes      | Play, Ledger, and Loadout read browser-safe host LiveData through host-data routing and `useLiveDataQuery`.                                    | Matched. No collector item is required or expected.                        |
| `localStorage`      | Yes      | Preferences and the legacy claim idempotency guard use `ai-os.ai-rogue.preferences.v1` and `ai-os.ai-rogue.claims.v1`.                         | Matched and AI-Rogue-scoped.                                               |
| `indexedDB`         | Yes      | Wallet, ledger, run history, and save slots use `ai-os.ai-rogue.persistence` stores.                                                           | Matched and AI-Rogue-scoped.                                               |
| `networkAccess`     | No       | No remote API/client collector behavior was found. Audio uses same-build local asset URLs generated by Vite, not remote or user-supplied URLs. | Matched for D3; Session 08 should document local asset loading separately. |
| Hosted storage      | No       | Public-demo copy and tests show claims/saves/settings remain browser-local. No AI Rogue server write path was found.                           | Matched.                                                                   |

**Privacy-boundary findings queued for the final report**:

* None from Session 06. Existing AR-D5-001 remains queued as a D5 persistence API consistency finding, not a D3 privacy/capability finding.

**Covered systems without promoted findings**:

* Ledger adversarial fixtures include private workspaces, private-looking tool labels, raw command strings, and secret prompt text; UI/e2e assertions confirm these strings do not render.
* Economy and progression source labels use private-text patterns plus bounded fallback labels before labels become provenance, loadout, or persisted source-label data.
* Save schemas reject private-looking runtime summaries and metadata, malformed ledger/run entries are dropped, and save-slot records cannot persist raw prompt/path metadata.
* Seed normalization rejects private-looking query/manual seed text without echoing the rejected content in the status message.
* Public-demo Play/Ledger/Loadout/Settings routes render in the hosted demo matrix without local bridge requests or document overflow.
* Capability declarations match current behavior: no collector, hosted storage, network access, raw telemetry export, or LiveData file write path was found.

**Highest-value follow-up checks queued**:

* In Session 07, audit runtime/audio imports from route mount to unmount so the local asset fetch and Web Audio engine are owned and disposed correctly.
* In Session 08, update stale audio/no-audio and remote-loading documentation claims if the asset/audio audit confirms current behavior.
* In Session 11, re-check unavailable localStorage, IndexedDB, clipboard, and Web Audio paths from mounted views for user-visible fallback copy.
* In Session 12, map the existing adversarial privacy fixtures to D3 coverage and decide whether a dedicated public-demo storage assertion should inspect IndexedDB/localStorage contents after hosted-demo Play/Ledger interactions.

**Files changed this session**:

* `docs/ongoing-projects/ai-rogue-audit-plan.md`

**Target report path**:

* `.spec_system/PRD/phase_35/PRD_phase_35.md` still does not exist. Session 06 did not create a privacy finding; final Session 14 synthesis should record the no-new-D3-finding result alongside AR-D2-001 and AR-D5-001.

**Remaining work**:

* Run Session 07 Render And Performance next.
* Carry forward the local audio asset-fetch caveat to Session 08 for asset/audio/bundle classification and any needed doc-drift entry.
* Carry forward the possible D3 coverage improvement for Session 12: public-demo browser-local state is copy/e2e-route covered, but a storage-content assertion after hosted-demo interactions may make the evidence stronger.

**2026-06-25 qimpl Session 07 Render And Performance**

**Scope executed**: Session 07 Render And Performance only. No product code changes were made. This pass focused on runtime mount/unmount ownership, lazy Pixi/runtime loading, active ticker render work, sprite/effects/audio lifecycle, resize and visibility behavior, reduced-motion render throttling, and the bundle budget baseline. Asset provenance, audio budget policy, type/API synthesis, accessibility, robustness, coverage mapping, refactor sequencing, and final report synthesis remain assigned to Sessions 08-14.

**Files and surfaces inspected**:

* Runtime mount boundary: `views/runtime-canvas.tsx`, `views/play-view.tsx`, `client.tsx`, and `runtime/index.ts`.
* Pixi/render pipeline: `runtime/renderer.ts`, `runtime/render-model.ts`, `runtime/effects.ts`, `runtime/pixi-runtime.ts`, and `runtime/assets.ts`.
* Audio lifecycle path: `runtime/audio.ts`.
* Bounded log/source support for render pressure triage: `runtime/combat.ts`, `runtime/simulation.ts`, `runtime/world.ts`, and `runtime/entities.ts`.
* Focused browser coverage: `tests/e2e/ai-rogue-runtime.spec.ts`, `tests/e2e/ai-rogue-mobile.spec.ts`, and `tests/e2e/pages-demo-mobile.spec.ts`.

**Focused checks run**:

| Check                         | Result           | Evidence                                                                                                                                                                                                                                                                                                                               |
| ----------------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Lazy runtime/Pixi route audit | Pass             | `client.tsx` lazy-loads AI Rogue views. `runtime-canvas.tsx` imports `../runtime` only after Play canvas mount. `runtime/index.ts` then dynamically imports `./renderer`, and `renderer.ts` dynamically imports `./pixi-runtime`.                                                                                                      |
| Mount/unmount ownership audit | Pass             | React mount generations destroy stale controllers. Renderer `destroy()` disposes audio/effects/input, disconnects ResizeObserver, removes pointer/visibility/reduced-motion/blur/resize listeners, cancels RAF, clears sprites, and destroys Pixi.                                                                                     |
| Visibility/blur audit         | Pass             | `visibilitychange` stops the ticker and resumes only when it was previously running. Window blur pauses only when `autoPauseOnBlur` is true.                                                                                                                                                                                           |
| Effects lifecycle audit       | Pass             | Floating text, impact sprites, and particles self-remove on TTL expiry. `clearTransient()` and `destroy()` destroy remaining transient objects, HUD text, flash, intro/relic/fade elements, and the end screen.                                                                                                                        |
| Audio lifecycle audit         | Pass with caveat | Web Audio degrades to a silent engine when unavailable, decodes local Ogg URLs on demand, uses a bounded URL buffer cache, stops retained music/heartbeat handles, clears cache, and closes the context on dispose. One-shot SFX handles are not retained, but dispose sets `disposed` and closes the context; no promoted D4 finding. |
| Sprite-pool audit             | Finding          | Active sprites are pooled, but inactive descriptors are hidden rather than destroyed or deleted. Feedback descriptor ids include event ids, so hidden feedback sprites can accumulate across a long mounted run. See AR-D4-001.                                                                                                        |
| Per-frame render audit        | Finding          | The active ticker calls `render()`, which rebuilds and sorts the full render descriptor graph every rendered frame even when the simulation snapshot has not changed. See AR-D4-002.                                                                                                                                                   |
| Resize behavior audit         | Finding          | ResizeObserver and window resize both call the full resize/render path immediately with no RAF coalescing or debounce. See AR-D4-003.                                                                                                                                                                                                  |
| Bundle budget gate            | Pass             | `bun run budget:check` passed. Total client JS gzip was 1489 KB against a 1500 KB budget. AI Rogue chunks were lazy/split: `play-view` 10 KB gzip, `renderer` 10 KB, `render-model` 11 KB, `effects` 4 KB, `audio` 6 KB, `pixi-runtime` 61 KB.                                                                                         |
| Focused unit tests            | Pass             | `bun run test -- src/extensions/ai-rogue/__tests__/runtime-canvas.test.tsx src/extensions/ai-rogue/__tests__/client.test.tsx` passed: 2 files, 30 tests.                                                                                                                                                                               |
| Focused browser e2e tests     | Pass             | `bun run test:e2e -- tests/e2e/ai-rogue-runtime.spec.ts tests/e2e/ai-rogue-mobile.spec.ts` passed: 12 Chromium tests covering painted canvas, resize, movement, pause gating, seed replay, save/load, combat feedback, route cleanup, mobile compact controls, and reduced-motion route cleanup.                                       |

**Mount/unmount resource ownership map**:

| Resource                       | Owner                           | Teardown path / assessment                                                                                                                                                                                                  |
| ------------------------------ | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Pixi application/canvas/ticker | `runtime/renderer.ts`           | Created in `mountAiRogueRenderer`; `destroy()` removes ticker callback, stops ticker, destroys app, and removes the runtime canvas. E2E route-exit/remount coverage passed.                                                 |
| Pixi display layers            | `runtime/renderer.ts`           | Stage children are owned by the Pixi app and destroyed with app children. Effects-owned overlay objects are explicitly destroyed first.                                                                                     |
| Atlas textures/base assets     | `runtime/assets.ts`/Pixi        | Loaded through local Vite URLs and Pixi Assets. Frame textures are recreated per mount from cached atlas sources. No eager non-Play import path was found; Session 08 should handle asset budget/provenance policy details. |
| Sprite pool                    | `runtime/renderer.ts`           | Cleared on controller destroy. During an active mounted run, inactive descriptors are hidden and retained; feedback ids can grow with event history. AR-D4-001 queued.                                                      |
| Runtime ticker loop            | `runtime/renderer.ts`           | Runs only while `state.isRunning`; reduced motion caps Pixi ticker FPS at 12 and renders every fourth tick. Hidden tabs stop the ticker.                                                                                    |
| Input sampler                  | `runtime/input.ts` via renderer | Created against `window`; destroyed on controller destroy and reset on run reset/load/start.                                                                                                                                |
| Pointer listener               | `runtime/renderer.ts`           | Attached to the Pixi canvas and removed by `cleanupPointer()` on destroy.                                                                                                                                                   |
| ResizeObserver/window resize   | `runtime/renderer.ts`           | Disconnected/removed on destroy. Resize callbacks are unthrottled while mounted; AR-D4-003 queued.                                                                                                                          |
| Visibility and blur listeners  | `runtime/renderer.ts`           | Removed by cleanup functions on destroy.                                                                                                                                                                                    |
| Reduced-motion media listener  | `runtime/renderer.ts`           | Removed by cleanup function on destroy. User preference/OS interaction should be revisited in Session 10 accessibility.                                                                                                     |
| Effects transient objects      | `runtime/effects.ts`            | TTL cleanup plus reset/load/destroy cleanup. Reduced motion gates particles, shake, camera glide, idle animation, descend fade, and impact motion.                                                                          |
| Audio engine                   | `runtime/audio.ts`              | Dynamic renderer import only, lazy context creation, dispose stops retained loops/music, clears cache, and closes context. Session 08 should handle audio asset budget and documentation drift.                             |

**Render and performance findings queued for the final report**:

```
[D4][High] AR-D4-001 Hidden feedback sprites accumulate during long mounted runs
  Location: src/extensions/ai-rogue/runtime/renderer.ts:1298
  Observation: `syncSprites` creates a sprite for every descriptor id missing
  from `spritePool`, but inactive sprites are only set `visible = false` at
  `renderer.ts:1332` and remain in the pool until controller destroy clears all
  sprites at `renderer.ts:907`. Feedback descriptors use
  `feedback:${event.id}` at `render-model.ts:372`; combat log state is bounded
  to 12 events by `combat.ts:200`, but sprites for events that have already
  fallen out of the log are not deleted during the mounted run.
  Impact: A long active run can retain stale Pixi sprites for historical
  feedback events. This is a resource leak within a route mount and becomes
  more relevant because the baseline playthrough already observed runs still
  active at the 4000-turn cap.
  Recommendation: Delete and destroy inactive transient descriptor families
  such as `feedback:*` after they leave the active set, or split sprite pools
  into persistent world/HUD pools and TTL/transient pools with explicit caps.
  Add a regression that drives many combat events and asserts sprite-pool size
  stays bounded.
  Related: Session 12 coverage gaps, Session 13 renderer refactor map.

[D4][Medium] AR-D4-002 Active ticker rebuilds the full render model every frame
  Location: src/extensions/ai-rogue/runtime/renderer.ts:302
  Observation: Each rendered tick calls `createAiRogueRenderModel`, and the
  render model rebuilds arrays for tiles, fog, entities, feedback, threats,
  crash dumps, HUD sprites, HUD descriptors, and summary text before sorting the
  sprite list at `render-model.ts:91`. The active ticker calls `render()` from
  `renderer.ts:572` even when the simulation snapshot has not changed.
  Impact: This creates steady GC pressure in the hot render loop. The work is
  bounded by snapshot size, but it conflicts with the D4 contract that per-frame
  work avoid unnecessary allocations and makes renderer refactors riskier.
  Recommendation: Cache the projection by snapshot identity/turn/depth,
  viewport size, and render preferences, and keep clock-only animation
  (background drift, tweens, effects) separate from snapshot projection.
  Characterize render-model output before changing this path.
  Related: Session 13 render-model/renderer refactor map.

[D4][Medium] AR-D4-003 Resize callbacks perform immediate full resize/render work
  Location: src/extensions/ai-rogue/runtime/renderer.ts:634
  Observation: A `ResizeObserver` callback calls `resize()` directly, and the
  window `resize` listener at `renderer.ts:641` uses the same immediate path.
  `resize()` measures the host, resizes the Pixi renderer, resizes effects,
  renders immediately, and emits a resize event with no RAF coalescing or
  debounce.
  Impact: Continuous viewport/container resizing can force repeated full
  renderer resizes and render-model rebuilds, increasing jank risk on mobile
  rotation, split-screen, and responsive layout changes.
  Recommendation: Coalesce resize work through one pending animation frame, or
  debounce ResizeObserver/window resize into a single measured render pass.
  Keep the existing resize e2e coverage and add a focused lifecycle/unit test
  for coalescing.
  Related: Session 10 mobile/layout audit, Session 12 coverage gaps.
```

**Covered systems without promoted findings**:

* No Pixi import was found in host routing, registry, extension data, or non-runtime host wiring. Pixi is isolated to `runtime/pixi-runtime.ts` and reached through dynamic imports from Play/runtime mount.
* Route cancellation is guarded by mount generations. Stale async runtime mounts either never start or destroy the returned controller before it is stored.
* Visibility hidden stops the ticker and blocks runtime commands while hidden; visible restores the previous running state only when appropriate.
* Reduced motion is represented in render preferences, effect update paths, particle/shake/glide gates, idle animation gates, scanline drift, and Pixi ticker FPS. Session 10 should still audit user-facing accessibility copy and OS preference edge cases.
* Audio uses committed local Ogg URLs generated by Vite globs and does not introduce a remote loading or network capability finding. Session 08 should classify the local `fetch(url)` decode path under asset/audio budget policy.
* Focused runtime/mobile e2e coverage currently proves painted canvas output, resize response, pause gating, compact pointer movement, save/reset/load, combat feedback, and route cleanup/remount behavior.

**Highest-value follow-up checks queued**:

* In Session 08, classify local audio Ogg and atlas loading against asset-size, provenance, and bundle policy, and reconcile stale no-audio/no-remote-loading documentation.
* In Session 10, check the interaction between saved reduced-motion preference, OS media query changes, static fallbacks, and mobile layout/readability.
* In Session 11, simulate WebGL/Web Audio unavailable and mid-import unmount paths from the mounted view to ensure fallback copy and cleanup are user-visible and race-safe.
* In Session 12, add coverage gaps for sprite-pool bounds, resize coalescing, and render-model projection characterization before renderer/refactor work.
* In Session 13, use AR-D4-001 through AR-D4-003 to sequence renderer, render-model, and effects splits.

**Files changed this session**:

* `docs/ongoing-projects/ai-rogue-audit-plan.md`

**Target report path**:

* `.spec_system/PRD/phase_35/PRD_phase_35.md` still does not exist. Session 07 queued AR-D4-001, AR-D4-002, and AR-D4-003 for final Session 14 synthesis rather than creating the final report early.

**Remaining work**:

* Run Session 08 Assets, Audio, And Bundles next.
* Preserve AR-D4-001 as a D4 resource-lifecycle finding and AR-D4-002/003 as D4 performance/refactor-prerequisite findings.
* Carry forward bundle budget evidence: total client JS gzip is 1489 KB against a 1500 KB budget, leaving only 11 KB of headroom.

**2026-06-25 qimpl Session 08 Assets, Audio, And Bundles**

**Scope executed**: Session 08 Assets, Audio, And Bundles only. No product code changes were made. This pass audited committed AI Rogue media, provenance manifests, asset-size policy, Web Audio loading/lifecycle, local asset loading, production bundle output, public-demo build output, public-demo scan/budget gates, and mobile public-demo route coverage. Type/API synthesis, accessibility, robustness, coverage mapping, refactor sequencing, and final report synthesis remain assigned to Sessions 09-14.

**Files and surfaces inspected**:

* Audio runtime and renderer ownership: `runtime/audio.ts` and `runtime/renderer.ts`.
* Atlas loading and validation: `runtime/assets.ts` and `runtime/__tests__/assets.test.ts`.
* Audio and visual provenance: `src/assets/ai-rogue/audio/music/provenance.json`, `src/assets/ai-rogue/audio/sfx/provenance.json`, `visual-assets.md`, `game-feel.md`, `README.md`, `implementation-baseline.md`, and `enablement-decision.md`.
* Budget/privacy/demo gates: `scripts/check-asset-sizes.sh`, `scripts/check-bundle-budget.sh`, `scripts/check-private-runtime-artifacts.sh`, pages-demo scripts, and `tests/e2e/pages-demo-mobile.spec.ts`.

**Focused checks run**:

| Check                       | Result           | Evidence                                                                                                                                                                                                                                                                     |
| --------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Asset inventory             | Pass             | `find src/assets/ai-rogue -type f -printf '%p %s\n'` found 28 committed runtime asset files: 6 music Ogg files plus provenance, 16 SFX Ogg files plus provenance, and gameplay/UI atlas JSON and PNG files.                                                                  |
| Asset-size policy           | Pass             | `bash scripts/check-asset-sizes.sh` passed: all assets within configured limits, total `src/assets` size 14M. AI Rogue music uses the reviewed 900 KB cap in `scripts/check-asset-sizes.sh:13` and line 28.                                                                  |
| Provenance consistency      | Pass             | Node provenance check confirmed 6 music manifest tracks match 6 Ogg files, max music file 738,060 bytes; 16 SFX manifest cues match 16 Ogg files, max SFX file 16,422 bytes; no manifest-listed files are missing.                                                           |
| Audio lazy/local loading    | Pass             | `runtime/audio.ts` uses Vite local Ogg URL globs; `renderer.ts:531` imports `./audio` only after Play runtime mount; `audio.ts:223` fetches those same-build URLs for lazy decode. No remote AI Rogue audio URL path found.                                                  |
| Web Audio unlock/fallback   | Pass             | `audio.ts:179` returns a silent engine when Web Audio is unavailable; `renderer.ts:746` calls `audio.unlock()` from runtime start; `audio.ts:313` creates/resumes the AudioContext only through unlock.                                                                      |
| Buffer cache and teardown   | Pass             | Buffer cache is bounded by the fixed local URL set and cleared on dispose at `audio.ts:406`; retained music and heartbeat handles are stopped at `audio.ts:385`; renderer destroy disposes audio at `renderer.ts:892`.                                                       |
| Ducking contract            | Finding          | Current docs and `audio.ts` claim a mixing/ducking layer, but source search found no sidechain, compressor, or event-based music gain ducking beyond independent music/SFX gain buses and fades. See AR-D9-002.                                                              |
| Documentation drift         | Finding          | `enablement-decision.md` still records no-audio and all-AI-Rogue-assets-under-200-KB assertions that no longer match current audio policy/assets. See AR-D9-001.                                                                                                             |
| Initial broad rg command    | Rerun after typo | One broad `rg` command exited 2 because it accidentally included a non-existent `runtime` path. The corrected audio/remote-loading search ran afterward and is the evidence used here.                                                                                       |
| Focused unit tests          | Pass             | `bun run test -- src/extensions/ai-rogue/runtime/__tests__/assets.test.ts src/extensions/ai-rogue/__tests__/persistence.test.ts src/extensions/ai-rogue/__tests__/client.test.tsx` passed: 3 files, 46 tests.                                                                |
| Production build            | Pass             | `bun run build` passed for client and SSR. The fresh build emitted AI Rogue local Ogg files, atlas files, `audio` chunk, `renderer`, `render-model`, `effects`, and `pixi-runtime` chunks.                                                                                   |
| Production bundle budget    | Pass             | `bun run budget:check` passed. Total client JS gzip was 1489 KB against the 1500 KB budget, leaving 11 KB headroom. AI Rogue `audio` chunk was 6 KB gzip; `pixi-runtime` was 61 KB gzip.                                                                                     |
| Private runtime artifacts   | Pass             | `bun run runtime:check-private` passed.                                                                                                                                                                                                                                      |
| Public-demo build           | Pass             | `bun run demo:build:pages` passed and assembled `demo-website/dist` with 199 files, 192 promoted client files, and 7 copied public files. AI Rogue local Ogg files were emitted into the demo build.                                                                         |
| Public-demo privacy scan    | Pass             | `bun run demo:scan:pages` passed: fixtures 5 scanned, dist 13 scanned, 186 skipped, 0 issues.                                                                                                                                                                                |
| Public-demo bundle budget   | Pass             | `bun run demo:budget:pages` passed. Total client JS gzip was 1489 KB against the 1500 KB budget.                                                                                                                                                                             |
| Public-demo mobile coverage | Pass             | `bun run test:e2e -- tests/e2e/pages-demo-mobile.spec.ts` passed: 24 Chromium tests. AI Rogue Play, Ledger, Loadout, and Settings rendered without local bridge requests or document overflow; Play painted canvas pixels and compact movement changed the canvas signature. |

**Media provenance and budget table**:

| Asset group        | Files / count                          | Largest file  | Policy result                                                                                                                                         |
| ------------------ | -------------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| Gameplay atlas     | `gameplay-atlas.png/json`              | 37,874 bytes  | Under the default 200 KB non-logo asset cap; atlas validation covered by focused tests.                                                               |
| UI atlas           | `ui-atlas.png/json`                    | 32,797 bytes  | Under the default 200 KB non-logo asset cap; atlas validation covered by focused tests.                                                               |
| Music              | 6 Ogg files plus `provenance.json`     | 738,060 bytes | Under the reviewed 900 KB AI Rogue music cap in `docs/media-policy.md`; provenance records Suno source IDs, trims, codec, duration, and output bytes. |
| Sound effects      | 16 Ogg files plus `provenance.json`    | 16,422 bytes  | Under the default 200 KB non-logo asset cap; provenance records ElevenLabs model, prompts, request parameters, codec, duration, and output bytes.     |
| Public-demo assets | Hashed local Ogg, atlas, JS, CSS files | 738.06 KB Ogg | Demo build emits the same local assets; demo privacy scan and budget pass.                                                                            |

**Asset, audio, and bundle findings queued for the final report**:

```
[D9][Medium] AR-D9-001 Enablement closeout still asserts the pre-audio media contract
  Location: docs/extensions/ai-rogue/enablement-decision.md:35
  Observation: The closeout table still says "No audio implementation found",
  and the non-goal/media-policy rows at lines 53 and 55 still assert no AI Rogue
  runtime asset exceeds 200 KB and no audio was introduced. Current code and
  policy now include Web Audio, six committed music tracks, sixteen committed
  SFX files, and a reviewed 900 KB music cap in `docs/media-policy.md:10` and
  `scripts/check-asset-sizes.sh:13`.
  Impact: A reader using the document as enablement evidence can incorrectly
  conclude that audio remains deferred and that every AI Rogue runtime asset is
  subject to the old 200 KB cap. That is non-blocking for runtime behavior, but
  it is misleading for default-enablement and media-policy review.
  Recommendation: Mark the Session 10 closeout as historical or add a
  supersession note pointing to `game-feel.md`, `visual-assets.md`, and the
  current media policy. If edited in place, replace "no audio" and "200 KB for
  all AI Rogue runtime assets" with the current Web Audio and 900 KB music-cap
  contract.
  Related: Session 02 doc-contract matrix, Session 14 doc-drift list.

[D9][Medium] AR-D9-002 Current audio docs claim ducking that the runtime does not implement
  Location: docs/extensions/ai-rogue/README.md:37
  Observation: `README.md:37` and `README.md:89` describe a Web Audio
  "mixing/ducking" layer, and `runtime/audio.ts:9` says the graph "ducks".
  The actual audio runtime creates master/music/SFX gain buses at
  `audio.ts:213`, applies static preference levels at `audio.ts:196`, fades
  sources in/out at `audio.ts:268` and `audio.ts:280`, and maps events to
  one-shots, but no sidechain, compressor, transient music-gain reduction, or
  event-based ducking path exists.
  Impact: This is a current doc-vs-code mismatch. Runtime audio still loads,
  mixes, loops, and tears down correctly, but reviewers may expect combat SFX
  to lower music automatically when that behavior is not present.
  Recommendation: Either implement explicit music ducking around high-priority
  SFX with focused audio-engine tests, or change current docs/comments from
  "mixing/ducking" to "mixing" until ducking is actually added.
  Related: Session 10 accessibility/audio preference review, Session 12 coverage gaps.
```

**Covered systems without promoted findings**:

* Local audio loading is not remote content loading. The only runtime `fetch` found in AI Rogue audio fetches Vite-generated same-build Ogg URLs from the committed asset set.
* Audio module import is route scoped: it is reached through Play runtime mount after `client.tsx` lazy view loading, not from registry, extension host, or non-Play routes.
* Web Audio unavailable paths use a silent no-op engine instead of throwing to the renderer.
* Decode failures return `null` and produce no sound rather than crashing. Session 11 should still browser-simulate bad audio/unavailable Web Audio for user-visible robustness evidence.
* Music and heartbeat loop handles are retained and stopped on stop/reset/load and destroy. One-shot SFX handles are not retained, but dispose marks the engine disposed, clears cache, and closes the AudioContext; no D4 finding was promoted beyond Session 07's caveat.
* Production and public-demo builds both keep AI Rogue chunks lazy and below per-chunk limits. The total client JS gzip budget remains tight at 1489 KB of 1500 KB.

**Highest-value follow-up checks queued**:

* In Session 09, include `runtime/audio.ts` in the type/API-surface pass so audio IDs, URL lookups, and preferences remain narrow and schema-backed.
* In Session 10, verify Settings copy and controls for audio mute/volume, reduced-motion interaction, keyboard reachability, and mobile layout.
* In Session 11, simulate Web Audio unavailable, failed audio fetch/decode, route change during audio import/decode, and missing atlas/asset paths.
* In Session 12, add missing-test items for ducking if the behavior remains a current contract, and for browser-level audio unavailable/decode-failure fallbacks if not already covered.
* In Session 14, include AR-D9-001 and AR-D9-002 in the doc-drift section and reconcile historical closeout docs versus current contract docs.

**Files changed this session**:

* `docs/ongoing-projects/ai-rogue-audit-plan.md`

**Target report path**:

* `.spec_system/PRD/phase_35/PRD_phase_35.md` still does not exist. Session 08 queued AR-D9-001 and AR-D9-002 for final Session 14 synthesis rather than creating the final report early.

**Remaining work**:

* Run Session 10 Accessibility And Input next.
* Preserve AR-D9-001 and AR-D9-002 as documentation-drift findings unless a later session repairs the source docs before final synthesis.
* Carry forward the hard budget caveat: production and public-demo total client JS gzip are both 1489 KB against a 1500 KB budget, leaving 11 KB headroom.

**2026-06-25 qimpl Session 09 Types And Schemas**

**Scope executed**: Session 09 Types And Schemas only. No product code changes were made. This pass focused on D5 type safety, runtime exports, save/economy schemas, persistence payloads, durable runtime snapshots, save/load handoff, audio ID/preference typing, and the existing schema-focused tests. Accessibility, robustness, coverage synthesis, refactor sequencing, and final report synthesis remain assigned to Sessions 10-14.

**Files and surfaces inspected**:

* Runtime type/API surface: `runtime/types.ts`, `runtime/index.ts`, `runtime/simulation.ts`, `runtime/renderer.ts`, and `views/runtime-canvas.tsx`.
* Durable schemas and persistence payloads: `save-schema.ts`, `economy-schema.ts`, `persistence.ts`, and `use-save-state.ts`.
* Audio/preferences type surface carried forward from Session 08: `runtime/audio.ts`, `runtime/renderer.ts`, `save-schema.ts`, and `views/settings-view.tsx`.
* Focused tests: save schema, persistence, save-state, runtime canvas, and core simulation snapshot tests.

**Focused checks run**:

| Check                                | Result           | Evidence                                                                                                                                                                                                                                                                                                                                  |
| ------------------------------------ | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Type-safety smell sweep              | Pass             | The configured `any`, `as any`, TypeScript suppression, and non-null member access sweep returned no matches. A broader cast sweep found mostly literal `as const`, guarded `unknown` narrowing, atlas metadata casts, and one durable-runtime save cast recorded below.                                                                  |
| Runtime public API audit             | Finding carried  | `runtime/index.ts` still exports broad simulation/content internals and `simulation-fixtures.ts`; this reinforces AR-D1-003 rather than creating a separate D5 duplicate.                                                                                                                                                                 |
| Schema/type source audit             | Pass with caveat | `save-schema.ts` and `economy-schema.ts` export Zod-inferred durable types. Runtime `AiRogueRuntimeSavePayload` is hand-authored and uses runtime `AiRogueRunState`; see AR-D5-002 for the save/load API naming and cast issue.                                                                                                           |
| Runtime snapshot parity reproduction | Pass             | Direct `bun --eval` round trip parsed a fresh `createAiRogueRun()` state through `aiRogueRuntimeSnapshotSchema`, found no missing top-level or tile fields, and successfully applied a movement command to the parsed run state.                                                                                                          |
| Audio ID/preference type audit       | Pass             | Audio IDs are narrow unions backed by `Record<AiRogueSfxId, string>` and `Record<AiRogueMusicId, string>`. Preferences remain bounded by `aiRoguePreferencesSchema` and mapped to `AiRogueAudioPreferences` in the renderer.                                                                                                              |
| Typecheck                            | Pass             | `bun run typecheck` exited 0.                                                                                                                                                                                                                                                                                                             |
| Focused unit tests                   | Pass             | `bun run test -- src/extensions/ai-rogue/__tests__/save-schema.test.ts src/extensions/ai-rogue/__tests__/persistence.test.ts src/extensions/ai-rogue/__tests__/use-save-state.test.tsx src/extensions/ai-rogue/__tests__/runtime-canvas.test.tsx src/extensions/ai-rogue/runtime/__tests__/simulation.test.ts` passed: 5 files, 50 tests. |
| Work-file ASCII check                | Pass             | `LC_ALL=C grep -nP '[^\x00-\x7F]' docs/ongoing-projects/ai-rogue-audit-plan.md` returned no matches.                                                                                                                                                                                                                                      |
| Work-file Prettier check             | Fail             | `bunx prettier --check docs/ongoing-projects/ai-rogue-audit-plan.md` reported Markdown style issues. A no-write formatter diff would reflow earlier Session 07/08 tables as well as the new Session 09 tables, so no broad write was applied during this qimpl pass.                                                                      |

**Schema-vs-runtime contract map**:

| Contract surface          | Source of truth / current shape                                                                                                                                              | Session 09 assessment                                                                                                                                           |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Preferences               | `aiRoguePreferencesSchema` infers `AiRoguePreferences`; persisted raw input mode is `auto` / `keyboard` / `compact`; runtime receives only effective `keyboard` / `compact`. | Holds. Audio mute/music/SFX preferences are bounded in schema and mapped to renderer/audio preferences.                                                         |
| Wallet and ledger         | `aiRogueWalletSchema`, `aiRogueLedgerEntrySchema`, and `aiRogueClaimEntrySchema` infer durable types.                                                                        | Mostly holds. AR-D5-001 remains the known direct durable claim validation gap; no new wallet/ledger type finding was added.                                     |
| Run summaries/history     | `aiRogueRunSummarySchema` and `createAiRogueRunSummaryFromSnapshot` infer the persisted history shape from bounded snapshot fields.                                          | Holds. Focused tests cover summary status mapping and achievement idempotency.                                                                                  |
| Save slots/runtime saves  | `aiRogueRuntimeSnapshotSchema` persists `AiRogueSerializedRunState`; `runtime/types.ts` hand-authors `AiRogueRuntimeSavePayload` with `AiRogueRunState`.                     | Current fields are in parity, but the API names and cast weaken refactor safety; see AR-D5-002.                                                                 |
| Runtime public entrypoint | `runtime/index.ts` exports the mount function plus broad simulation/content/testing internals.                                                                               | Refactor risk already captured as AR-D1-003. D5 should cross-link it because API consumers can import internals and fixture helpers from the production barrel. |
| Audio IDs and preferences | Audio IDs are local unions in `runtime/audio.ts`; preferences are schema-bounded in `save-schema.ts`; renderer maps preferences into `AiRogueAudioPreferences`.              | Holds. Missing ducking remains AR-D9-002 doc drift, not a type-contract failure.                                                                                |

**Type/API finding queued for the final report**:

```
[D5][Medium] AR-D5-002 Live and durable runtime snapshot APIs are easy to confuse
  Location: src/extensions/ai-rogue/runtime/types.ts:635
  Observation: The runtime controller exports `AiRogueRuntimeSnapshot` for live
  frame/status data, while `save-schema.ts:667` also exports an
  `AiRogueRuntimeSnapshot` type for durable save-slot records with a different
  shape. `runtime-canvas.tsx:40` has to alias the durable type, and
  `runtime-canvas.tsx:1017` casts `snapshot.runState` back to
  `AiRogueRuntimeSavePayload["runState"]` because the runtime save payload is a
  hand-authored interface using `AiRogueRunState` rather than the schema-inferred
  `AiRogueSerializedRunState`.
  Impact: Current schema fields are in parity with `AiRogueRunState`, and a
  direct parse/load reproduction passed, so this is not a current corruption
  bug. It is still a refactor-blocking API-surface risk: importing the wrong
  snapshot type is easy, and future schema changes that sanitize, default, or
  split durable run state can be hidden by the cast until a saved run is loaded.
  Recommendation: Rename the durable type to something like
  `AiRogueRuntimeSaveSnapshot` or `AiRogueDurableRuntimeSnapshot`, make
  `AiRogueRuntimeSavePayload.runState` use `AiRogueSerializedRunState` or a
  dedicated hydrated runtime type, and move the durable-to-runtime payload
  conversion behind a schema-owned helper with focused save/load tests.
  Related: AR-D1-003, AR-D5-001, Session 13 types/save-schema refactor map.
```

**Covered systems without promoted findings**:

* Save/economy schemas infer their exported durable record types from Zod schemas; no duplicated durable wallet, ledger, claim, run-history, or preference interfaces were found outside the intentionally public persistence result types.
* Current durable runtime snapshots parse a fresh generated run without losing top-level `AiRogueRunState` fields, and the parsed run state can still be fed back into `applyAiRogueCommand`.
* Schema defaults for legacy runtime snapshots cover progression loadout, objective, relic effects, pending threats, protocols, vault keys, equipment, crash dumps, compile state, terminals, and floor objectives. Existing tests cover several legacy/default paths.
* Audio ID maps are keyed by narrow union types, so missing committed Ogg basenames become a URL lookup/provenance issue rather than a wide string API.
* `bun run typecheck` and focused save/schema/runtime-canvas tests passed after the audit, with no product code changes.
* The work file remains ASCII-only. A Prettier check failed on Markdown table formatting; the formatter write was deliberately not applied because it would reflow earlier session tables unrelated to the Session 09 audit content.

**Highest-value follow-up checks queued**:

* In Session 10, audit keyboard/touch/reduced-motion behavior and include the settings audio controls now that the audio preference types are confirmed schema-backed.
* In Session 11, browser-simulate unavailable IndexedDB/localStorage, clipboard, WebGL, and Web Audio paths so the schema-safe fallbacks also have user-visible recovery evidence.
* In Session 12, add AR-D5-002 coverage guidance: saved-run load tests should protect the durable-to-runtime payload helper once the snapshot naming/cast is cleaned up.
* In Session 13, include `runtime/types.ts`, `runtime/index.ts`, and `save-schema.ts` in the refactor map with explicit type/API boundaries.

**Files changed this session**:

* `docs/ongoing-projects/ai-rogue-audit-plan.md`

**Target report path**:

* `.spec_system/PRD/phase_35/PRD_phase_35.md` still does not exist. Session 09 queued AR-D5-002 and cross-linked AR-D1-003/AR-D5-001 for final Session 14 synthesis rather than creating the final report early.

**Remaining work**:

* Run Session 10 Accessibility And Input next.
* Preserve AR-D5-002 as a D5 type/API-surface finding unless the snapshot naming and cast are repaired before final synthesis.
* Carry AR-D1-003 into Session 13/14 as both an architecture and API-surface refactor prerequisite, while avoiding duplicate findings for the same broad runtime barrel issue.

**2026-06-25 qimpl Session 10 Accessibility And Input**

**Scope executed**: Session 10 Accessibility And Input only. No product code changes were made. This pass focused on D6 keyboard access, compact/touch access, input-mode resolution, Settings accessibility preferences, Play seed sharing and clipboard fallback, canvas assistive text, mobile/public-demo layout, reduced-motion behavior, and route cleanup. Robustness, coverage synthesis, refactor sequencing, and final report synthesis remain assigned to Sessions 11-14.

**Files and surfaces inspected**:

* Input resolution and sampling: `input-mode.ts` and `runtime/input.ts`.
* Play/runtime route: `views/play-view.tsx`, `views/runtime-canvas.tsx`, `runtime/renderer.ts`, `runtime/effects.ts`, and `runtime/render-model.ts`.
* Other user-facing AI Rogue routes: `views/settings-view.tsx`, `views/ledger-view.tsx`, `views/loadout-view.tsx`, and `views/view-shell.tsx`.
* Focused tests and browser specs: input-mode, runtime input, runtime canvas, render model, client view tests, `tests/e2e/ai-rogue-mobile.spec.ts`, and `tests/e2e/pages-demo-mobile.spec.ts`.

**Focused checks run**:

| Check                        | Result           | Evidence                                                                                                                                                                                                                                                                                                                              |
| ---------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Input-mode source audit      | Pass             | Raw `auto` resolves only to effective `keyboard` or `compact` in `input-mode.ts:40`, explicit overrides are preserved, labels report `Auto (compact)` / `Auto (keyboard)`, and media-query listeners clean up.                                                                                                                        |
| Keyboard runtime verb audit  | Pass             | `runtime/input.ts:46` maps movement, primary, secondary, protocol, inspect, target-next, pause, and reset. The renderer applies keyboard commands through the shared dispatcher at `runtime/renderer.ts:596`.                                                                                                                         |
| Compact/touch verb audit     | Finding promoted | Compact UI exposes movement plus primary, secondary, and protocol at `runtime-canvas.tsx:107` and `runtime-canvas.tsx:134`; pause/reset are native route buttons, but inspect and target-next have no touch-accessible control.                                                                                                       |
| Canvas a11y text audit       | Finding promoted | `runtime/render-model.ts:106` computes a rich summary, but `runtime/renderer.ts:1106` sets only a static canvas `aria-label` and no code applies the live summary to assistive text.                                                                                                                                                  |
| Reduced-motion source audit  | Pass with caveat | Runtime preferences and OS media queries set `state.isReducedMotion`; tweening, idle animation, scanline drift, particles, shake, hit-stop, flash, intro, relic, and descend effects are gated or dampened.                                                                                                                           |
| Large HUD preference audit   | Finding promoted | `settings-view.tsx:59` exposes `largeHudLabels`, and `save-schema.ts:280` persists it, but `runtime-canvas.tsx:213` / `runtime-canvas.tsx:357` do not forward it and runtime render preferences do not include it.                                                                                                                    |
| Focused unit tests           | Pass             | `bun run test -- src/extensions/ai-rogue/__tests__/input-mode.test.tsx src/extensions/ai-rogue/runtime/__tests__/input.test.ts src/extensions/ai-rogue/__tests__/runtime-canvas.test.tsx src/extensions/ai-rogue/runtime/__tests__/render-model.test.ts src/extensions/ai-rogue/__tests__/client.test.tsx` passed: 5 files, 50 tests. |
| AI Rogue mobile e2e          | Pass             | `bun run test:e2e -- tests/e2e/ai-rogue-mobile.spec.ts` passed: 4 Chromium tests covering fresh mobile Auto compact controls, portrait compact layout, explicit Keyboard override on mobile, reduced-motion media emulation, clipboard fallback, and route cleanup.                                                                   |
| Public-demo mobile route e2e | Pass             | `bun run test:e2e -- tests/e2e/pages-demo-mobile.spec.ts` passed: 24 Chromium tests, including AI Rogue Play, Ledger, Loadout, and Settings without local bridge requests or document overflow; Play also painted canvas pixels and moved via compact controls.                                                                       |
| Work-file ASCII check        | Pass             | `LC_ALL=C grep -nP '[^\x00-\x7F]' docs/ongoing-projects/ai-rogue-audit-plan.md` returned no matches after this update.                                                                                                                                                                                                                |
| Work-file Prettier check     | Fail             | `bunx prettier --check docs/ongoing-projects/ai-rogue-audit-plan.md` reported Markdown style issues. The file already had broad table wrapping issues from earlier logs, so no unrelated reflow was applied.                                                                                                                          |

**Input-mode state table**:

| Surface            | Raw value / source                                            | Effective runtime behavior                                                                                                                                     | Session 10 assessment                                                                                                      |
| ------------------ | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| Settings           | `auto`, `keyboard`, or `compact` persisted in preferences     | Settings shows raw buttons with `aria-pressed` and resolved copy from media-query capabilities.                                                                | Holds. Focused client tests cover coarse/no-hover and fine/hover label resolution.                                         |
| Play route         | Save-state raw preference plus current input capabilities     | `PlayView` resolves to `keyboard` or `compact` before mounting the runtime.                                                                                    | Holds. Raw `auto` never reaches the runtime canvas bridge as an effective value.                                           |
| Runtime controller | `runtime-canvas.tsx` passes only effective input mode         | Renderer stores `state.inputMode` as `keyboard` or `compact`; keyboard sampler always listens, canvas pointer input only applies in compact mode.              | Holds, with AR-D6-002 for touch-only access to inspect/target-next.                                                        |
| Compact controls   | Visible native buttons under the canvas                       | Directional buttons plus Strike, Surge, and Protocol dispatch `touch` commands only while mounted, running, active, not busy, and effective mode is `compact`. | Holds for movement/combat/protocol. Missing inspect/target-next touch controls are a promoted accessibility finding.       |
| Keyboard controls  | Window-level keyboard sampler                                 | Arrow/WASD, Space/Enter, Shift, F/Q, E, Tab, Escape/P, and R dispatch through the same runtime command path.                                                   | Holds. Browser tests cover movement; source and unit tests cover the full key map.                                         |
| Decision controls  | Compile and terminal pending choices                          | Native buttons with labels call controller decision methods while the run is active.                                                                           | Holds. `runtime-canvas.test.tsx` covers compile and terminal option dispatch.                                              |
| Route controls     | Start, Pause, Reset, Save, Load, Settings reset, Ledger claim | Native buttons expose labels, disabled states, and focus rings; Settings reset moves focus into confirmation and back to the reset button.                     | Holds for inspected source. Browser coverage exists for runtime start/reset/save/load, mobile route cleanup, and reset UI. |

**Accessibility/input findings queued for the final report**:

```
[D6][High] AR-D6-001 Runtime canvas exposes only a static accessible name
  Location: src/extensions/ai-rogue/runtime/renderer.ts:1106
  Observation: The mounted Pixi canvas gets `role="img"` and a static
  `aria-label` of "AI Rogue runtime canvas". `render-model.ts:106` already
  computes a rich dynamic summary with run status, depth, turn, health, shards,
  sector, objective, latest combat signal, seed, motion mode, contrast mode, and
  input mode, but no renderer or React bridge code applies that summary to the
  canvas, an `aria-describedby` target, or an `aria-live` text surface. The
  hidden runtime event list in `runtime-canvas.tsx:819` is also `hidden` and
  `aria-hidden="true"`, so it is test instrumentation rather than assistive
  output.
  Impact: Keyboard users can play, but screen-reader users do not receive the
  current board/run state from the core Play surface. This is a default-
  enablement accessibility blocker unless a current non-canvas equivalent is
  provided.
  Recommendation: Expose `renderModel.summary` through a stable off-canvas
  region referenced by `aria-describedby`, or update the canvas accessible name
  on meaningful turn changes. Add browser or unit coverage that asserts the
  summary changes after movement and includes reduced-motion/high-contrast/input
  state.
  Related: Session 12 coverage gaps, Session 14 default-enablement verdict.

[D6][Medium] AR-D6-002 Compact/touch mode cannot reach inspect and target-next verbs
  Location: src/extensions/ai-rogue/views/runtime-canvas.tsx:134
  Observation: The runtime command union includes `inspect` and `target-next`,
  and the keyboard sampler maps them from `KeyE` and `Tab` in
  `runtime/input.ts:62`. Compact controls expose movement plus Strike, Surge,
  and Protocol only, while Pause and Reset are covered by native route buttons.
  No touch-accessible control dispatches `inspect` or `target-next`, even though
  the renderer supports inspect mode at `runtime/renderer.ts:1207`.
  Impact: Touch-only users cannot open or cycle inspect mode, so enemy/tile
  details available to keyboard users are unreachable from compact mobile play.
  The main movement/combat loop remains playable, but the runtime verb surface
  is incomplete.
  Recommendation: Add compact Inspect and Next target buttons, or deliberately
  replace the inspect workflow with touch tile selection plus a visible detail
  panel. Cover the path in runtime-canvas unit tests and mobile e2e.
  Related: Session 12 missing compact/touch tests.

[D6][Medium] AR-D6-003 Large HUD Labels preference is persisted but has no runtime effect
  Location: src/extensions/ai-rogue/views/settings-view.tsx:59
  Observation: Settings exposes "Large HUD labels", `save-schema.ts:280`
  persists `largeHudLabels`, and Loadout echoes the preference at
  `loadout-view.tsx:264`. The runtime bridge forwards reduced motion, high
  contrast, input mode, auto-pause, and audio preferences at
  `runtime-canvas.tsx:213` and `runtime-canvas.tsx:357`, but not
  `largeHudLabels`; `AiRogueRenderPreferences` and the effects HUD text sizing
  also have no large-HUD branch.
  Impact: Users can enable an accessibility preference that does not improve
  readability. This is misleading and leaves no evidence that the large-HUD
  contract can avoid canvas label overlap.
  Recommendation: Either implement a real large-HUD render path with bounded
  layout tests, or remove/disable the preference until supported. Add a focused
  regression that proves HUD text size/layout changes when enabled.
  Related: Session 13 renderer/effects refactor map, Session 12 coverage gaps.
```

**Covered systems without promoted findings**:

* Settings controls are native checkboxes, buttons, and sliders with labels, disabled states, optimistic updates, and focus restoration for failed saves and reset confirmation.
* Play seed controls use a native input, sanitize share URLs through the existing seed-share path, and expose clipboard-unavailable fallback copy; mobile e2e verifies the fallback when `navigator.clipboard` is undefined.
* Keyboard movement, desktop Auto -> keyboard, mobile Auto -> compact, explicit mobile Keyboard override, compact button movement, and compact canvas pointer movement have browser evidence.
* Runtime compile and terminal choices are native buttons with labels and disabled states, not canvas-only click targets.
* Reduced-motion coverage is broad in source: OS `prefers-reduced-motion` forces the renderer to reduced mode, persisted reduced motion lowers ticker max FPS, entity tweening snaps, idle animation stops, scanline drift freezes, particles/shake/hit-stop skip, flash is dampened, and descend transition is skipped. Session 11 should still browser-simulate failure/unavailable APIs, not re-open this as a motion bug unless new evidence appears.
* AI Rogue Play, Ledger, Loadout, and Settings passed public-demo mobile overflow checks in the route matrix.

**Highest-value follow-up checks queued**:

* In Session 11, browser-simulate WebGL unavailable, unavailable `matchMedia`, clipboard denial, route changes during runtime import, and blocked storage while Settings focus restoration and Play overlays remain visible.
* In Session 12, add missing-test items for AR-D6-001, AR-D6-002, and AR-D6-003: dynamic canvas assistive summary, compact inspect/target-next, and a positive large-HUD preference effect.
* In Session 13, include the runtime canvas / renderer / effects boundary needed to expose assistive summaries and large-HUD sizing without increasing React churn.
* In Session 14, carry AR-D6-001 as a default-enablement blocker unless fixed before synthesis, and include AR-D6-002 / AR-D6-003 in the accessibility backlog.

**Files changed this session**:

* `docs/ongoing-projects/ai-rogue-audit-plan.md`

**Target report path**:

* `.spec_system/PRD/phase_35/PRD_phase_35.md` still does not exist. Session 10 queued AR-D6-001, AR-D6-002, and AR-D6-003 for final Session 14 synthesis rather than creating the final report early.

**Remaining work**:

* Run Session 11 Robustness Paths next.
* Preserve AR-D6-001, AR-D6-002, and AR-D6-003 unless the relevant source changes are repaired before final synthesis.
* Carry forward the current browser evidence: AI Rogue mobile e2e passed 4/4, and public-demo mobile route matrix passed 24/24 including all AI Rogue routes.

**2026-06-25 qimpl Session 11 Robustness Paths**

**Scope executed**: Session 11 Robustness Paths only. No product code changes were made. This pass focused on D7 unavailable browser APIs, malformed storage, runtime import and mount races, renderer/audio setup failures, reset/save/claim races, unmount cleanup, and current test evidence. Coverage synthesis, refactor sequencing, and final report synthesis remain assigned to Sessions 12-14.

**Files and surfaces inspected**:

* Platform probes and input capabilities: `input-mode.ts`.
* Runtime import, mount lifecycle, renderer setup, Pixi cleanup, visibility, blur, resize, reduced-motion listener, and teardown: `views/runtime-canvas.tsx` and `runtime/renderer.ts`.
* Audio setup/decode/disposal: `runtime/audio.ts`.
* Atlas loading and malformed texture guards: `runtime/assets.ts`.
* Seed share, clipboard fallback, and URL update fallback: `views/play-view.tsx` and `seed-share.ts`.
* Durable state, localStorage, IndexedDB, reset compensation, save-state mutation guards, and legacy claim migration: `persistence.ts`, `use-save-state.ts`, and `claim-store.ts`.
* Focused tests and browser specs: input-mode, runtime canvas, save-state, persistence, claim store, seed-share, assets, runtime input, and `tests/e2e/ai-rogue-mobile.spec.ts`.

**Focused checks run**:

\| Check | Result | Evidence | | ----------------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | --------------------- | -------------------- | --------------------------------------------------------------------------------------------------------- | ----- | ----- | ---- | ----------- | --------- | --------- | ------------------------------------------------------- | | Robustness source sweep | Run | `rg -n "catch | JSON\\.parse | try \\{" ...` found the expected parse/error handling sites in seed-share, claim-store, persistence, input-mode, renderer, audio, Settings, Play, Ledger, and runtime-canvas. | | Platform/API sweep | Run | `rg -n "indexedDB | localStorage | matchMedia | clipboard | AudioContext | decodeAudioData | getContext | webgl | WebGL | PIXI | Application | navigator | window\\. | document\\." ...` found the expected browser API sites. | | Cleanup/race sweep | Run | `rg -n "destroy\\( | dispose\\( | removeEventListener | addEventListener | requestAnimationFrame | cancelAnimationFrame | ...` found renderer, audio, input sampler, input-mode, Play popstate, and runtime-canvas lifecycle paths. | | Focused unit tests | Pass | `bun run test -- src/extensions/ai-rogue/__tests__/input-mode.test.tsx src/extensions/ai-rogue/__tests__/runtime-canvas.test.tsx src/extensions/ai-rogue/__tests__/use-save-state.test.tsx src/extensions/ai-rogue/__tests__/persistence.test.ts src/extensions/ai-rogue/__tests__/claim-store.test.ts src/extensions/ai-rogue/__tests__/seed-share.test.ts src/extensions/ai-rogue/runtime/__tests__/assets.test.ts src/extensions/ai-rogue/runtime/__tests__/input.test.ts` passed: 8 files, 65 tests. | | AI Rogue mobile e2e | Pass | `bun run test:e2e -- tests/e2e/ai-rogue-mobile.spec.ts` passed: 4 Chromium tests, including clipboard-unavailable fallback, reduced-motion media emulation, portrait layout, compact controls, explicit keyboard override, and route cleanup removing the runtime canvas. | | Audio robustness coverage | Coverage gap | `rg -n "audio" src/extensions/ai-rogue/**/__tests__/*.ts* tests/e2e/ai-rogue-*.spec.ts` returned no test hits. Source degrades to a silent engine and catches decode/close failures, but no focused test currently simulates missing `AudioContext` or bad decode. | | Reduced-motion listener audit | Finding promoted | `renderer.ts:1581` calls `window.matchMedia` without a catch and `renderer.ts:1600` requires `addEventListener`; `input-mode.ts:112` and `input-mode.ts:187` already show the safer local pattern with try/catch plus `addListener` fallback. | | WebGL/atlas failure audit | Pass with gap | Renderer setup failures propagate to the runtime-canvas error overlay via `runtime-canvas.tsx:381`; atlas validation has explicit errors in `assets.ts:289` and `assets.ts:340`. No current browser test simulates WebGL unavailable or a failed Pixi asset load. | | Storage/reset audit | Pass | localStorage and IndexedDB accessors return typed unavailable/denied results (`persistence.ts:165`, `persistence.ts:174`), malformed JSON is reset or ignored with warnings (`persistence.ts:568`, `persistence.ts:904`), IndexedDB read errors map to `read_failed` (`persistence.ts:650`), and reset compensates localStorage when IndexedDB reset fails (`persistence.ts:962`, `persistence.ts:984`). | | Async race audit | Pass with caveat | Runtime mount uses generation guards and `isMountCurrent` (`runtime-canvas.tsx:260`, `runtime-canvas.tsx:339`, `runtime-canvas.tsx:373`); save-state refresh/mutations use sequence and operation guards (`use-save-state.ts:189`, `use-save-state.ts:217`). Runtime-canvas local save/load promises are not separately generation-guarded, but they do not mutate durable data after the guarded hook rejects/finishes, so this remains a coverage caveat rather than a promoted finding. | | Work-file ASCII check | Pass | `LC_ALL=C grep -nP '[^\\x00-\\x7F]' docs/ongoing-projects/ai-rogue-audit-plan.md` returned no matches after this update. | | Work-file Prettier check | Fail | `bunx prettier --check docs/ongoing-projects/ai-rogue-audit-plan.md` still reports Markdown style issues. The file already had broad table wrapping drift from earlier execution logs, so no unrelated formatter rewrite was applied. |

**Robustness path matrix**:

| Path                                                     | Current behavior                                                                                                              | Session 11 assessment                                                                                 |
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `matchMedia` unavailable in input mode                   | Input capabilities fall back to unknown capability values and Auto resolves to keyboard.                                      | Holds; client/input-mode tests cover unavailable Play capabilities.                                   |
| `matchMedia` throws in input mode                        | `readAiRogueInputModeCapabilities` catches and returns unknown capability values.                                             | Holds in source; focused tests cover the input-mode surface.                                          |
| `matchMedia` throws or lacks modern listener in renderer | Runtime reduced-motion sync can throw during mount.                                                                           | Finding AR-D7-001 promoted.                                                                           |
| WebGL / Pixi app init unavailable                        | Renderer catch emits error and runtime-canvas shows an error overlay instead of leaving a mounted partial canvas.             | Graceful by source inspection; browser simulation missing.                                            |
| Missing or malformed atlas frames                        | Atlas validation throws explicit errors before texture creation; renderer catch turns setup failure into runtime error state. | Graceful by source inspection and assets unit tests; failed asset-load browser simulation missing.    |
| Web Audio unavailable                                    | `createAiRogueAudioEngine` returns a silent engine when no `AudioContext` exists.                                             | Graceful by source inspection; focused tests missing.                                                 |
| Bad audio fetch/decode                                   | Decode failures return `null`; playback no-ops and disconnects gain handles.                                                  | Graceful by source inspection; focused tests missing.                                                 |
| localStorage unavailable or denied                       | Accessors return `storage_unavailable` or `storage_denied`; save-state maps denied to user-visible status.                    | Holds with unit evidence.                                                                             |
| IndexedDB unavailable, blocked, or read-failed           | Adapter resolution returns unavailable; open/read failures map to typed errors.                                               | Holds with unit evidence for unavailable/read-failed. Browser blocked/quota simulation missing.       |
| Malformed preferences or legacy claims                   | Malformed JSON is reset or ignored with warnings rather than throwing.                                                        | Holds with unit evidence.                                                                             |
| Reset partial failure                                    | localStorage values are saved first and restored if IndexedDB reset is unavailable or fails.                                  | Holds by source inspection and reset-only tests; failing reset compensation is not browser-simulated. |
| Claim/save/reset duplicate operations                    | Hook mutations run through `operationRef`; Ledger also has `claimInFlightRef`.                                                | Holds by source inspection and focused hook tests.                                                    |
| Runtime import resolves after route change               | `mountGenerationRef`, `isCancelled`, and controller destroy suppress stale mount effects.                                     | Holds by source inspection; mobile e2e route cleanup verifies canvas removal.                         |
| Mid-run unmount                                          | Controller destroy disposes audio/effects/input, listeners, RAF, sprite pool, ticker, app, and canvas.                        | Holds by source inspection and mobile e2e route cleanup.                                              |

**Robustness finding queued for the final report**:

```
[D7][Medium] AR-D7-001 Reduced-motion media query setup can fail the runtime mount
  Location: src/extensions/ai-rogue/runtime/renderer.ts:1581
  Observation: `createReducedMotionSync` calls `window.matchMedia` directly and
  then unconditionally calls `mediaQuery.addEventListener("change", sync)`.
  Other AI Rogue capability code already handles this browser surface more
  defensively: `input-mode.ts:112` catches throwing `matchMedia` calls, and
  `input-mode.ts:187` supports both `addEventListener` and legacy
  `addListener`. A locked-down or older browser where `matchMedia` throws or
  only exposes `addListener` would make renderer setup throw during mount.
  `runtime-canvas.tsx:381` catches the rejected mount promise and shows an error
  overlay, so this is not a white-screen crash, but the Play surface becomes
  unavailable solely because reduced-motion probing failed.
  Impact: Default enablement would be brittle on reduced/legacy browser media
  query implementations. It also contradicts the D7 expectation that unavailable
  platform APIs degrade to safe defaults.
  Recommendation: Reuse the input-mode media-query subscription pattern or move
  it to a shared helper: catch `matchMedia`, support `addListener` /
  `removeListener`, and return a no-op cleanup when subscription is impossible.
  Add a focused renderer or runtime-canvas test for throwing `matchMedia` and an
  addListener-only media query object.
  Related: Session 10 reduced-motion audit, Session 12 missing robustness tests.
```

**Covered systems without promoted findings**:

* `input-mode.ts` already degrades missing or throwing `matchMedia` to unknown capability values, and raw Auto still resolves to keyboard rather than passing `auto` into the runtime.
* Renderer setup errors, including WebGL/Pixi/atlas failures, are caught and surfaced through runtime-canvas error state; partial Pixi apps are destroyed in the catch path.
* Audio is intentionally optional: no `AudioContext` returns a silent engine, context construction/resume/decode/stop/close failures are caught, and `dispose()` marks handles stopped before clearing caches and closing context.
* Browser storage access is centralized behind adapters. localStorage/IndexedDB absence, denied access, malformed JSON, read/write failures, transaction failures, and reset compensation all return typed results or warnings.
* Runtime import and mount races are guarded by `mountGenerationRef`, `isCancelled`, `isMountCurrent`, and destroy-on-stale-controller logic.
* The existing mobile browser spec verifies clipboard-unavailable fallback and route cleanup for a mounted runtime canvas.

**Highest-value follow-up checks queued**:

* In Session 12, add coverage gaps for AR-D7-001: throwing `matchMedia` and addListener-only media query behavior during renderer/runtime mount.
* In Session 12, add browser or unit coverage for no WebGL / failed Pixi app init, failed Pixi asset load, missing `AudioContext`, bad audio decode, and blocked/quota IndexedDB behavior.
* In Session 13, include a small shared browser-media-query helper in the runtime/input boundary discussion if AR-D7-001 is still open.
* In Session 14, carry AR-D7-001 as a D7 robustness finding unless fixed before synthesis.

**Files changed this session**:

* `docs/ongoing-projects/ai-rogue-audit-plan.md`

**Target report path**:

* `.spec_system/PRD/phase_35/PRD_phase_35.md` still does not exist. Session 11 queued AR-D7-001 for final Session 14 synthesis rather than creating the final report early.

**Remaining work**:

* Run Session 12 Test Coverage next.
* Preserve AR-D7-001 unless the reduced-motion media query setup is hardened before final synthesis.
* Carry forward Session 11 evidence that focused robustness unit tests passed 65/65 and AI Rogue mobile e2e passed 4/4.

**2026-06-25 qimpl Session 12 Test Coverage**

**Scope executed**: Session 12 Test Coverage only. No product code changes were made. This pass mapped all current AI Rogue unit specs, dedicated AI Rogue e2e specs, and public-demo mobile route coverage to D1-D9. It also tied missing tests back to the findings and follow-up gaps queued by Sessions 03-11. Refactor sequencing and final findings synthesis remain assigned to Sessions 13-14.

**Coverage inventory confirmed**:

* AI Rogue unit specs: 41 files, 7,339 test lines, 265 passing tests.
* Dedicated AI Rogue Playwright specs: 5 files, 15 Chromium tests.
* Public-demo mobile route coverage: `tests/e2e/pages-demo-mobile.spec.ts` generated 24 route checks in the current matrix, including AI Rogue Play, Ledger, Loadout, and Settings.
* Public-demo AI Rogue gameplay coverage: the Play route check starts the runtime, asserts compact touch controls, checks the WebGL canvas is painted, and verifies rendered pixels change after movement.

**Unit spec coverage map**:

| Subject group                                       | Specs mapped                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Dimensions covered | Assessment                                                                                                                                                                                                                                                                                                                                  |
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Host, views, capabilities, privacy labels           | `client.test.tsx`, `runtime-canvas.test.tsx`, `input-mode.test.tsx`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | D1, D3, D6, D7, D8 | Strong shell/view coverage for extension registration, public-demo copy, lazy runtime boundary, input-mode resolution, compact action buttons, compile/terminal controls, Settings flows, and import boundaries. Weak for dynamic canvas assistive summary, large-HUD runtime effect, and compact inspect/target-next.                      |
| Economy, ledger, persistence, schemas, seed sharing | `economy.test.ts`, `claim-store.test.ts`, `persistence.test.ts`, `save-schema.test.ts`, `seed-share.test.ts`, `use-save-state.test.tsx`                                                                                                                                                                                                                                                                                                                                                                                                                                        | D2, D3, D5, D7, D8 | Strong coverage for caps, unknown pricing, idempotent claims, scoped reset, schema migrations, storage fallback classes, malformed JSON, durable state, save-state mutation guards, and seed normalization/rejection. Gaps remain around direct durable claim amount validation drift and browser-level blocked/quota IndexedDB simulation. |
| Progression and loadout                             | `progression.test.ts`, `loadout-upgrade.test.ts`, `simulation.test.ts` progression cases                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | D2, D5, D8         | Good behavior coverage for class/relic/loadout math, upgrade costs, achievement propagation, and selected loadout effects. Refactor tests should preserve this before splitting progression state from `simulation.ts`.                                                                                                                     |
| Simulation, content, and deterministic rules        | `simulation.test.ts`, `rng.test.ts`, `world.test.ts`, `combat.test.ts`, `fov.test.ts`, `initiative.test.ts`, `status.test.ts`, `status-expanded.test.ts`, `enemy-effects.test.ts`, `objective-lock.test.ts`, `thief.test.ts`, `compile.test.ts`, `cascade.test.ts`, `shield-buffer.test.ts`, `traversal-verbs.test.ts`, `terminals.test.ts`, `prefabs.test.ts`, `floor-arc.test.ts`, `equipment.test.ts`, `protocols.test.ts`, `themes.test.ts`, `ecology.test.ts`, `vault.test.ts`, `crash-dumps.test.ts`, `biome-final.test.ts`, `roguelike-loop.test.ts`, `inspect.test.ts` | D2, D5, D8         | Broad behavior-driven coverage exists for deterministic generation, run-loop ordering, combat, FOV, status effects, objectives, terminal/compile choices, traversal verbs, protocols, prefabs, floors, vaults, thief, ecology, and final beats. The main D2 gap is the lethal-DOT command matrix from AR-D2-001.                            |
| Render model, runtime input, assets                 | `render-model.test.ts`, `input.test.ts`, `assets.test.ts`, `inspect.test.ts`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | D4, D5, D6, D7, D8 | Useful pure coverage for render summaries, high-contrast descriptors, reduced-motion summary text, keyboard mapping, pointer tie-breaks, atlas metadata, and texture loading. There is no focused renderer/effects lifecycle test for sprite-pool bounds, resize coalescing, WebGL failure, dynamic ARIA propagation, or audio fallback.    |

**E2E coverage map**:

| Spec                                     | Tests                     | Dimensions covered     | Assessment                                                                                                                                                                                                                                                   |
| ---------------------------------------- | ------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `tests/e2e/ai-rogue-runtime.spec.ts`     | 8                         | D1, D2, D4, D6, D7, D8 | Good browser evidence for Play mount, real WebGL pixels, resize, keyboard input, pause gating, desktop Auto keyboard mode, share seed normalization, compact pointer movement, save/reset/load, scripted combat feedback, and route unmount/remount cleanup. |
| `tests/e2e/ai-rogue-mobile.spec.ts`      | 4                         | D4, D6, D7, D8         | Good mobile evidence for Auto compact controls, portrait overflow, explicit Keyboard override, reduced-motion media emulation, clipboard-unavailable fallback, and route cleanup. Does not cover compact inspect/target-next or large-HUD behavior.          |
| `tests/e2e/ai-rogue-ledger.spec.ts`      | 1                         | D3, D5, D8             | Good adversarial privacy fixture and idempotent claim evidence for Ledger, including private path/prompt/command suppression and durable one-claim state.                                                                                                    |
| `tests/e2e/ai-rogue-persistence.spec.ts` | 1                         | D3, D5, D7, D8         | Good end-to-end durable-state coverage for preferences, claims, save/load readiness, loadout selection, upgrade purchase, scoped reset, private text suppression, and unrelated localStorage preservation.                                                   |
| `tests/e2e/ai-rogue-enablement.spec.ts`  | 1                         | D1, D3, D8             | Good host LiveData enablement evidence that AI Rogue Play mounts without relying on a collector item.                                                                                                                                                        |
| `tests/e2e/pages-demo-mobile.spec.ts`    | 24 generated route checks | D3, D4, D6, D8         | Good public-demo evidence that hosted routes avoid local bridge requests and document overflow. AI Rogue Play additionally proves painted WebGL pixels and compact movement in public-demo mode.                                                             |

**Focused checks run**:

\| Check | Result | Evidence | | ------------------------------------------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ----------- | ------------ | --------------- | ---------- | ----- | --------- | ------------ | ------ | ---------- | ---------- | -------------- | ----------------------------------------------------------- | | Unit inventory map | Pass | `find src/extensions/ai-rogue -path '*/__tests__/*' ...` plus `wc -l` confirmed 41 AI Rogue unit spec files. | | Test intent sweep | Run | `rg -n "^(describe | it | test)\\(" src/extensions/ai-rogue tests/e2e/ai-rogue-\*.spec.ts tests/e2e/pages-demo-mobile.spec.ts` mapped unit/e2e describe and test names. | | Gap keyword sweep | Run | `rg -n "aria | describedby | largeHud | inspect | target-next | AudioContext | decodeAudioData | matchMedia | WebGL | indexedDB | private path | prompt | transcript | credential | reduced motion | canvas" ...` separated existing coverage from absent tests. | | Full AI Rogue unit suite | Pass | `bun run test -- src/extensions/ai-rogue` passed: 41 files, 265 tests. | | Full AI Rogue e2e plus public-demo mobile matrix | Pass | `bun run test:e2e -- tests/e2e/ai-rogue-runtime.spec.ts tests/e2e/ai-rogue-mobile.spec.ts tests/e2e/ai-rogue-ledger.spec.ts tests/e2e/ai-rogue-persistence.spec.ts tests/e2e/ai-rogue-enablement.spec.ts tests/e2e/pages-demo-mobile.spec.ts` passed: 39 Chromium tests. |

**High and important finding coverage status**:

| Finding / risk                                               | Current coverage                                                                                                                                        | Session 12 gap classification                                                                               |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| AR-D1-001 renderer mutates run state outside simulation APIs | Import-boundary tests prove lazy runtime isolation, but no guard prevents renderer-level direct run-state mutation.                                     | Add a static or behavior test that renderer commands flow through public simulation/controller APIs only.   |
| AR-D2-001 lethal status damage before Surge/Protocol actions | Status and command tests cover many effects, but not the lethal-DOT verb matrix from Session 04.                                                        | High-priority missing characterization test in `status-expanded.test.ts` or `simulation.test.ts`.           |
| AR-D4-001 hidden feedback sprite accumulation                | E2e route cleanup proves canvas unmount/remount; no long-run sprite-pool bound test exists.                                                             | Add renderer/effects lifecycle coverage before refactoring or optimizing effects.                           |
| AR-D4-003 immediate resize/render work                       | Runtime e2e proves resize works, not that resize work is coalesced or bounded.                                                                          | Add resize-coalescing or render-call-count coverage if the performance fix is attempted.                    |
| AR-D6-001 static canvas accessible name                      | `render-model.test.ts` proves rich summary generation, but bridge/e2e tests do not assert that summary reaches the DOM/canvas accessibility surface.    | High-priority missing accessibility regression.                                                             |
| AR-D6-002 compact mode lacks inspect/target-next             | Keyboard input and inspect model tests exist; compact UI tests cover movement/primary/secondary/protocol only.                                          | Missing touch UI and mobile e2e coverage once the control path exists.                                      |
| AR-D6-003 large-HUD preference has no runtime effect         | Preferences are persisted in tests, but no test asserts a positive runtime/layout change.                                                               | Missing positive-effect test after implementation or a removal test if the setting is removed.              |
| AR-D7-001 renderer `matchMedia` setup can fail mount         | Input-mode tests cover safe media query fallback; renderer/runtime mount tests do not simulate throwing `matchMedia` or addListener-only media queries. | Missing robustness regression.                                                                              |
| Audio optional/failure paths                                 | No AI Rogue test references `AudioContext`, `decodeAudioData`, or audio engine creation directly.                                                       | Add unit coverage for silent engine, failed decode, dispose, and optional audio behavior.                   |
| Browser storage blocked/quota paths                          | Unit tests cover adapter results and some read failure paths; e2e uses normal IndexedDB/localStorage only.                                              | Add browser-level blocked/quota simulation if default enablement depends on user-visible fallback evidence. |
| AR-D5-001 direct durable claim validation drift              | Claim and persistence tests cover normal claims and idempotency; no test intentionally feeds mismatched durable claim/wallet amounts.                   | Add schema/durable write validation coverage if the claim write path is hardened.                           |
| AR-D5-002 durable/live runtime snapshot naming and cast risk | Save/load e2e and schema tests cover current parity.                                                                                                    | Add tests around a schema-owned durable-to-runtime helper after the API is renamed.                         |
| AR-D9-002 audio ducking doc drift                            | Settings and schema tests cover audio preferences; no source behavior or test proves ducking.                                                           | If ducking remains a contract, add audio behavior tests; otherwise keep as doc drift only.                  |

**Coverage findings queued for the final report**:

```
[D8][High] AR-D8-001 High-risk simulation and accessibility findings lack direct regression coverage
  Location: src/extensions/ai-rogue/runtime/__tests__/simulation.test.ts:1
  Observation: The suite is broad, but two high-impact risks are still not
  directly guarded: AR-D2-001's lethal status damage before Surge/Protocol
  actions, and AR-D6-001's requirement that the rich runtime summary reach a
  real assistive DOM/canvas surface. Existing tests prove status mechanics and
  render-model summary generation separately, but not those user-visible
  failure paths.
  Impact: Fixes for the two highest-priority correctness/accessibility findings
  could regress during the upcoming refactor unless characterization tests are
  added first.
  Recommendation: Add a lethal-DOT command matrix in `simulation.test.ts` or
  `status-expanded.test.ts`, and add a bridge/e2e assertion that the mounted
  runtime exposes updated summary text after movement.
  Related: AR-D2-001, AR-D6-001, Session 13 refactor prerequisites.

[D8][Medium] AR-D8-002 Renderer, audio, and platform-failure coverage is source-inspection-heavy
  Location: src/extensions/ai-rogue/runtime/__tests__/assets.test.ts:1
  Observation: Assets have metadata/texture tests, and browser e2e proves happy-
  path WebGL rendering and route cleanup. There is still no focused coverage for
  renderer `matchMedia` failure, addListener-only media queries, WebGL/Pixi init
  failure, failed Pixi asset load, unavailable `AudioContext`, failed audio
  decode, audio dispose, or browser-level blocked/quota IndexedDB behavior.
  Impact: D7 fallback claims rely partly on source inspection. Default
  enablement would be stronger with tests that simulate unavailable platform
  APIs and prove visible recovery states.
  Recommendation: Add renderer/runtime-canvas tests for reduced-motion media
  query fallback and setup failure, add `runtime/audio` unit tests for silent
  and decode-failure paths, and add one browser-level storage/WebGL failure test
  if feasible without brittle browser patching.
  Related: AR-D4-001, AR-D4-003, AR-D7-001, Session 11 robustness matrix.

[D8][Medium] AR-D8-003 Compact input and large-HUD preferences need positive UI coverage
  Location: src/extensions/ai-rogue/__tests__/runtime-canvas.test.tsx:1
  Observation: Runtime-canvas tests cover compact movement plus primary,
  secondary, and protocol controls, and Settings tests persist
  `largeHudLabels`. No test covers compact/touch inspect or target-next because
  those controls do not exist yet, and no test proves that enabling
  `largeHudLabels` changes runtime rendering or layout.
  Impact: The accessibility preference and compact verb surface can remain
  incomplete while tests still pass.
  Recommendation: After implementation, extend `runtime-canvas.test.tsx` and
  mobile e2e to cover compact Inspect/Next target, and add a focused positive
  assertion for the large-HUD runtime/render effect or remove the preference and
  test that it is absent.
  Related: AR-D6-002, AR-D6-003.
```

**Current coverage quality assessment**:

* Strongest areas: deterministic simulation fixtures, economy caps and idempotency, durable schema migrations, seed privacy, public-demo browser- local copy, host/lazy import boundaries, and real browser canvas smoke tests.
* Useful but brittle areas: import-boundary tests are source-scanning guards, not architectural enforcement; canvas pixel hashes prove rendering changed but do not identify which render subsystem regressed.
* Weakest areas: renderer/effects lifecycle internals, platform failure simulation, audio failure behavior, assistive canvas output, compact touch verb completeness, and positive accessibility preference effects.
* No product code or tests were changed in this pass; all missing tests are proposed follow-up work for fixes/refactors.

**Files changed this session**:

* `docs/ongoing-projects/ai-rogue-audit-plan.md`

**Target report path**:

* `.spec_system/PRD/phase_35/PRD_phase_35.md` still does not exist. Session 12 queued AR-D8-001, AR-D8-002, and AR-D8-003 for final Session 14 synthesis rather than creating the final report early.

**Remaining work**:

* Run Session 13 Refactor Map next.
* Preserve the D8 coverage findings unless the related tests are added before final synthesis.
* Carry forward current verification evidence: all 41 AI Rogue unit specs passed, all 15 dedicated AI Rogue e2e tests passed, and the 24-route public-demo mobile matrix passed including all four AI Rogue routes.

**2026-06-25 qimpl Session 13 Refactor Map**

**Scope executed**: Session 13 Refactor Map only. No product code, tests, assets, generated files, spec-system state, session specs, or task checklists were changed. This pass converted Sessions 03-12 evidence into a safe oversized-module refactor map and sequencing recommendation for the final Session 14 findings report.

**Inputs consolidated**:

* D1 architecture findings: AR-D1-001 renderer run-state mutation, AR-D1-002 production combat fixture query path, and AR-D1-003 broad runtime barrel/API surface.
* D2/D5 findings that constrain state splits: AR-D2-001 lethal status damage before Surge/Protocol, AR-D5-001 direct durable claim validation drift, and AR-D5-002 live/durable runtime snapshot naming and cast risk.
* D4/D6/D7 findings that constrain render and UI splits: AR-D4-001 sprite accumulation, AR-D4-002 per-frame render projection rebuilds, AR-D4-003 immediate resize work, AR-D6-001 static canvas accessible name, AR-D6-002 missing compact inspect/target-next, AR-D6-003 inert Large HUD Labels, and AR-D7-001 fragile renderer media-query subscription.
* D8 coverage prerequisites: AR-D8-001 through AR-D8-003, especially lethal-DOT command coverage, dynamic assistive canvas summary coverage, renderer/effects lifecycle coverage, and positive compact/large-HUD UI coverage.

**Focused checks run**:

| Check                  | Result | Evidence                                                                                                                                                                                                                                                                                                                                             |
| ---------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Oversized-module count | Run    | `wc -l` confirmed the current >800-line set: `simulation.ts` 3108, `renderer.ts` 1605, `save-schema.ts` 1247, `effects.ts` 1057, `runtime-canvas.tsx` 1047, `persistence.ts` 1020, `render-model.ts` 928, `world.ts` 834, and `types.ts` 804.                                                                                                        |
| Module outline sweep   | Run    | `rg -n "^(export \|const \|function \|async function \|class \|interface \|type )" ...` mapped public types/functions and private seams across the nine oversized modules.                                                                                                                                                                           |
| Import/API sweep       | Run    | `rg -n "^import \|^export " ... runtime/index.ts` confirmed the production runtime barrel still exports simulation, content, render-model, fixtures, and mount/controller APIs from one entrypoint.                                                                                                                                                  |
| Finding seam sweep     | Run    | Targeted `rg` checked the known refactor hazards: `applySelectedUpgradeToRun`, `updateSelectedUpgrade`, `updateProgressionLoadout`, `createReducedMotionSync`, `syncSprites`, `createAiRogueRenderModel`, `ResizeObserver`, `aria-label`, `largeHudLabels`, snapshot types, claim persistence, and simulation APIs.                                  |
| Source inspections     | Run    | Read decisive line ranges in the nine oversized modules, including command reducers, enemy turns, floor descent, renderer mount/render/resize/sprite/media-query code, schema parse/apply helpers, persistence adapters/transactions/reset, effects HUD/transients, render projection/summary, world generation/fixtures, and runtime type surfaces. |
| Typecheck              | Pass   | `bun run typecheck` exited 0.                                                                                                                                                                                                                                                                                                                        |
| AI Rogue unit suite    | Pass   | `bun run test -- src/extensions/ai-rogue` passed: 41 files, 265 tests.                                                                                                                                                                                                                                                                               |

**Refactor sequencing recommendation**:

| Order | Workstream                                                         | Why this order                                                                                                                                                                                                                                                                                                                                                   |
| ----- | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 0     | Add characterization tests first                                   | Do not split until AR-D8 prerequisites cover lethal DOT before Surge/Protocol, assistive runtime summary updates, sprite-pool bounds, resize coalescing, renderer media-query fallback, audio fallback, compact Inspect/Next target, Large HUD behavior, direct durable claim validation, and durable-to-runtime save conversion.                                |
| 1     | Narrow runtime API and move pre-run state mutation into simulation | AR-D1-001 and AR-D1-003 are the highest-leverage blockers. Split `runtime/index.ts` into a mount entrypoint plus explicit simulation/testing entrypoints, then move selected-upgrade/loadout application from `renderer.ts` into simulation-owned APIs before renderer or simulation file splits.                                                                |
| 2     | Stabilize schema/persistence contracts                             | Resolve AR-D5-001 and AR-D5-002 before large durable-state splits. Rename durable snapshot types, add a schema-owned durable-to-runtime helper, and make claim wallet/ledger validation single-path so save-schema and persistence can split without hiding casts or amount drift.                                                                               |
| 3     | Split simulation by reducer pipeline                               | After AR-D2-001 is characterized or fixed, split `simulation.ts` along state-transition boundaries: run creation/snapshot, command dispatch, movement/landing, player actions, enemy turns/threats/thief behavior, floor/objective progression, and post-turn finalization.                                                                                      |
| 4     | Split render/controller ownership                                  | After renderer lifecycle tests exist, split `renderer.ts`, `render-model.ts`, `effects.ts`, and `runtime-canvas.tsx` so the controller owns state/events, the scheduler owns ticker/resize/media queries, Pixi sprite resources own pooling/teardown, projection is cached separately from animation, and React owns only bridge/control/accessibility surfaces. |
| 5     | Split world and shared types last                                  | `world.ts` and `types.ts` are broad but mostly stable. Split them after runtime/API and simulation/schema boundaries are narrower, otherwise type-only cycles and public barrel exports will keep the new files coupled.                                                                                                                                         |

**Oversized-module refactor map for Session 14**:

| Module                     | Current seam evidence                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | Recommended split                                                                                                                                                                                                                                                                                                                          | Tests required before split                                                                                                                                                          |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `runtime/simulation.ts`    | Public API starts at `createAiRogueRun` (`simulation.ts:452`), `applyAiRogueCommand` (`simulation.ts:522`), compile/terminal decision APIs (`simulation.ts:543`, `simulation.ts:577`), snapshot creation (`simulation.ts:669`), command normalization (`simulation.ts:768`), movement (`simulation.ts:792`), floor descent (`simulation.ts:1306`), enemy turns (`simulation.ts:1394`), player actions (`simulation.ts:2264`, `simulation.ts:2397`, `simulation.ts:2486`), and shared turn finalization (`simulation.ts:2898`).                                                   | Split into `run-factory`, `snapshot`, `command-dispatch`, `movement`, `player-actions`, `enemy-turns`, `floor-progression`, and `turn-finalizer`. Move selected upgrade/loadout initialization here before the split so the renderer stops editing `AiRogueRunState` directly.                                                             | AR-D2-001 lethal-DOT matrix, progression/loadout start-state tests, deterministic same-seed replay tests, floor descent/objective tests, and existing full simulation/content suite. |
| `runtime/renderer.ts`      | `mountAiRogueRenderer` (`renderer.ts:107`) owns controller state, Pixi app, input, audio, effects, render loop, resize, visibility, media queries, save/load, run creation, and sprite pooling. Known hazards sit in render projection (`renderer.ts:302`), resize (`renderer.ts:552`, `renderer.ts:634`), pre-run state mutation (`renderer.ts:852`, `renderer.ts:862`, `renderer.ts:1052`), static canvas a11y (`renderer.ts:1106`), sprite retention (`renderer.ts:1290`), and media-query subscription (`renderer.ts:1579`).                                                 | Split into controller/state machine, command adapter, render scheduler, Pixi resource/sprite pool, browser subscriptions, audio adapter, inspect overlay, and save-payload adapter. The sprite pool should separate persistent world/HUD sprites from transient descriptor families.                                                       | Renderer media-query fallback, sprite-pool bound, resize coalescing, save/load bridge, route cleanup, and command-through-public-API tests.                                          |
| `save-schema.ts`           | One file owns preferences (`save-schema.ts:275`), wallet (`save-schema.ts:293`), ledger (`save-schema.ts:317`), run history (`save-schema.ts:343`), serialized run state (`save-schema.ts:607`), durable runtime snapshots (`save-schema.ts:667`), types (`save-schema.ts:704`), defaults/factories (`save-schema.ts:827`), parsers (`save-schema.ts:941`, `save-schema.ts:975`, `save-schema.ts:1011`, `save-schema.ts:1058`, `save-schema.ts:1104`), and wallet/ledger mutations (`save-schema.ts:1126`, `save-schema.ts:1166`, `save-schema.ts:1191`, `save-schema.ts:1236`). | Split into constants/keys, preferences schema, wallet-ledger schema, run-history schema, runtime-save schema, defaults/factories, record parsers/migrations, and wallet-ledger operations. Rename durable runtime snapshot types during the split.                                                                                         | Save-schema migration/default tests, direct oversized-claim validation test from AR-D5-001, durable snapshot conversion tests from AR-D5-002, and save/load e2e.                     |
| `runtime/effects.ts`       | `createAiRogueEffects` (`effects.ts:123`) owns HUD text, camera glide, shake, flash, intro/relic/end-screen cards, floating numbers, impact sprites, particles, event ingestion (`effects.ts:516`), per-frame update (`effects.ts:670`), layout (`effects.ts:848`), cleanup (`effects.ts:926`), and destroy (`effects.ts:949`). Large-HUD behavior has no input path.                                                                                                                                                                                                            | Split into HUD overlay, transient combat effects, camera/shake/flash, cinematic cards/end screen, and lifecycle cleanup helpers. Thread a render/UI preference object through HUD sizing if Large HUD Labels is implemented.                                                                                                               | Effects teardown tests, reduced-motion tests for each effect family, Large HUD positive-layout test or preference-removal test, and existing runtime/mobile route cleanup.           |
| `views/runtime-canvas.tsx` | `AiRogueRuntimeCanvas` (`runtime-canvas.tsx:156`) owns mount generation, controller ref, runtime import, preferences sync, selected upgrade/loadout sync, run completion recording, Start/Pause/Reset/Save/Load actions, compile/terminal decisions, compact controls, hidden event list, and durable snapshot conversion (`runtime-canvas.tsx:1005`).                                                                                                                                                                                                                           | Split into `useAiRogueRuntimeController`, `useAiRogueRuntimePersistenceActions`, `RuntimeControls`, `RuntimeDecisionPanels`, `CompactControls`, and an assistive summary component that consumes runtime snapshots. Remove durable snapshot casting by calling a schema-owned helper.                                                      | Dynamic assistive summary DOM/e2e test, compact Inspect/Next target test, save/load/reset tests, mount-cancellation tests, and durable snapshot helper tests.                        |
| `persistence.ts`           | The file owns adapter resolution and IndexedDB adapter (`persistence.ts:302`), preferences localStorage (`persistence.ts:553`, `persistence.ts:584`), full state reads (`persistence.ts:639`, `persistence.ts:687`), wallet/save/run-summary writes (`persistence.ts:709`, `persistence.ts:764`, `persistence.ts:790`), claim/upgrade transactions (`persistence.ts:826`, `persistence.ts:853`), legacy migration (`persistence.ts:881`), scoped reset (`persistence.ts:927`), and direct claim validation (`persistence.ts:998`).                                               | Split into browser adapters, preference storage, IndexedDB stores/transactions, read aggregators, wallet/save/run-history operations, claim/upgrade operations, legacy migration, and reset compensation. Keep transaction helpers close to their stores.                                                                                  | Blocked/quota storage simulation if feasible, reset compensation tests, claim idempotency and oversized-amount test, migration tests, and persistence e2e.                           |
| `runtime/render-model.ts`  | `createAiRogueRenderModel` (`render-model.ts:85`) rebuilds/sorts tiles, fog, entities, feedback, pending threats, crash dumps, HUD sprites, descriptors, and summary every render. Feedback descriptor ids come from event ids (`render-model.ts:358`), HUD sprites/descriptors are separate paths (`render-model.ts:468`, `render-model.ts:600`), and rich summary already exists (`render-model.ts:818`) but is not surfaced to assistive tech.                                                                                                                                | Split into viewport math, tile/fog projection, entity projection, transient feedback/threat/crash projection, HUD sprite projection, HUD descriptor/summary projection, and ordering helpers. Add a cache boundary keyed by snapshot identity/turn/depth/preferences/viewport before optimizing.                                           | Render-model snapshot characterization, summary text assertions, feedback id lifecycle tests with renderer pool, high-contrast tests, and Large HUD projection tests if implemented. |
| `runtime/world.ts`         | `createAiRogueWorld` (`world.ts:131`) mixes base map generation, hazards, pickups, relic shrines, enemies, protocols, vaults, prefabs, terminals, and final sorting. Fixture row parsing starts at `world.ts:390`; geometry/tile helpers start at `world.ts:482`; prefab/vault/terminal helpers live at `world.ts:625`, `world.ts:683`, and `world.ts:787`.                                                                                                                                                                                                                      | Split into generator pipeline, spawn placement, prefab placement, fixture row parser, and tile/geometry utilities. Keep deterministic placement order explicit so content additions do not silently alter seeds.                                                                                                                           | Same-seed world generation tests, fixture parser tests, vault/terminal connectivity tests, prefab placement tests, and simulation playthrough smoke.                                 |
| `runtime/types.ts`         | Core domain types, frame-name unions, simulation state/snapshot, runtime controller/events, seed metadata, save payload, and schema-derived progression aliases are all in one file. The file imports from `../save-schema` at `types.ts:6` and defines both live runtime snapshot (`types.ts:635`) and runtime save payload (`types.ts:649`).                                                                                                                                                                                                                                   | Split into domain geometry/world/entity types, simulation state/event/command types, runtime controller/event types, render asset frame-name types, and progression/save bridge types. Break the save-schema dependency by moving shared durable aliases to a dedicated bridge module or importing only from a narrowed schema entrypoint. | Typecheck, import-cycle guard, runtime barrel API tests, durable snapshot naming/conversion tests, and simulation/render-model compile coverage.                                     |

**Cross-module boundaries to preserve**:

* Simulation/content modules must remain free of Pixi, DOM, React, persistence, browser globals, host LiveData, and route concerns.
* Public-demo and extension enablement stay in host-layer files; game runtime modules should not branch on public-demo mode.
* `renderer.ts` may own mounted browser resources, but run-state transitions should flow through simulation APIs.
* Durable schemas remain the source of truth for persisted data; runtime save payloads should convert through schema-owned helpers instead of casts in React bridge code.
* Render projection should stay pure. Animation clocks, sprite pooling, effects, and browser scheduling should stay outside `render-model.ts`.

**Refactor map section queued for the final report**:

```
The audit supports refactoring, but only after targeted characterization tests
are added. The first refactor should narrow the runtime public API and move
pre-run selected-upgrade/loadout mutation from the renderer into simulation
APIs. The second should stabilize durable snapshot and claim validation
contracts. Only then should the large simulation, renderer, schema,
persistence, effects, render-model, world, runtime-canvas, and types files be
split along the seams listed in the map above. Splitting renderer/render-model
before AR-D4/AR-D6/AR-D7 coverage exists would likely preserve today's defects
while making them harder to locate.
```

**No new findings promoted in Session 13**:

* Session 13 did not add new AR-D findings. It consolidated the already queued D1-D9 findings into refactor order, module seams, and pre-refactor test requirements for Session 14 synthesis.
* Minor local duplication artifacts were not found in the source when checked with `nl -ba`; earlier repeated lines were terminal capture artifacts from concatenated `sed` ranges, not file content.

**Files changed this session**:

* `docs/ongoing-projects/ai-rogue-audit-plan.md`

**Target report path**:

* `.spec_system/PRD/phase_35/PRD_phase_35.md` still does not exist. Session 13 queued the refactor map and sequencing recommendation for final Session 14 synthesis rather than creating the final report early.

**Remaining work**:

* Run Session 14 Findings Synthesis next.
* Create `.spec_system/PRD/phase_35/PRD_phase_35.md` and include executive summary, Go/No-Go default-enablement verdict, all queued findings, the refactor map above, coverage gaps, doc-drift list, and evidence appendix.
* Carry AR-D6-001 as a default-enablement blocker unless fixed before Session 14, and preserve all queued AR-D findings unless source changes invalidate them.
* Include current verification evidence: `bun run typecheck` passed, and `bun run test -- src/extensions/ai-rogue` passed 41 files / 265 tests.

**2026-06-25 qimpl Session 14 Findings Synthesis**

**Scope executed**: Session 14 Findings Synthesis only. No product code, tests, assets, generated files, spec-system state, session specs, or task checklists were changed. This pass consolidated Sessions 01-13 into the final audit report at `.spec_system/PRD/phase_35/PRD_phase_35.md`.

**Completed this session**:

* Created `.spec_system/PRD/phase_35/PRD_phase_35.md`.
* Included executive summary, finding counts, No-Go default-enablement verdict, explicit blockers, grouped D1-D9 findings, refactor map, coverage gaps, doc-drift list, follow-up backlog, evidence appendix, and completion criteria table.
* Preserved the no-new-D3-finding result: the audit promoted no privacy, hosted-storage, network, public-demo server-write, or seed-share leak finding.
* Carried all queued AR-D findings from Sessions 03-13: AR-D1-001 through AR-D1-003, AR-D2-001, AR-D4-001 through AR-D4-003, AR-D5-001 through AR-D5-002, AR-D6-001 through AR-D6-003, AR-D7-001, AR-D8-001 through AR-D8-003, and AR-D9-001 through AR-D9-002.
* Recorded No-Go blockers for default enablement: AR-D6-001, AR-D2-001, AR-D1-002, and AR-D4-001.

**Files changed this session**:

* `.spec_system/PRD/phase_35/PRD_phase_35.md`
* `docs/ongoing-projects/ai-rogue-audit-plan.md`

**Commands run this session**:

| Command                                                                                                                  | Result                   | Notes                                                                                                                                                                                                                |
| ------------------------------------------------------------------------------------------------------------------------ | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sed` reads against the work file and qimpl reference                                                                    | Pass                     | Loaded the work file, queued findings, baseline gates, refactor map, and completion criteria.                                                                                                                        |
| `git status --short`                                                                                                     | Pass                     | Confirmed the work file was already modified before this session and the new report is untracked until committed.                                                                                                    |
| `rg --files` / targeted `rg` source checks                                                                               | Pass                     | Confirmed current source still contains the main evidence anchors for renderer mutation, static canvas label, reduced-motion media query setup, large-HUD preference, snapshot naming, and direct claim persistence. |
| `bunx prettier --check .spec_system/PRD/phase_35/PRD_phase_35.md`                                                        | Initial fail, final pass | Failed before formatting the new report, passed after `bunx prettier --write .spec_system/PRD/phase_35/PRD_phase_35.md`.                                                                                             |
| `LC_ALL=C rg -n "[^\\x00-\\x7F]" .spec_system/PRD/phase_35/PRD_phase_35.md docs/ongoing-projects/ai-rogue-audit-plan.md` | Pass                     | Exit 1 with no matches, which means no non-ASCII characters were found.                                                                                                                                              |

**Checks attempted**:

* Focused Markdown formatting check for the new report.
* ASCII scan for both files touched in this session.
* Targeted source/document evidence spot checks for the final report anchors.
* Full product gates were not rerun in Session 14 because this was a docs-only synthesis pass; the report carries forward the Session 01/04/08/13 gate evidence and calls out that full gates should run before default enablement.

**Check results**:

* `.spec_system/PRD/phase_35/PRD_phase_35.md` passes Prettier after formatting.
* No non-ASCII characters were found in the touched Markdown files.
* No unresolved blocker prevented final report creation.

**Current implementation state**:

* The audit plan execution is complete.
* Product/runtime code remains unchanged by the audit.
* The final report verdict is No-Go for default enablement until the report's listed blockers are fixed or explicitly accepted with compensating coverage.

**Remaining work**:

* None for this qimpl audit execution.
* Follow-up implementation work should start from `.spec_system/PRD/phase_35/PRD_phase_35.md`, beginning with AR-D6-001 and AR-D2-001 plus their characterization tests.


---

# 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://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/.spec_system/archive/phases/phase_34/prd_phase_34.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.
