> 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/sessions/phase30-session03-pixijs-runtime-boundary/spec.md).

# Session Specification

**Session ID**: `phase30-session03-pixijs-runtime-boundary` **Phase**: 30 - AI Rogue Game Extension **Status**: Not Started **Created**: 2026-06-22

***

## 1. Session Overview

This session proves the lazy PixiJS v8 runtime boundary for the AI Rogue Play surface. It replaces the Session 02 visual placeholder with a runtime bridge that dynamically imports PixiJS only after the Play view mounts, owns the WebGL renderer imperatively, paints a nonblank canvas from committed atlas inputs, and tears down every ticker, listener, canvas, and Pixi resource on route exit.

It is next because Session 01 ratified the renderer, asset, privacy, and lazy import baseline, and Session 02 created the disabled-first extension shell and routes. Later economy, persistence, simulation, and asset-integration sessions need a stable runtime ownership contract before they attach gameplay state.

The scope is deliberately a boundary proof, not gameplay. The runtime should show coarse start, pause, reset, resize, hidden-tab, reduced-motion, and input events back in React, but combat, progression, wallet writes, IndexedDB saves, and full sprite choreography remain deferred to later Phase 30 sessions.

***

## 2. Objectives

1. Mount PixiJS v8 lazily from the AI Rogue Play route without importing `pixi.js` from the registry, client metadata, route host, or non-game views.
2. Own WebGL renderer setup, resize handling, ticker lifecycle, visibility throttling, reduced-motion behavior, and route-away disposal in runtime modules with explicit cleanup.
3. Load the committed AI Rogue atlas metadata and paint a nonblank, nearest-neighbor, 2x pixel-art canvas using `preserveDrawingBuffer: true`.
4. Expose coarse runtime controls and events to React for start, pause, reset, resize, keyboard input smoke, and runtime error states.
5. Add focused unit/component, Playwright, build, and bundle-budget evidence proving runtime isolation and no unexpected shared chunk growth.

***

## 3. Prerequisites

### Required Sessions

* [x] `phase30-session01-direction-and-asset-readiness` - Ratified `AI Rogue`, `ai-rogue`, the PixiJS lazy import rule, WebGL `preserveDrawingBuffer: true`, committed atlas paths, tile scale, and privacy boundaries.
* [x] `phase30-session02-extension-shell-and-routes` - Registered the AI Rogue extension shell, Play/Ledger/Loadout/Settings views, disabled-first states, route rendering, and import-boundary tests.

### Required Tools Or Knowledge

* PixiJS v8 `Application.init`, imperative renderer ownership, ticker, stage, texture, and destroy APIs.
* Existing dynamic extension routes in `src/routes/extensions.$extensionId.tsx` and `src/routes/extensions.$extensionId.$viewId.tsx`.
* Existing AI Rogue shell files under `src/extensions/ai-rogue/`.
* Existing canvas pixel-read verification pattern in `tests/e2e/memory-graph.spec.ts`.
* Existing build and bundle budget commands: `bun run build` and `bun run budget:check`.

### Environment Requirements

* Bun 1.3.14 project tooling.
* React 19, TanStack Router/Start, Vite 8, Tailwind CSS 4, Vitest, happy-dom, Playwright, and Chromium.
* WebGL-capable Playwright Chromium for canvas pixel checks.

***

## 4. Scope

### In Scope (MVP)

* AI OS operator can open `/extensions/ai-rogue/play` with AI Rogue runtime data enabled and see a PixiJS canvas paint from the lazy runtime path.
* AI OS maintainer can verify PixiJS remains route-lazy - implemented by source import-boundary tests, production chunk inspection, and budget output.
* AI Rogue runtime owns WebGL setup - implemented with PixiJS v8 `Application.init`, `preserveDrawingBuffer: true`, transparent renderer configuration, nearest-neighbor scaling, explicit resize, and destroy logic.
* AI Rogue runtime owns lifecycle and input - implemented with start, pause, reset, keyboard sampling, hidden-tab throttling, reduced-motion behavior, ticker gating, and event callbacks to React.
* AI Rogue Play view shows coarse runtime state - implemented through a React bridge component with accessible controls, loading, ready, paused, reset, error, offline, and unavailable states.
* AI Rogue tests prove behavior - implemented through focused runtime tests, route/client tests, Playwright nonblank/resize/input/cleanup checks, and build-budget verification.

### Out Of Scope (Deferred)

* Economy transforms, `Insight Shards` wallet claims, and ledger mutation - Reason: Session 04 owns browser-safe economy and manual claims.
* IndexedDB persistence, versioned saves, wallet durability, and reset storage - Reason: Session 05 owns persistence contracts.
* Dungeon generation, combat, FOV, enemies, run completion, and deterministic simulation - Reason: Session 06 owns pure TypeScript simulation.
* Full atlas sprite wiring, animated player/enemy/tile layers, and spendable upgrade integration - Reason: Session 07 owns play runtime integration.
* WebGPU, worker simulation, OffscreenCanvas, audio, gamepad, pointer lock, remote loading, collectors, admin writes, hosted storage, auth, or database dependencies - Reason: these remain deferred by the Phase 30 baseline.

***

## 5. Technical Approach

### Architecture

Add `src/extensions/ai-rogue/runtime/` as the imperative runtime boundary. The runtime package should expose a small `mountAiRogueRuntime()` entrypoint that accepts a host element, initial options, and event callbacks, then dynamically imports and owns PixiJS resources behind that boundary. The entrypoint returns a controller with start, pause, reset, resize, snapshot, and destroy methods.

Keep React in charge of routing, buttons, status text, accessibility labels, offline messaging, and coarse runtime state. React should not receive per-frame data. The Play view should render a bridge component from `src/extensions/ai-rogue/views/runtime-canvas.tsx`; that component performs the dynamic runtime import on mount, guards duplicate start/pause/reset triggers while initialization is in flight, and destroys the runtime on unmount.

Use the committed `src/assets/ai-rogue/gameplay-atlas.{png,json}` as the loader proof. Full asset choreography is deferred, but this boundary should parse atlas metadata, load the gameplay atlas image, set nearest-neighbor scaling, and render at least one stable frame or tile-backed marker plus simple diagnostic shapes so Playwright can verify a nonblank WebGL canvas.

### Design Patterns

* Static extension registry: keep `pixi.js` and `src/extensions/ai-rogue/runtime` out of `src/extensions/registry.ts`, `client.tsx`, and non-game views.
* Runtime controller: imperative mount returns a controller and performs all cleanup on `destroy()`.
* Coarse bridge events: runtime emits status, frame, resize, input, and error events to React; React displays summaries and controls.
* Canvas verification: use `preserveDrawingBuffer: true` and the existing `gl.readPixels` Playwright pattern before considering screenshot fallback.
* Lazy budget evidence: inspect `dist/client/assets` after build and update `scripts/check-bundle-budget.sh` only if the measured PixiJS lazy chunk needs the watched vendor allowance.

***

## 6. Deliverables

### Files To Create

| File                                                       | Purpose                                                                                                                                        | Est. Lines |
| ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `src/extensions/ai-rogue/runtime/types.ts`                 | Runtime options, controller, status, event, input, resize, and snapshot contracts.                                                             | \~110      |
| `src/extensions/ai-rogue/runtime/assets.ts`                | Atlas metadata constants, frame validation, PixiJS asset loading placeholder, and nearest-neighbor texture setup.                              | \~120      |
| `src/extensions/ai-rogue/runtime/input.ts`                 | Keyboard input sampler with pressed-key state, command mapping, and listener cleanup.                                                          | \~100      |
| `src/extensions/ai-rogue/runtime/renderer.ts`              | PixiJS v8 WebGL application mount, stage setup, ticker gate, resize handling, visibility/reduced-motion behavior, nonblank draw, and disposal. | \~220      |
| `src/extensions/ai-rogue/runtime/index.ts`                 | Public lazy runtime entrypoint exporting `mountAiRogueRuntime`.                                                                                | \~20       |
| `src/extensions/ai-rogue/runtime/__tests__/assets.test.ts` | Atlas metadata and frame-name validation tests against committed JSON.                                                                         | \~80       |
| `src/extensions/ai-rogue/runtime/__tests__/input.test.ts`  | Keyboard sampler mapping and cleanup tests.                                                                                                    | \~90       |
| `src/extensions/ai-rogue/views/runtime-canvas.tsx`         | React bridge for lazy runtime import, controls, status, loading, error, event summaries, and cleanup.                                          | \~220      |
| `tests/e2e/ai-rogue-runtime.spec.ts`                       | Playwright coverage for nonblank canvas, resize, keyboard input smoke, and route-away cleanup.                                                 | \~190      |

### Files To Modify

| File                                                                                   | Changes                                                                                                                                                         | Est. Lines |
| -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `src/extensions/ai-rogue/views/play-view.tsx`                                          | Replace the static playfield placeholder with the runtime bridge while preserving first-screen layout and readiness panels.                                     | \~70       |
| `src/extensions/ai-rogue/__tests__/client.test.tsx`                                    | Update Play view expectations and import-boundary assertions so only the Play runtime bridge can lazy-load runtime modules and no shell file imports `pixi.js`. | \~60       |
| `src/routes/__tests__/extensions-routes.test.tsx`                                      | Update AI Rogue route expectations for the runtime canvas bridge and loading/disabled states.                                                                   | \~35       |
| `scripts/check-bundle-budget.sh`                                                       | Add a PixiJS lazy-vendor pattern only if measured production output requires the vendor allowance; otherwise leave unchanged and record evidence.               | \~5        |
| `.spec_system/specs/phase30-session03-pixijs-runtime-boundary/implementation-notes.md` | Task-by-task implementation notes, changed-file list, and command evidence.                                                                                     | \~140      |
| `.spec_system/specs/phase30-session03-pixijs-runtime-boundary/security-compliance.md`  | Runtime privacy, dependency, browser-surface, and no-new-network review.                                                                                        | \~100      |
| `.spec_system/specs/phase30-session03-pixijs-runtime-boundary/validation.md`           | Final validation report with unit, e2e, build, budget, ASCII/LF, and cleanup evidence.                                                                          | \~150      |

***

## 7. Success Criteria

### Functional Requirements

* [ ] Opening `/extensions/ai-rogue/play` with enabled AI Rogue fixture data lazily imports the runtime and renders a visible PixiJS canvas.
* [ ] The rendered canvas is nonblank under Playwright pixel-read verification.
* [ ] Resize events update renderer dimensions without layout overflow or canvas collapse.
* [ ] Start, pause, and reset controls update coarse runtime state and prevent duplicate triggers while initialization or reset is in flight.
* [ ] Keyboard input smoke behavior is visible through a runtime event summary.
* [ ] Hidden-tab or visibility-change handling pauses or throttles the ticker and resumes safely when visible.
* [ ] Reduced-motion preference lowers or disables nonessential animation without preventing the nonblank proof frame.
* [ ] Route-away cleanup destroys PixiJS resources and removes listeners so a remount starts from a clean runtime instance.
* [ ] Registry, client metadata, route host, extension index, Ledger, Loadout, and Settings views do not import `pixi.js` or runtime modules.

### Testing Requirements

* [ ] Runtime asset tests validate committed atlas frame metadata.
* [ ] Runtime input tests validate key mapping and listener cleanup.
* [ ] AI Rogue client/route tests cover runtime bridge states and import boundaries.
* [ ] Playwright runtime tests cover nonblank paint, resize, keyboard input, and route-away cleanup.
* [ ] `bun run build` and `bun run budget:check` pass or record the measured PixiJS lazy-vendor classification update.

### Non-Functional Requirements

* [ ] PixiJS remains outside shared app chunks and unrelated routes.
* [ ] Runtime code introduces no network call, credential flow, admin write, hosted storage, database dependency, collector, or remote loading path.
* [ ] Canvas and controls have accessible labels, keyboard support, and stable responsive dimensions on desktop and mobile.
* [ ] Runtime event payloads contain only browser-safe labels, dimensions, status, and input command names.

### Quality Gates

* [ ] All files ASCII-encoded
* [ ] Unix LF line endings
* [ ] Code follows project conventions
* [ ] Focused tests, Playwright runtime test, typecheck, build, and budget checks pass or have documented unrelated blockers

***

## 8. Implementation Notes

### Working Assumptions

* AI Rogue remains a single-repo extension rather than a monorepo package: the analyzer reports monorepo detection as false, and current AI Rogue code lives under `src/extensions/ai-rogue/`. Planning can proceed with repo-root-relative paths.
* The runtime should mount only from the Play route bridge: Session 02 already proved dynamic extension routing, and the Phase 30 baseline requires PixiJS to stay out of the registry, app shell, route index, and non-game views.
* Loading one committed gameplay atlas frame is enough for Session 03: the session stub says full asset wiring is deferred, while also saying the loader placeholder and nonblank paint test can load one committed atlas instead of synthetic texture.

### Conflict Resolutions

* Master PRD status conflict: `.spec_system/PRD/PRD.md` still labels Phase 30 as Not Started, while the analyzer reports Phase 30 as in progress and lists Sessions 01 and 02 as completed. The analyzer is the authoritative state source for `plansession`, so Session 03 is the next executable session.

### Key Considerations

* Keep PixiJS imports in the lazy runtime module, not in files that the registry imports eagerly.
* Use `preserveDrawingBuffer: true` first so Playwright can verify pixels with the existing WebGL readback pattern.
* Keep React state coarse. Per-frame ticker state should remain inside the runtime controller.
* Do not write generated game state, telemetry, saves, or runtime data to committed files in this session.

### Potential Challenges

* PixiJS v8 initialization is async: guard component state so route-away during initialization destroys any late-created application instead of leaking it.
* Happy-dom does not provide real WebGL: keep renderer unit tests focused on pure helpers and use Playwright for actual canvas proof.
* Production chunk names may not include a stable `pixi` prefix: record the measured dist output and update the budget pattern only if a real violation requires it.

### Relevant Considerations

* \[P00] **Stack conventions**: Bun, Vite 8, TanStack Start, React 19, Radix UI, and Cloudflare Worker compatibility shape the runtime bridge and tests.
* \[P02] **Static extension registry requires code changes**: No marketplace, dynamic loading, eval, or remote code belongs in AI Rogue runtime work.
* \[P02] **Extension payloads and labels stay bounded**: Runtime events should stay browser-safe and bounded to labels, status, dimensions, and command names.
* \[P27] **Repo-wide formatting drift remains**: Keep validation scoped and record unrelated repo-wide drift if broad checks fail outside touched files.
* \[P29] **Budget checks need separate labels**: Keep total client JS gzip, app chunk, lazy vendor chunk, CSS, and extension payload budgets distinct in validation records.

### Behavioral Quality Focus

Checklist active: Yes Top behavioral risks for this session:

* Async runtime initialization can outlive the route if the user navigates away during load; every acquired resource needs cleanup on scope exit.
* Start, pause, and reset controls can be clicked repeatedly while the runtime is loading; state-mutating controls need duplicate-trigger prevention while in flight.
* Canvas rendering depends on WebGL, visibility, reduced-motion, and resize state; the view needs explicit loading, empty, error, offline, and fallback states.

***

## 9. Testing Strategy

### Unit Tests

* Validate atlas metadata and required frame names in `src/extensions/ai-rogue/runtime/__tests__/assets.test.ts`.
* Validate keyboard command mapping, pressed-key state, duplicate key handling, and listener cleanup in `src/extensions/ai-rogue/runtime/__tests__/input.test.ts`.
* Update AI Rogue client tests to prove runtime import boundaries and bridge states without requiring WebGL in happy-dom.

### Integration Tests

* Update extension route tests to confirm `/extensions/ai-rogue/play` renders the runtime bridge shell and keeps unrelated Trend Finder surfaces absent.
* Verify source-level import boundaries for registry, client metadata, route host, extension index, Ledger, Loadout, and Settings.

### Runtime Verification

* Add Playwright coverage that seeds enabled AI Rogue extension data, opens `/extensions/ai-rogue/play`, waits for the PixiJS canvas, verifies nonblank pixels with WebGL readback, resizes the viewport, sends keyboard input, and navigates away to prove cleanup/remount behavior.
* Run `bun run build` and `bun run budget:check`, then inspect `dist/client/assets` for PixiJS lazy chunk behavior.

### Edge Cases

* WebGL unavailable or PixiJS init failure shows an accessible runtime error state instead of a blank surface.
* Offline browser state keeps local shell messaging explicit without blocking already-loaded local runtime proof.
* Route-away during async init destroys late-created resources.
* Reduced-motion preference keeps proof rendering stable while throttling or disabling nonessential animation.

***

## 10. Dependencies

### Other Sessions

* Depends on: `phase30-session01-direction-and-asset-readiness`, `phase30-session02-extension-shell-and-routes`
* Depended by: `phase30-session06-dungeon-simulation-core`, `phase30-session07-play-runtime-integration`

***

## Next Steps

Run the `implement` workflow step to begin implementation.


---

# 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/sessions/phase30-session03-pixijs-runtime-boundary/spec.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.
